How do I create an iPhone framework and use it in

2019-01-22 00:41发布

问题:

I would like to create a framework for some reusable code that I would like to include in other iPhone apps. What is the best way to do it? Ideally, I would like it to work just like builtin frameworks and have the app use it without mucking around with build files.

回答1:

Apple prevents the use of custom frameworks on the iPhone. But you can use good old static libraries. In the 3.0 GM SDK there's even a project template for that, but you can also simply set up a static library target yourself.



回答2:

I've created templates for Xcode 4 that allow you to build universal iOS frameworks (which work in both device and simulator).

Once the templates are installed, you simply select "Static iOS Framework" when creating a new project and it does the rest. It also works with unit tests.

https://github.com/kstenerud/iOS-Universal-Framework



回答3:

I have been thinking about the same thing. So far all I've been able to do is make one project just the way I want it and copy it to another folder to start a new project. Then I rename the .xcodeproj file and open that. Then I customize the basics (icons, default.png, the target, the executable) before building the new app.

It's clunky, and NOT the way code reuse is supposed to work. I'm sure there are better solutions. Maybe some clever use of source code management / version control? Maybe something built into XCode? Other ideas? I look forward to seeing more posts here.



回答4:

@Nikolai Ruhe - where exactly does Apple forbid use of custom frameworks on the iPhone? I have read through both the iOS Developer Program License Agreement and the App Store Review Guidelines, and cannot seem to find any mention of such a ban.

I don't see why Apple would allow the use of custom static libraries, and forbid the use of custom frameworks. Perhaps I'm missing some other legal document?



回答5:

see this link, You can absolutely create a framework and use it. Why will apple reject your app if you structure your program. see this link

The framework is nothing but structural organization of your code. There is no direct approach to do it. but you can achieve it by using a bundle and aggrigated target. Add a new Bundle to your project and do the following Base SDK: Latest iOS (iOS X.X) (in the X.X will appear the number of the lastest iOS SDK installed on your machine). Architectures: $(ARCHS_STANDARD_32_BIT) armv6 (it’s very important to be exactly this value including the space before “armv6″) This setting is valid to Xcode 4.2, if you are using an old version, use the “Standard (armv6 armv7)” option. (the values for this property depend on the value of the item bellow, so set that first). Build Active Architecture Only: NO (otherwise we can’t compile to armv6 and armv7 at the same time). Valid Architecture: $(ARCHS_STANDARD_32_BIT) (it’s very important to be exactly this value). If your Xcode is showing two lines with armv6 and armv7, delete then and insert this value in one single line. Dead Code Stripping: NO. Link With Standard Libraries: NO. Mach-O Type: Relocatable Object File. This is the most important change. Here, we instruct the compiler to treat the Bundle as a relocatable file, by doing this, we can turn it into a framework with the wrapper setting. Other Linker Flags: This setting is not mandatory, but if you are planning to use any kind of C++ code (.cpp or .mm) on this framework, Chris Moore (on the comments) advises to use the “-lstdc++” option. In this case could be a good idea to use “-ObjC” too, to avoid conflicts in old compilers. Wrapper Extension: framework. Here we change the Bundle to a Framework. To Xcode, frameworks is just a folder with the extension .framework, which has inside one or more compiled binary sources, resources and some folders, a folder, usually called Headers, contains all the public headers. Generate Debug Symbols: NO (this is a very important setting, otherwise the framework will not work on other computers/profiles). Precompile Prefix Header: NO.

create a aggrigated target and copy

# Sets the target folders and the final framework product.
FMK_NAME=FI
FMK_VERSION=A

# Install dir will be the final output to the framework.
# The following line create it in the root folder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework

# Working dir will be deleted after the framework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework

# Building both architectures.
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator

# Cleaning the oldest.
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi

# Creates and renews the final product folder.
mkdir -p "${INSTALL_DIR}"
mkdir -p "${INSTALL_DIR}/Versions"
mkdir -p "${INSTALL_DIR}/Versions/${FMK_VERSION}"
mkdir -p "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources"
mkdir -p "${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers"

# Creates the internal links.
# It MUST uses relative path, otherwise will not work when the folder is copied/moved.
ln -s "${FMK_VERSION}" "${INSTALL_DIR}/Versions/Current"
ln -s "Versions/Current/Headers" "${INSTALL_DIR}/Headers"
ln -s "Versions/Current/Resources" "${INSTALL_DIR}/Resources"
ln -s "Versions/Current/${FMK_NAME}" "${INSTALL_DIR}/${FMK_NAME}"

# Copies the headers and resources files to the final product folder.
cp -R "${DEVICE_DIR}/Headers/" "${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers/"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/"

# Removes the binary and header from the resources folder.
rm -r "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/Headers" "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/${FMK_NAME}"

# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}"

rm -r "${WRK_DIR}"

this into the run script and run the aggrigate target to get the framework