美文网首页深入浅出iOSiOS-swiftSDK开发
xcode7制作framework,结合xib,storyboa

xcode7制作framework,结合xib,storyboa

作者: 小璐有大大的梦想 | 来源:发表于2016-09-23 23:28 被阅读4317次

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

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)

防止做法:

前缀.png

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

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


Aggregate.png

2、添加script到新建的Target

RunScript.png

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

copyScript.png

脚本:

# Sets the target folders and the final framework product.
# 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME
FMK_NAME = "MyFramework"
FMK_NAME=${PROJECT_NAME}

# 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

># -configuration ${CONFIGURATION}
# Clean and Building both architectures.
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

># 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 binary files (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 "${SRCROOT}/Products/"

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

//真机支持的架构
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

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 <Foundation/Foundation.h>
@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引入框架的时候

SDK.png

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

相关文章

网友评论

  • 0d7e5df3c2b3:请问我编译bundle工程后,Product->StaticLibBundle.bundle 文件还是红色的是为什么
  • Laughingg://这个Class对应你工程所在的类名
    [[NSBundle bundleForClass:self.class] loadNibNamed:@"ColorView"
    owner:self options:nil];
    //这个对应你的FrameWork的Bundle Identifier
    [[NSBundle bundleWithIdentifier:@"com.xxx.xx"] loadNibNamed:@"ColorView"
    owner:self options:nil];


    这样搞是不行的吧 。

    你设置farmework 为 static lib 试试,就找不到文件。
    Laughingg:@小璐有大大的梦想 你确定你的是静态库吗?
    小璐有大大的梦想:@Laughingg 试了 不行 [[NSBundle bundleForClass:self.class] loadNibNamed:@"ColorView"
    owner:self options:nil]; 这样加载的路径不对 和我打印的main bundled的路径一样 这样只会在主bundle里找 而不会去加载我自定义的bundle 推荐: [NSBundle bundleWithPath: [[NSBundle mainBundle] pathForResource:@"xxx" ofType: @"bundle"]]
  • b6a42eecbbfb:请问下,(storyboard文件放在bundle项目工程里面。也就是两个项目,但是呢,只要storyboard上的类名和你要拖入的类名一致,还是可以照样拖线的),关于这句,线是可以拉没错,但是我建个测试工程把framework和bundle加进去运行却有报错Unknown class xxxxx(your class name) in Interface Builder file.你有遇到过么
    小璐有大大的梦想:@yy天空之上 你说的没错 我说的是会不会是你xib ,storyboard上那些子view上写了自定义类名 而那个类名是你framework没有的 报这个问题就是你bundle里存在未知的类啊
    b6a42eecbbfb:@小璐有大大的梦想 但是两者的类名就是一致的啊,不一致线根本就拉不到framework里的类的吧
    小璐有大大的梦想:@yy天空之上 要保证xib上的类名和framework里面的类名一致哦 就不会报这个错误 你检查下

本文标题:xcode7制作framework,结合xib,storyboa

本文链接:https://www.haomeiwen.com/subject/dhtxyttx.html