ios编译framework
⑴ iOS 制作自己的Framework(引入第三方库)
一、创建工程并新建Framework Target
二、创建测试工程
Framework制作好了,我们需要一个Target测试一下吧。那么直接在刚刚创建的这个工程里面,新建一个Single View APP的Target就好了。
三、引入第三方库
如果我们在制作Framework的时候,需要用到第三方库怎么办呢?网上有轮子,而且有专人维护,总比我们自己造的强。但是如果公司有条件的话,最好是不引入第三方库。
我们在引入第三方库的时候,使用cocoapods进行管理,假设我们的SDK需要AFNetworking这个库,按下面操作引入。
四、创建Framework打包脚本
五、运行
六、导出Framework给他人使用
本文完结。喜欢点个喜欢吧~~
⑵ iOS之Framework相关知识
lipo -info FramworkName.framework/FrameworkName
1、真机armv7、arm64
2、模拟器i386、x86_64
file FramworkName.framework/FrameworkName 如果有 dynamically 字段的话是动态库,反之为静态库
在项目中, 以Embedded Binaries 方式导入为动态库;以Link Binary With Libraries 方式导入为静态库
1、手动合并 lipo -create 真机路径 模拟器路径 -output 真机路径
2、自动合并脚本
(1)build Phases新建个Run Script输入以下脚本
(2)先随便选个模拟器编译,(提示失败没问题),然后再选择真机编译下,提示成功即在工程的procts文件夹下可看到合并好的framework包
lipo -remove 架构名(i386) Framework.framework/FrameworkName -o Framework.framework/FrameworkName
1、分别拆分出不同架构的SDK
(1)创建不同架构的文件夹
(2) lipo FramworkName.framework/FrameworkName -thin 架构 -output 架构文件夹/FrameworkName
2、分别分解出 .o 文件
cd 架构文件夹
ar xv FrameworkName
3、分别去除和别人重复的 .o 文件
4、分别重新封装 .o 文件为framework
ar rcs FrameworkName *.o
5、合并所有新封装的SDK
lipo -create 文件1 文件2 文件3 文件4 -outout FrameworkName
⑶ iOS 静态库和动态库打包framework流程(纯swift版/swift、OC混编版)
选择 iOS -- Framework&Library , 点击 next
如果打包文件中使用了第三方库,建议pod管理,并告知用户使用pod安装,避免用户重复导入。跟平时开发逻辑一样,打开 .xcworkspace 工程。
操作完之后工程目录显示
把打包需要的文件添加到项目中。 如果想要这个类或类里面的方法被外面使用,需要配合pubic修饰供外面使用
由于以上获取的framework只能在对应的版本上运行(即真机只能在设备上运行模拟器版本只能在模拟器上面运行使用),所以需要合并framework版本。
合并framework版本:
sudo lipo -create (此处请填写真机AppVest文件路径) (此处填写模拟器AILLSDK文件路径) -output 自定义合成文件存储路径(合成文件的名字AILLSDK)
因为真机版本和模拟器版本的framework都存在arm64架构,导致架构重复,不出意外,会提示合并失败。如下
处理合并失败的问题
最后,将 XX.framework(真机或者模拟器framework都可)文件夹 拷贝出来,替换AILLSDK(本文使用的)为刚才合并的新文件。
查看替换后的framework支持全部真机模拟器架构。
我在合并binary文件之后,仅拷贝出 Release-iphoneos 文件夹下的 XXX.framework ,并替换掉AILLSDK二进制文件。导入项目中使用模拟器运行,报错,显示找不到架构。
解决方案
拷贝所有的moles到
再替换掉AILLSDK二进制文件,导入项目,如果framework中内含第三方库,需要在所在的工程中使用pod加载,否则会提示编译失败。
至此,编译成功。🎉🎉🎉🎉🎉
不管是在framework封装的内部,内部swift类调用内部的OC类,还是内部的OC类使用内部的swift类,还是外部工程swift类使用framework内部OC类,还是外部工程OC类使用framework内部swift类。原理是一致的,以下来介绍下:
在 AILLSDK.h(你自己创建framework时候生成的.h文件) 中添加import导入
#import <AILLSDK/OC类名.h>
在oc的 .m 或 .h 文件中,导入 #import <AILLSDK/AILLSDK-Swift.h> , 也就是 你自己framework名-Swift.h
⑷ iOS Aggregate生成.framework
选中TARGETS的工程 —> 点击Editor —> 选择Add Target —> 创建Aggregate —> 点击Next创建
选择刚刚创建的Aggregate —> 选中Build Phases —> 点击左侧+ —> 选择 New Run Script Phase
复制脚本到刚刚新建的New Run Script Phase
复制完成如下图所示
选择刚刚创建的Aggreate —> 设备选择Generic iOS Device(iOS通用设备) —> command + B 编译
编译成功,会自动跳出一个finder,即生成的.framework,支持真机和模拟器
问题描述:执行上述命令在部分项目会出现如下问题
解决方案:
⑸ iOS 打包framework(包含第三方framework或.a文件)
1.创建framework工程
2.将framework拖进工程中,工程分两部分,一个是原始文件(红色部分),一个是我需要进行封装的文件(蓝色部分):
3.将bitcode置为NO
4.1 选择工程->targe->build setting,在搜索框中搜索linking,进行如下设置
4.2 将Build Active Architecture Only 设为 NO
5.1 把要公开的头文件已到Public中去,在使用.framework时只能调用公开.h文件中的声明。
5.2 完成上述步骤之后,在HYSDK.h文件中,把所有需要暴露的.h文件都用#import < HYSDK/PublicHeader.h>引入,记住一定要将所有的需要暴露的.h文件都写在给定位置,不然编译后生成的.framework在引用的时候会有警告;
6.开始编译,选择Generic iOS Device 或者 真机 或 模拟器,编译一下,再选择模拟器环境编译一下
9.创建成功之后。新建工程。将新的framework再倒入进去。配置相关依赖库即可。如果报找不到第三方的库,则需要将第三方SDK.framework倒入进来即可。
⑹ iOS 在编译时出现 framework not found XXXX框架
iOS 在编译时出现 framework not found xxxx框架主要是由于你在添加框架时后期移除这个框架虽然被删除了但是还是被引用了,在Other Linker Flags中被引用,所以在编译时就会出现找不到这个框架
这时只要进入项目的Build Settings 找到Other Linker Flags中找到你的那个XXXX框架然后删除,重新编译就可以成功。
⑺ ios OC、swift混编制作framework
按照文档一步一步来
新建一个基于单页面工程,然后新建一个一个Target,选中Cocoa Touch Framework。然后,分别新建一个Swift文件和Objective C类,注意Target Member Ship选中Framework。类的内容如下:
OCSource.h
[图片上传失败...(image-8dab68-1634619754604)]
OCSource.m
[图片上传失败...(image-2c9071-1634619754604)]
Swift调用OC
新建SwiftSource.swift
[图片上传失败...(image-34eca8-1634619754604)]
然后,按照文档中,为了让Swift文件访问Objective C文件,我们应该在umbrella header,也就是MixFramework.h中,暴露所需要的header。
也就是,MixFramework.h,
[图片上传失败...(image-b166c3-1634619754604)]
然后,自信满满的点击build。
Boom~~~,编译不通过。
[图片上传失败...(image-6ca763-1634619754604)]
原因:OCSource.h默认编译的时候是Project权限. 为了在umbrella header中使用,要把这个文件的权限改成Public
按照图中的方式拖过去即可。
[图片上传失败...(image-f2d31d-1634619754604)]
嗯,现在build,可以看到build成功了。
OC调用Swift
在SwiftSource.swift中,增加一个类,
[图片上传失败...(image-98ce8c-1634619754604)]
然后,为了在OC中调用Swift的方法,我们需要导入头文件,这时候,OCSource.m文件内容如下
[图片上传失败...(image-f61fb3-1634619754604)]
然后,build,发现成功了,很开心。
外部调用
在ViewController.swift中,我们调用Framework中的内容。
[图片上传失败...(image-6be19c-1634619754604)]
然后运行,发现控制台打印出
[图片上传失败...(image-4b70-1634619754604)]
嗯,framework打包成功了。
问题
通常,我们希望暴露给外部的接口是纯Swift,而OC文件的具体接口应该隐藏,这就是我标题中的优雅两个字的含义。
如果你好奇,你会发现,在ViewController.swift中你可以这么调用
[图片上传失败...(image-fefccf-1634619754604)]
也就是说,OC的内容也暴露出来了,这破坏了Framework的封装特性。
通过查看MixFramework的编译结果,发现最后暴露出的接口是这样子的
[图片上传失败...(image-8b0488-1634619754604)]
这一行,把OC对应的实现暴露出来了
[图片上传失败...(image-9c74a7-1634619754604)]
优雅的解决方案
不再通过umbrella header的方式让framework中的Swift调用OC方法。而是通过molemap。
新建一个mole.molemap文件,内容如下
[图片上传失败...(image-633a91-1634619754604)]
[图片上传失败...(image-d30f90-1634619754604)]
这里的#(SRCROOT)是XCode的宏,会自动替换成项目所在的根目录,这里输入的路径是mole.molemap文件所在的路径。
然后,删除MixFramework.h(umbrella header)中#import 的OC header。
把OCSource.h的权限改回默认的project。
[图片上传失败...(image-291cca-1634619754604)]
再编译,发现OC的类被隐藏了。
⑻ ios framework 制作和合并
1、 run -> debug 模式换成 release
2、默认创建的framework 是动态库,在 build setting 设置 Mach-O type = StaticLibrary
3、输入 在 build setting 设置 Build Active Architecture Only = NO 代表 当前输出的是 支持所有设备, YES 是当前选择的设备。
1创建 demo 工程,然后 在 file > save as workspace
关闭项目,打开 .workspace ,然后把 framework 工程拷贝到同目录,在工程中拖入framework的 .project 文件, 在 run 的里面可以选择 framework或者demo工程,直接修改framework之后 command+b ,切换到demo 运行即可,调试
在xcode12之前,上面的操作,完全可以输入合并的。
xcode12上出现的
我自己的做法是,在模拟器 command+b 的时候 修改配置项:
导出真机的时候,删除加入的 arm64 执行 command+b ,
这样再去合并。就能解决这个问题了。
貌似是swift版本的才有这个问题
在模拟器和真机合并framework之后,还会出现这个问题,就需要把 framework 中 Moles 的文件拷贝到合并的 framework 中:
如图, -output 路径为 Realse-iphoneos ,所以把 Realse-iphonesimulator->Moles 中的红色标注,拷贝到 Realse-iphoneos 对应位置。
解决问题。