xcode7制作framework,结合xib,storyboard,资源文件等

公司项目中需要用到SDK,查阅相关文档,整理如下:
实现主要以framework+bundle的形式封装SDK,framework里面放置代码,bundle里面放置xib,storyboard,图片,音视频等资源文件。
一:创建framework
1:打开xcode,新建iOS->Framework & Library->Cocoa Touch Framework

xcode7制作framework,结合xib,storyboard,资源文件等_第1张图片
cFramework.png

2、在PROJECT->Deployment Target->iOS Deployment Target选择你需要支持的最低系统。同样的操作在TARGETS中,Deployment Info->Deployment Target

3、我的项目是支持iOS7.0的,此时运行要报ld: warning: embedded dylibs/frameworks only run on iOS 8 or later的警告。这是因为工程的默认设置是Dynamic Framework,需要在iOS8.0才能使用。
所以我们要做的将Dynamic Framework设置为Static Library,在Build Settings->Linking->Mach-O Type->Static Library

4、这里要注意,在编译时,不要将图片文件,xib,媒体文件放在工程里面,否则编译后framework中会出现大量的零散图片文件在里面。这时需要将图片等资源放在.bundle文件中,在第三步介绍。

5、这样打包的framework依然有问题,如果你用了Category,别人在用你的framework时会发生崩溃。这时别人在引用时需要在工程中other linker flags中添加-objC如果依然有问题,再添加-all_load。

6、终于编译成功,但发现很多关于符号表的警告,这时需要将Generate Debug Symbols设置为NO即可关闭符号表警告。

7、但是我需要支持bitcode,以上设置后并不能使framework支持bitcode,因此还需要进行额外的设置一个命令让其支持bit code。在TAGETS的Build setting中搜索Other C Flags,添加命令“-fembed-bitcode”。同样的设置在PROJECT中。如果不进行以上操作。别人在集成你的framework时可以编译,亦可以真机测试。唯独在打包时会发出警告并打包失败。警告为framework不支持bitcode!

8、无论SDK还是Framework都需要暴露公共的头文件以供使用者读取和。在TARGETS->Build Phases->Headers里面,有三种类别。Public(公共的),这里存放公开的头文件。Private(私有的)这里存放私有的Header,虽然说是私有的,但是还是公开的头文件,编译之后仍然可以framework包里面找到。所以有些Header是不想给别人看到的,必须要放在Project中。

9、打包。Edit Scheme->Build Configuration->选为Release然后Run即可.

注意:自己的SDK最好在每个类名前加个前缀,以防止下面未来可能发生的重复引入错误。

ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

防止做法:

xcode7制作framework,结合xib,storyboard,资源文件等_第2张图片
前缀.png

附加:这样做出来的framework只能在模拟器或者真机上用,要想都可以用,请看下步。

二:合并SDK (暂不需要合并的同学请跳过此步)
1、在你的SDK项目中新建add target -> other -> Aggregate Target


xcode7制作framework,结合xib,storyboard,资源文件等_第3张图片
Aggregate.png

2、添加script到新建的Target

xcode7制作framework,结合xib,storyboard,资源文件等_第4张图片
RunScript.png

3、复制下面提供的脚本,我实现是把以下脚本放入一个txt文件中,然后再拖进去运行的,方法自己选。运行之后会自动打开合并之后的framework文件,注意不要勾选Run script only when installing。

xcode7制作framework,结合xib,storyboard,资源文件等_第5张图片
copyScript.png

脚本:

# Sets the target folders and the finalframework product.
# 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME
# 例如: FMK_NAME = "MyFrameWork"
FMK_NAME=${PROJECT_NAME}
# Install dir will be the final output tothe framework.
# The following line create it in the rootfolder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework
# Working dir will be deleted after theframework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework
# -configuration ${CONFIGURATION}
# Clean and Building both architectures.
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos -arch armv7 -arch armv7s -arch arm64 -arch arm64e
clean build
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk
iphonesimulator clean build
# Cleaning the oldest.
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
# Uses the Lipo Tool to merge both binaryfiles (i386 + armv6/armv7) into one Universal final product.
lipo -create"${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -
output "${INSTALL_DIR}/${FMK_NAME}"
rm -r "${WRK_DIR}"
open "${INSTALL_DIR}"

可以自己修改以上脚本,以满足自己的需要的架构

