六月潮湿天气的日数比五月多,比四月也多。周四晚踢足球,深圳多雨,中午电闪雷鸣雨不停,有人建议取消场地,我想雨后终究会见到彩虹,不一会,雨停。
项目需求提供framework,记录下过程。
一、什么是库?
库是共享程序代码的方式,一般分为静态库和动态库。
二、静态库和动态库的区别?
静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多分拷贝冗余拷贝。
动态库:链接不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。
三、iOS里静态库形式?
.a和.framework
四、iOS里动态库形式?
.dylib和.framework
五、framework为么可以既是静态库有事动态库?
系统的.framework是动态库,我们自己建立的.framework是静态库。
六、.a与.framework有什么区别?
.a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。
.a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用。
.a + .h + sourceFile = .framework。
建议用.framework。
七、为什么要使用静态库?
方便共享代码,便于合理使用。
实现iOS程序的模块化。可以把固定的业务模块化成静态库。和别人分享你的代码库,但不想让别人看到你代码的实现。开发第三方sdk的需要。
提供给接入方使用的是文件,一般是一个.framework和一个同名的.bundle文件。
1、嵌入包含.bundle的framework到接入方的embeded binaries里面,刚开始想着是否能只提供一个.framework文件,bundle包含在里面。可是可以,只是需要将打出来的.framework导入到embeded binaries中。但是接入此.framework后,打包会报错。
![](https://img.haomeiwen.com/i4193251/0acccb96e03711f7.png)
点击show logs,did not contain a "archived-expanded-entitlements.xcent" resource
解决办法:一个static的libraryxxx.framework被添加在Embedded Binaries里面了,从Embedded Binaries移除framework,添加在Link Frameworks and Libraries里面。
只能作罢,只有动态库能放到embeded binaries中,Xcode也能制作动态库,只是不能上传AppStore。
通过嵌入embeded binaries里面打出来的,最后形成.app文件右键显示包内容之后和可以看到一个Frameworks的文件夹。里面有嵌入embeded binaries的所有framework。
![](https://img.haomeiwen.com/i4193251/d890df64479c8100.png)
- 新建一个workspace,添加两个project:CVideoProject,CVideoDemoProject。在CVideoProject中添加一个target:CVideoBundle。相当于总共有三个target,方便调试。
1.新建静态库:static framework。
![](https://img.haomeiwen.com/i4193251/54a4861ef40814df.png)
2.修改配置信息
每次build时不是只生成支持一种设备的framework
Snip20190616_3.png
添加framework支持所有类型设备。
Snip20190616_4.png
arm64:iPhone6s | iphone6s plus|iPhone6| iPhone6 plus|iPhone5S | iPad Air| iPad mini2(iPad mini with Retina Display)
armv7s:iPhone5|iPhone5C|iPad4(iPad with Retina Display)
armv7:iPhone4|iPhone4S|iPad|iPad2|iPad3(The New iPad)|iPad mini|iPod Touch 3G|iPod Touch4
i386是针对intel通用微处理器32位处理器
x86_64是针对x86架构的64位处理器
模拟器32位处理器测试需要i386架构,
模拟器64位处理器测试需要x86_64架构,
真机32位处理器需要armv7,或者armv7s架构,
真机64位处理器需要arm64架构。
需要暴露给接入方使用的头文件移到public路径中。
Snip20190616_5.png
Snip20190616_8.png
3.在framework中新建bundle。
![](https://img.haomeiwen.com/i4193251/18be89a16c61ba9f.png)
![](https://img.haomeiwen.com/i4193251/547653eabc762e97.png)
导入用到的资源文件
Snip20190616_14.png
修改bundle文件的参数配置
Snip20190616_15.png
Snip20190616_16.png
Snip20190616_18.png
Snip20190616_20.png
编译bundle target生成bundle。
Snip20190616_23.png
Snip20190616_24.png
Snip20190616_25.png
编译framework发现framework中包含bundle。
Snip20190616_26.png
1、将bundle放入到framework中,打出来的framework中包含bundle,此时代码里面引入图片的路径有变。在workspace的Demo中的embeded binaries引入framework。
![](https://img.haomeiwen.com/i4193251/1f4631cd7f4391d8.gif)
通过打开CVideoDemo.app显示包内容发现如果嵌入到embeded binaries中的framework都放在一个frameworks文件夹路径下。而CVideo.bundle就在Frameworks/CVideo.framework路径下,图片的路径据此找到。
1.gif
-(void)setupBackNaviBar
{
self.navigationItem.leftBarButtonItem = nil;
self.backView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 44)];
CVideoAddAreaButton *backButton=[CVideoAddAreaButton buttonWithType:UIButtonTypeCustom];
backButton.shouldExpandClickArea = YES;
[backButton setFrame:CGRectMake(0, 0, 44, 44)];
[backButton setImage:[CVideoBundle CVideoImageWithName:@"icon_back"] forState:UIControlStateNormal];
[backButton addTarget:self action:@selector(onNaviBack) forControlEvents:UIControlEventTouchUpInside];
[self.backView addSubview:backButton];
self.closeButton=[CVideoAddAreaButton buttonWithType:UIButtonTypeCustom];
self.closeButton.shouldExpandClickArea = NO;
[self.closeButton setFrame:CGRectMake(32, 0, 44, 44)];
[self.closeButton setImage:[CVideoBundle CVideoImageWithName:@"icon_close"] forState:UIControlStateNormal];
[self.closeButton addTarget:self action:@selector(closeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.backView addSubview:self.closeButton];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:self.backView];
}
+ (NSString *)CVideoBundlePathForResource:(NSString *)name ofType:(NSString *)type {
NSString *bundlePath = [self getCVideoBundlePath];
return [[NSBundle bundleWithPath:bundlePath] pathForResource:name ofType:type];
}
+ (UIImage *)CVideoImageWithName:(NSString *)name {
//bundle放入framework中,framework嵌入embeded binaries中的图片路径
name = [NSString stringWithFormat:@"%@@%dx", name, (int)[UIScreen mainScreen].scale];
NSString *imagePath = [CVideoBundle CVideoBundlePathForResource:name ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
//bundle单独拖入Demo中的bundle路径
// NSString *imagePath = [NSString stringWithFormat:@"%@/%@",[self getCVideoBundlePath],name];
// UIImage *image = [UIImage imageNamed:imagePath];
return image;
}
+ (NSString *)getCVideoBundlePath {
static NSString *bundlePath;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//bundle放入framework中,framework嵌入embeded binaries中的bundle路径
bundlePath = [[NSBundle mainBundle] pathForResource:@"Frameworks/CVideo.framework/CVideo" ofType:@"bundle"];
//bundle单独拖入Demo中的bundle路径
// bundlePath = [[NSBundle mainBundle] pathForResource:@"CVideo" ofType:@"bundle"];
});
return bundlePath;
}
2、显然,虽然将bundle放入framework中,提供给接入方只需要提供framework文件给接入方而不需要提供bundle文件,但是打包的时候会报错,所以还是要将bundle和framework分开提供。
![](https://img.haomeiwen.com/i4193251/d7254735c99864dd.gif)
- 图片的路径。
-(void)setupBackNaviBar
{
self.navigationItem.leftBarButtonItem = nil;
self.backView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 44)];
CVideoAddAreaButton *backButton=[CVideoAddAreaButton buttonWithType:UIButtonTypeCustom];
backButton.shouldExpandClickArea = YES;
[backButton setFrame:CGRectMake(0, 0, 44, 44)];
[backButton setImage:[CVideoBundle CVideoImageWithName:@"icon_back"] forState:UIControlStateNormal];
[backButton addTarget:self action:@selector(onNaviBack) forControlEvents:UIControlEventTouchUpInside];
[self.backView addSubview:backButton];
self.closeButton=[CVideoAddAreaButton buttonWithType:UIButtonTypeCustom];
self.closeButton.shouldExpandClickArea = NO;
[self.closeButton setFrame:CGRectMake(32, 0, 44, 44)];
[self.closeButton setImage:[CVideoBundle CVideoImageWithName:@"icon_close"] forState:UIControlStateNormal];
[self.closeButton addTarget:self action:@selector(closeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.backView addSubview:self.closeButton];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:self.backView];
}
+ (NSString *)CVideoBundlePathForResource:(NSString *)name ofType:(NSString *)type {
NSString *bundlePath = [self getCVideoBundlePath];
return [[NSBundle bundleWithPath:bundlePath] pathForResource:name ofType:type];
}
+ (UIImage *)CVideoImageWithName:(NSString *)name {
//bundle放入framework中,framework嵌入embeded binaries中的图片路径
name = [NSString stringWithFormat:@"%@@%dx", name, (int)[UIScreen mainScreen].scale];
// NSString *imagePath = [CVideoBundle CVideoBundlePathForResource:name ofType:@"png"];
// UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
//bundle单独拖入Demo中的bundle路径
NSString *imagePath = [NSString stringWithFormat:@"%@/%@",[self getCVideoBundlePath],name];
UIImage *image = [UIImage imageNamed:imagePath];
return image;
}
+ (NSString *)getCVideoBundlePath {
static NSString *bundlePath;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//bundle放入framework中,framework嵌入embeded binaries中的bundle路径
// bundlePath = [[NSBundle mainBundle] pathForResource:@"Frameworks/CVideo.framework/CVideo" ofType:@"bundle"];
//bundle单独拖入Demo中的bundle路径
bundlePath = [[NSBundle mainBundle] pathForResource:@"CVideo" ofType:@"bundle"];
});
return bundlePath;
}
网友评论