关于Swift集成framework的方法也查了很多资料,但大同小异,主要有两种
1.利用cocoaTouch Framework建立如图
进入xcode之后,里面就是制作framework的界面和正常的项目一样,不过不能运行(ps:这里只是一个SDK并不是一个工程),只能编译,编译过之后就是就可以拿到framework的包,包的位置在products这个目录下如图
这里解释一下,图中products目录下就是我拿到的framework,右边有代码的文件是TestVC这个控制器类的测试代码,XRFramework02是随工程建立之后产生的,Helloworld(继承自NSObject)、TestVC、TestVC02这三个文件是我建立的测试文件,后面两个继承自UIViewController
注:补充一下swift的访问控制的关键字
fileprivate :如名字一样,只有这个文件才能访问.
private: 只能在作用域访问.
interal: 默认,在整个模块可以访问.
public: 在模块里面是可以继承或者重写,在模块外可以访问,但不可以重写和继承.
open:在所有模块都可以访问,重写和继承.
open> public > interal > fileprivate > private
framework这里简单解释一下,这里会有运行环境不同分为Debug和Release,在两种环境下都有模拟器测试和真机测试,根据自身情况可以选择不同运行环境和测试环境,编译就是Command+B,编译完成就可以在Products目录下找到framework包,从find中找到包,拖入自己的项目,在需要使用framework的文件中导入包名
上图是另外一个测试项目,上面导入包,下面就可以调用framework的代码,因为我在TestVC 类的代码是利用Alamofire调用的天气接口(网上找的),代码直接在TestVC 类viewDidLoad添加的,所以进入TestVC 类就会执行被封装进framework的代码,有不明白的地方请看文中的图片。
前面说的framework是直接编译之后 ,然后去framework所在文件夹中拖出来,拖到项目中的,因此可能会有运行环境和测试环境问题,其实这方面的问题也简单:在什么运行环境和测试环境中做的framework,就在什么环境下调用framework,一般也不会有什么问题。
通用版的framework自作:
注: 引入动态库的时候,需要在工程配置嵌入动态库,不然的话会报错
如果工程是oc工程的话,还需要在build Setting里面配置一个选项为YES,否则也是运行报错
合并模拟器版framework和真机版framework
分别用真机和模拟器build,右键选择打开framework的目录,会发现有两个release版本的framework.
使用 lipo 命令合并两个版本的framework.
lipo -create ./Release-iphonesimulator/myFramework.framework/myFramework ./Release-iphoneos/myFramework.framework/myFramework
-output ./myFramework
通用版本framwork:
通用版本的framework即将Debug/Release模式下编译生成的framework(有两种模拟器和真机环境下的应用场景),通用版本即是将Debug/Release模式下生成的framework合并成一个新的文件,然后将新生成的文件贴到Debug/Release的framework中,现在再拿这个新的framework就是通用版本的framwork。
使用脚本自动化生成和合并framework.首先添加新的target.
8.在红框里面输入一段脚本,然后选择这个target进行build即可生成.
脚本代码:
FMK_NAME=myFrameworkINSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.frameworkWRK_DIR=buildDEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.frameworkSIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.frameworkxcodebuild
-configuration "Release" -target"${FMK_NAME}"
-sdk iphoneos clean buildxcodebuild -configuration"Release" -target"${FMK_NAME}"
-sdk iphonesimulator clean buildif [ -d"${INSTALL_DIR}"
]thenrm -rf"${INSTALL_DIR}"fimkdir -p"${INSTALL_DIR}"cp
-R"${DEVICE_DIR}/""${INSTALL_DIR}/"cp
-R"${SIMULATOR_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
“${INSTALL_DIR}"
在SDK开发的工程中如果单独建立Cocoa Touch Framework的项目做framework的话,无法确定开发需要集成的功能,是否正常,有时候需要一边做功能另外可以运行测试功能,这里也补充一下这种情况的做法,新建项目 -> 选择target -> 选择Add Target ->Cocoa Touch Framework,流程就是这样的流程,下面上图说明:
在上图中第二步箭头位置点击选择Add Target,然后再出来的窗口中选择Cocoa Touch Framework,建立玩Cocoa Touch Framework,剩下的做法就和上面的做法一样了。
最近发现一个新的问题,当framework中封装的文件包含xib/storyBoard 时,直接调用viewcontroller是不能呈现xib/storyboard上面的内容的,因此想要呈现xib/storyboard的内容可以采取以下的办法
这里分两种情况第一种针对viewcontroller的xib文件具体做法如下所示:
let bundle = Bundle.init(for: TestViewController.self)
let testVC = TestViewController.init(nibName: "TestViewController", bundle: bundle)
self.present(testVC, animated: true, completion: nil)
这里的TestViewController是测试viewcontroller,带有xib,如果viewcontroller不带有 xib 关联文件,在调用framework的时候,就可以直接push或者present调用,可以正常显示。
第二种情况是framework带有storyboard,然后调用framework的storyboard中的viewcontroller,这里介绍使用方法如下:
let path = Bundle.main.path(forResource: "XRFramework05", ofType: "framework")
print("查看路径:\(path!)")
let bundle = Bundle.init(path: path!)
let storyBoard = UIStoryboard.init(name: "TestMyStoryboard", bundle: bundle)
let loginVC = storyBoard.instantiateViewController(withIdentifier: "TestViewController02")
self.present(loginVC, animated: true, completion: nil)
这里有一点需要注意,调用framework的viewcontroller的时候,需要在项目的Build Phase ->copy bundle resources中添加framework,这里还有一个点需要注意就是上面的let
loginVC = storyBoard.instantiateViewController(withIdentifier: "TestViewController02")这一行代码中的identifier是storyboard的xib文件的storyboard ID没有添加需要自己添加上,这样才能正常调用,否则会报错。
另外再补充一条,我这里用的Swift 3.2,这里使用范围也是在Swift 3.2的项目,理论说情况类似,但是在Swift 4.0 中会抛弃一些方法,可能会出现问题,这里暂时先不说。