//真机支持的架构
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos -arch armv7 -arch armv7s -arch arm64  clean build
//模拟器所支持的架构
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator -arch x86_64 -arch i386 clean build

4、查看是否成功
1.打开终端,进入到你的frameWork,cd xxxx/xxx.framework
2.查看架构支持,lipo -info xxx(xxx为framework的名字)
3.然后可以看到 xxx is architecture: x86_64(支持的架构显示在这)

设备的CPU架构(指令集)
armv7、armv7s为真机架构, i386为模拟器, x86_64支持32位, arm64支持64位
具体如下

模拟器:
4s-5: i386
5s-6s Plus: x86_64
真机:
armv6: iPhone、iPhone 2、iPhone 3G、iPod Touch(第一代)、iPod Touch(第二代)
armv7: iPhone 3Gs、iPhone 4、iPhone 4s、iPad、iPad 2
armv7s: iPhone 5、iPhone 5c
arm64: iPhone 5s、iPhone 6、iPhone 6 Plus、iPhone 6s、iPhone 6s Plus、iPad Air、iPad Air2、iPad mini2、iPad mini3

三:生成bundle文件
1、新建OS X->Framework & Library->Bundle

xcode7制作framework,结合xib,storyboard,资源文件等_第6张图片
2.png

2、在TARGTS->Build Settings->Deployment->iOS Deployment Target->选择自己需要支持的最低系统。

3、build后会生成一个bundle包,但在包中的图片由以前的png格式全部变成tiff格式。为了防止这种格式转变。需要在Build Settings->Architectures->Base SDK->选择iOS的SDK要支持的版本。这时TARGETS中Build Setting->User-Defined中会出现一个新的Key:COMBINE_HIDPI_DEBUG_INFO,把它设置为NO。

4、关于怎么取资源 提供LHBundleTool类获得

.h文件声明
#import 
@interface LHBundleTool : NSObject
+ (NSString *)getBundlePath: (NSString *)bundleName;
+ (NSBundle *)getBundle;
@end
.m文件实现
#import "LHBundleTool.h"
@implementation LHBundleTool
+ (NSBundle *)getBundle {
return [NSBundle bundleWithPath: [[NSBundle mainBundle] pathForResource:@“你bundle的名字” ofType: @"bundle"]];
}
+ (NSString *)getBundlePath: (NSString *) bundleName{
NSBundle *myBundle = [LHBundleTool getBundle];
if (myBundle && bundleName) {
return [[myBundle resourcePath] stringByAppendingPathComponent: bundleName];
}
return nil;
}
@end      

示例:加载bundle里面的xib

//通过[LHBundleTool getBundle]实例化bundle对象,取资源。
//eg:取view  _egView = [[[LHBundleTool getBundle] loadNibNamed:@“xxView” owner:self options:nil] lastObject];   

取图片路径

//我自定义的宏
#define LHSrcImg(file) [@"xxx.bundle" stringByAppendingPathComponent:file]

四:开发篇
framework是里面代码的实现,xib、storyboard文件放在bundle项目工程里面。也就是两个项目,但是呢,只要storyboard上的类名和你要拖入的类名一致,还是可以照样拖线的。
接下来演示加载故事版
1、在自己的framework里面创建LHVC控制器类
2、在bundle里面创建故事版文件取名Sec,放置视图控制器类,设置黄色,类名为LHVC。
3、在framework里面怎么加载故事版呢 和原来的方法一样,只是bundle换了而已

LHVC *lhVC = [[UIStoryboard storyboardWithName:@"Sec" bundle:[LHBundleTool getBundle]] instantiateViewControllerWithIdentifier:@"LHVC"];

4、自己再新开一个项目加入自己的SDK,测试代码。

五:第三方冲突的问题
有些必要的框架可能你SDK里面使用到了,项目工程里面也用到了,例如常用的AF,SD,MB等等,会有冲突。暂时自己的解决方案,在编写SDK引入框架的时候

xcode7制作framework,结合xib,storyboard,资源文件等_第7张图片
SDK.png

基本的流程已经介绍完了,第一次写文章,写得不好还请见谅,有更好的方法或思路,欢迎留言。参考了许多资料,赠人玫瑰,手有余香。

你可能感兴趣的:(xcode7制作framework,结合xib,storyboard,资源文件等)