iOS程序中为了保持多个项目代码的互用或者提供自己代码给别人执行又不想暴露自己的源码,通常采用建立静态库或者动态库的方式,今天我就介绍下这两个库的建立以及使用
目录
4.1 按如下方式设置虚拟机状态下可以生成所有虚拟机都能使用的库:将其设置为NO
一、.a库的创建以及使用:
1、基本创建:
.a一定要选取为oc语言,不然后面没发引用
接下来在库里面编写需要的代码,例:
LibTest.h里面:
+(void)showMsg;
LibTest.m里面:
+(void)showMsg{
NSLog(@"ios lib test");
}
选择添加要暴露出的.h接口文件:
然后build就会出现生成的包了:
打开包内容:
将生成的包和.h文件放在同一文件夹以供调用:
2、oc工程调用:
放在同一文件中直接引入项目:
.h导入,.m调用:
#import "LibTest.h"
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[LibTest showMsg];
}
这样同一虚拟机就可以调用了,不同虚拟机、真机、打包问题将在下面介绍
3、swift工程调用:
因为.a包是oc的所以需要引入桥接文件:
建立方式:新建oc文件自动配置:
如果没有弹出来,或者点击了取消:
新建header文件:
配置桥接文件:Building Setting里面,ocBridgingHeader配置如下路径:工程名/文件名.h
新建.h刚出来改为如下图所示倒包,这样就完成oc和swift混编了:
swift调用:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
LibTest.showMsg()
}
二、.framework创建以及使用:
1、工程外创建引用
1.1、工程外创建:
编辑代码,外部可以调用的类用public修饰:
1.2调用:直接framework包拖入调用
如果提示找不到,去配置里面添加引用:
2、工程内创建引用:
2.1 创建:
在工程内创建引用,源码可见,但可以供其他项目直接调用,且不同虚拟机、真机等不需要单独处理直接运行就好,打包也不会因为二进制出问题,最好搭配gitsubmodules使用
首先最好见一个workspace,项目添加在这个里面,按上面的添加.framework工程,在这步选择加入哪个workspace:
内容填充:
注意需要调用的类和方法用public修饰:(字段权限:public 可以跨库调用,open:本库里面可以调用,interval:默认普通权限,fileprivate:本文件里面可以调用,private:只有本类里面可以访问)
2.2 调用:
添加引用:
直接import调用:
三、archive处理
按上面方式打包调用时,archive打包上传会崩溃提示:
需要在生成库时做这个设置:
更改:
添加:
这样重新生成就可以了
四、兼容真机、虚拟机
按上面在项目外围静态库生成,拖入调用只能使用当前虚拟机的包,不能满足要求,可以按如下方式设定:
4.1 按如下方式设置虚拟机状态下可以生成所有虚拟机都能使用的库:将其设置为NO
4.2 .a真机虚拟机合并
任选一虚拟机cmd+b
真机cmd+b
libLibtest.a右键showinfinder
将上图两个.a包合并:lipo -create 合并文件文件路径 合并文件文件路径 -output 生成文件名
我这里就是:lipo -create Debug-iphoneos/libLibTest.a Debug-iphonesimulator/libLibTest.a -output libLibTest.a 生成如下.a文件
将生成的.a文件和.h文件放在一个包里面就可以调用了:
4.3 .framework虚拟机合并
同上真机虚拟机运行,合并这两个文件:
lipo -create Debug-iphoneos/LYH.framework/LYH Debug-iphonesimulator/LYH.framework/LYH -output LYH 生成新的LYH文件:
随便拷贝一个已经生成的framework,替换LYH运行文件:
拷贝合并真机和虚拟机的swiftModules:
这个framework就可以直接调用了
五、资源文件处理
对于库里面包含资源文件(图片、xib、国际化)的,需要提供bundle处理:
5.1 不新建bundle
对于没有手动创建bundle的,接口需要提供出自己库的bundle接口以供调用:
库里面提供外部方法:
import Foundation
public class FrameWorkManager {
public init() {
}
public static func bundle() -> Bundle{
return Bundle.init(for: self)
}
}
外部调用库资源:
import Foundation
import UIKit
import FrameworkTest
extension UIImage{
static func imageInFramework(_ named : String) -> UIImage?{
return UIImage.init(named: named, in: FrameWorkManager.bundle(), compatibleWith: nil)
}
}
let image = UIImage.imageInFramework("baiduLogin")
5.2 手动创建bundle:
这个网上比较多,直接新建bundle文件放在里面,bundle调用即可。我喜欢上面那种,这个就不多做说明了。