一、制作静态库.a文件
第一步
- 创建一个新项目 选择
Cocoa Touch Static Library
第二步
-
Build Active Architecture Only
设置为NO
(不同机型的架构不一样,设置为NO适配不同机型)
第三步
-
跟平常一样写代码 写代码的时候要注意命名
第四步
-
设置最低支持版本和暴露头文件(别人能看到的.h文件)
第五步
- 运行代码生成对应库(模拟器和真机下分别在debug和release环境下运行代码
[最后合并的时候注意对应]
,总共是4次,右键点击项目目录里的库.a文件,Show in Finder会发现4有个文件,对应刚才4次运行结果)
第六步
合并库文件(注意空格)
说明:最终生成了两个合并好的库文件,debug和release。使用时根据当前工程配置情况选用对应库文件。
生成debug库文件
分别将模拟器和真机的两个.a文件合并成一个.a文件 打开终端 lipo -create xxx/xxx/xx/xx.a xxx/xxx/xx/xx.a -output xxx/xx.a 前两个xxx/xxx/xx/xx.a
分别是模拟器和真机的.a文件的路径 后面的是你要存放生成的.a文件的路径 路径一定要是.a文件(最后这里的库名字是你自己写在路径里的,由你自己决定)
终端:
lipo -create
debug下模拟器库文件路径
debug模式下真机库文件路径
-output
合并后库文件路径
生成release库文件
终端:lipo -create
release下模拟器库文件路径
release模式下真机库文件路径
-output
合并后库文件路径
第七步
- 使用!
- 将对应的合并好的.a文件添加到自己的工程中,看是否能正常使用。
- 注意,制作的
.a静态库
是没有.h的引用头文件的
,这里需要自己手动添加,在刚才的四个文件夹的include
里,任选一个,添加至项目.
二、制作Framework文件
第一步
- 创建一个新项目,
Cocoa Touch Framework
第二步
-
Build Active Architecture Only
设置为NO
(不同机型的架构不一样,设置为NO适配不同机型)
第三步
- 加入自己的各种类文件,注意命名
第四步
- 暴露头文件
注意:framework工程新建就有一个.h文件,其实就是一个主头文件.我们在主头文件中导入需要导入的头文件,后面我们在使用这个静态库的时候只需要导入这个主头文件即可.就像我们使用很多第三方开源框架一样.
第五步
- Build Setting 搜索
linking
设置为静态库(默认是动态库), 将Mach-O Type
设为Static Library
,framework可以是动态库也可以是静态库,对于系统的framework是动态库,而用户制作的framework只能是静态库.
Link With Standard Libraries 设置为 NO(下图漏了)
设置Dead Code Stripping 为NO是编译选项优化,包瘦身(可不改)
第六步
记得设置最低的支持版本
-
与
.a
一样,进行command+B
第七步
- 合并:这里的合并指的是
1.debug 下真机+模拟器合并
2.release 下真机+模拟器合并
- 注意:output文件后缀为.lipo
生成的.lipo文件去掉后缀名,改为与合并前文件一样的名称,拖入开始运行生成的人一个文件中,替换原来的.
lipo -create /Users/qujiahong/Library/Developer/Xcode/DerivedData/JHSomesLib-becdskpvrczmkueccmpfgkjviinr/Build/Products/Debug-iphonesimulator/JHSomesLib.framework/JHSomesLib /Users/qujiahong/Library/Developer/Xcode/DerivedData/JHSomesLib-becdskpvrczmkueccmpfgkjviinr/Build/Products/Debug-iphoneos/JHSomesLib.framework/JHSomesLib -output /Users/qujiahong/Desktop/ForPlugin/firstLib/JHSomesLib
- 合并自己对应环境下的,对应使用即可
第八步
使用!
-
导入framework.
第九步、补充:这里还有一种自动合并的方法,利用脚本
- 新建Aggregate Target
(在当前的这个工程下,点击图中的 + )
- 脚本植入代码
(推荐)
:
#!/bin/sh
#要build的target名
TARGET_NAME=${PROJECT_NAME}
if [[ $1 ]]
then
TARGET_NAME=$1
fi
UNIVERSAL_OUTPUT_FOLDER="${SRCROOT}/${PROJECT_NAME}/"
#创建输出目录,并删除之前的framework文件
mkdir -p "${UNIVERSAL_OUTPUT_FOLDER}"
rm -rf "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework"
#分别编译模拟器和真机的Framework
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
#拷贝framework到univer目录
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework" "${UNIVERSAL_OUTPUT_FOLDER}"
#合并framework,输出最终的framework到build目录
lipo -create -output "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}"
#删除编译之后生成的无关的配置文件
dir_path="${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/"
for file in ls $dir_path
do
if [[ ${file} =~ ".xcconfig" ]]
then
rm -f "${dir_path}/${file}"
fi
done
#判断build文件夹是否存在,存在则删除
if [ -d "${SRCROOT}/build" ]
then
rm -rf "${SRCROOT}/build"
fi
rm -rf "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" "${BUILD_DIR}/${CONFIGURATION}-iphoneos"
#打开合并后的文件夹
open "${UNIVERSAL_OUTPUT_FOLDER}"
- 或者这一段脚本
(二选一)
if [ "${ACTION}" = "build" ]
then
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}.framework
DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework
SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
#ditto "${DEVICE_DIR}/Headers" "${INSTALL_DIR}/Headers"*
lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}"
open "${DEVICE_DIR}"
open "${SRCROOT}/Products"
fi
三、总结
1 、注意理解:无论是.a静态库还.framework静态库,我们需要的都是二进制文件
+.h
+资源文件
,不同的是,.a本身只是二进制文件,需要配上.h和资源文件才能使用,而.framework本身已经包含了二进制文件、.h和资源文件,可以直接使用。
2 、图片资源的处理:两种静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。新建一个文件夹,把它改名为.bundle,右键->显示包内容,之后就可以向其中添加资源文件。
3、 如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。