Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
263 views
in Technique[技术] by (71.8m points)

ios - How to archive an app that includes a custom framework?

I have an xcode framework project that I've created, which I can compile into a myframework.framework file. After compiling, I drag this framework into the Frameworks project folder of my application, and then to make use of classes from the framework I add the proper import statement to any class that needs it; this allows my app to successfully compile with references to classes defined in the framework. To get the app to deploy successfully to my device, I also add my custom framework to the "Embedded Binaries" section for my target. With all this in place, I can build my app from xcode and run it on my device.

My problem comes when I attempt to Archive my application for the app store. When I attempt to do this, I get a ton of compiler errors where xcode says it cannot find the declarations for any of the classes defined in my custom framework.

How can I set up Archive in xcode so that it properly references and embeds my custom framework?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You actually don't need to put it in the "embedded binaries" section. You only need it in the "linked frameworks and libraries section. Make sure that your framework is a Universal Framework (meaning it can compile for all architectures), and make sure you have the right compiler flags set (-ObjC if your framework has any categories etc) There may be some other things you need to set as well like "Other C Flags" if your framework includes any c code and you want to enable bitcode in your client app then you should put "-fembed-bitcode" in your framework Other C Flags. Those were the things I needed to do to get my framework app to the store. I think its a just a misconception that you need to put this in embedded binaries as well to get it to archive for the store.

This is the build script I use to generate the universal framework. It builds right to my desktop. You can uncomment section 8 if your framework is in Swift. You want to create an aggregate target and add this as a run script in build phases.

# Merge Script

# 1
# Set bash script to exit immediately if any commands fail.
set -e

# 2
# Setup some constants for use later on.
FRAMEWORK_NAME="MyFramework"

# 3
# If remnants from a previous build exist, delete them.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi

# 4
# Build the framework for device and for simulator (using
# all needed architectures).
xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch arm64 -arch armv7 -arch armv7s only_active_arch=no defines_module=yes -sdk "iphoneos"
xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch x86_64 -arch i386 only_active_arch=no defines_module=yes -sdk "iphonesimulator"

# 5
# Remove .framework file if exists on Desktop from previous run.
if [ -d "${HOME}/Desktop/${FRAMEWORK_NAME}.framework" ]; then
rm -rf "${HOME}/Desktop/${FRAMEWORK_NAME}.framework"
fi

# 6
# Copy the device version of framework to Desktop.
cp -r "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework" "${HOME}/Desktop/${FRAMEWORK_NAME}.framework"

# 7
# Replace the framework executable within the framework with
# a new version created by merging the device and simulator
# frameworks' executables with lipo.
lipo -create -output "${HOME}/Desktop/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}"

# 8
# Copy the Swift module mappings for the simulator into the
# framework.  The device mappings already exist from step 6.
#cp -r "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/" "${HOME}/Desktop/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule"

# 9
# Delete the most recent build.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi

Once your framework is on the desktop, if you go inside of it there will be a text document with the same name as your framework. If you navigate to that and run the command "lipo -info" on it in terminal you should get the following output:

Architectures in the fat file: MyFramework are: armv7 armv7s i386 x86_64 arm64 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...