framework制作教程
1. 目的
1) 方便集成和使用
2. 前置条件
1) Xcode5.0
3. 步骤
1) 新建一个Target,类型选OS X中的Bundle
2) 填写相应信息,建立完成效果如下
3) 选中HelloWorld这个Target,切换到Build Settings界面
4) 将Base SDK的值由默认的Latest OS X修改为Latest iOS为
5) 将Build Active Architecture Only的值修改为No
6) 将Link With Standard Libraries由Yes修改为No
7) 将Mach-O Type由默认的Bundle修改为Relocatable Object File
8) 将Wrapper Extension的值由默认值bundle修改为framework
9) 将Dead Code Stripping的值由默认值Yes修改为No
10) 新建一个总头文件,用于包含所有其他的头文件,约定俗成这个头文件的命名一般与framework名称相同,这里取HelloWorld
11) 建立逻辑类
12) 编写代码
13) 在总头文件(HelloWorld.h)中将要提供给外部使用的类头文件引入
14) 选中工程文件(HelloWorld) ---> Target(HelloWorld) ----> Build Phases
15) 再依次选中菜单栏Editor ---> Add Build Phase ---> Add Copy Headers Build Phase
16) 操作完成后,Target的Build Phases多了一项Copy Headers
17) 点击Copy Headers 下面的+号,选择要对外暴露的.h文件
18) 点Add完成,默认会将.h文件放入了Project分组中,在这个分组里面的头文件无法被外部工程访问,因此需要将头文件放到Public分组
19) 选中Project分组里面的.h文件,拖动到Public分组
20) 这时候按快捷键Command+B进行编译,会报错
21) 根据错误提示很快可以定位是预编译头HelloWorld-Prefix.pch里面引入的头文件未找到,把引入的头文件<Cocoa/Cocoa.h>修改为<Foundation/Foundation.h>再编译就通过了虽然代码很干净,但是依旧有一个警告,这对有强迫症的人是绝对无法忍受的,必须消灭掉(后来也证明这个警告是必须要消灭的,在链接时会引起符号重复错误)
22) 消灭警告:展开Project Navigator下面的Frameworks,将其与HelloWorld的Target取消关联
23) 再编译就干干净净,清清爽爽
24) 新增一个Aggregate类型的Target
25) 切换到新建的Target(FrameworkBuilder)的Build Phases界面
26) 点击菜单栏Editor ---> Add Build Phase ---> Add Run Script Build Phase, 会增加一栏Run Script
27) 在黑色背景的文本框内填入以下Shell代码
set -o errexit
# Sets the target folders and the final framework product.
FMK_NAME=HelloWorld
FMK_VERSION=A
#FMK_RESOURCE_NAME=HelloWorldResource
# 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}/Framework/${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"
RESOURCE_DIR="${WRK_DIR}/Release-iphoneos"
# Building both architectures.
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator
#xcodebuild -configuration "Release" -target "${FMK_RESOURCE_NAME}" -sdk iphoneos
# 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"
# 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/"
#cp -R "${RESOURCE_DIR}/${FMK_RESOURCE_NAME}.bundle" "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/"
# Uses the Lipo Tool to merge both binary files (i386 + armv7/armv7s) into one Universal final product.
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}"
# 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}"
# Removes the binary and header from the resources folder.
rm -r "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/${FMK_NAME}"
rm -r "${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/Headers"
rm -r "${WRK_DIR}"
28) 编译FrameworkBuilder,成功后会在工程所在的目录下生成Framework目录,该目录下的HelloWorld.framework就是生成好的标准framework
4. 注意事项
1) xxxStaticLib Build Active Architecture Only设置为NO。解决在调试期间在不同平台上编译出现找不到符号链接的问题。
2) 头文件中有#import <Three20/Three20.h>的,不能将Three20头文件所在的路径写在HeaderSearch Paths里,要将Three20的头文件所在路径写在User Header Search Paths里(需要将AlwaysSearch User Paths的值设置为YES)。