iOS组件化开发之私有库创建(中)

前言

上一节我们通过把代码简单的拆分上传至github,通过cocoapods的远程私有库,把拆分的代码当作第三方库供我们使用,但是这种方式存在很多问题,实际项目使用这种简单粗暴的拆分也不可取,所以今天讲上一篇博客提到的第二种私有库创建方式,后面统一把私有库称作组件。

最后大概结构
image.png

本文要讲的是改变组件创建的方式,解决:

  • 组件使用.framework或者.a这两种静态库的方式创建
  • 组件单独依赖第三方,即有自己的podfile文件配置使用
  • 组件有自己单独的资源文件,在自己组件中使用资源文件
  • 组件工程调试及配置使用

吐槽部分可跳过

关于创建静态库的方式:

  1. 使用pod命令也就是pod lib命令创建
  2. 自己通过xcode手动创建

两种方式也无所谓好坏,都能够达到创建组件的目的。我想要说的是手动创建好处:

  1. 手动创建可以知道创建过程都做了什么,pod命令如果不去深究不能很明白原理。
  2. pod命令创建的组件只能放在Development Pods文件夹目录下
    ,对于手动创建使用target依赖的方式的方式来说显得不是很友好。
  3. pod命令创建的组件要添加资源文件时配置麻烦,手动创建简单。

当然手动创建也有缺点:

  1. pod命令创建方便快捷,手动创建相对步骤多
  2. 创建和编译过程需要踩坑。

总结:

  1. 如果是单纯抽取一些小东西用命令就可以没必要折腾
  2. 如果项目要大规模使用组件化建议手动创建方式

正文

上面说过创建组件静态库有两种,一种是.framwework另外一种是.a,两种方式创建大同小异。这里先以创建.a静态库的方式创建,相关节点配置不同点我会说明。

创建

打开xcode创建进入选择创建菜单


屏幕快照 2018-06-29 11.47.46.png

上图中Cocoa Touch Framework就是创建.framework静态库的方式,我们先创建.a形式的静态库 选中Cocoa Touch Static Library点击 next,填写你组件静态库的名称完成。

创建好之后像这样:


image.png

初始文件:

  1. 帮我们创建和静态库名称一样的文件夹和类(头文件)。
  2. 把创建的头文件加入到Copy Files 里面,这里要关心的一点是,如果你修改了头文件这里也要添加相应你要暴露的头文件,这里的头文件可以是多个也就是你想暴露多少个就添加多少个

添加podfile:

使用pod init 命令在根目录添加 podfile,这里简单添加Masonry


platform :ios, '8.0'

target 'StaticKit' do

    pod 'Masonry'

end

进行pod install命令之后我们可以看到pod给我们黄色的警告

image.png

主要是前面的错误:

[!] The Podfile contains framework or static library targets (StaticKit), for which the Podfile does not contain host targets (targets which embed the framework).
If this project is for doing framework development, you can ignore this message. Otherwise, add a target to the Podfile that embeds these frameworks to make this message go away (e.g. a test target).

这大概的意思是说当前的target为静态库,而且pod依赖的是当前这个静态库不是依赖host targetshost targets我的理解是可执行的target,当时我没注意这个警告以为是普通的警告,之后添加到壳工程的时候会提示该静态库的pod找不到

当然最后如果我们认真看提示的警告已经告诉了我们解决的办法了,最后一行的括号内(e.g. a test target)。这就是让我们创建一个测试的targetpod依赖它就可以让这个警告消失。这个很多网上文章都是一笔带过没说清楚的,不然就是不提静态库添加第三方依赖的问题,当然我的解释也不一定对。

静态库需要添加一个测试target让第三方依赖

添加测试target

点击+按钮进入选择target菜单

image.png

选中iOS Unit Testing Bundle 取名为 StaticKitTests

image.png

创建好之后是这样

image.png

修改podfile重新更新


platform :ios, '8.0'

project 'StaticKit'
#修改为测试的target
target 'StaticKitTests' do

    pod 'Masonry'

end

更新后的 pod信息,发现已经正常了

image.png

到这里如果你把Masonry 导入项目的类的时候会发现提示无法找到头文件,这时候我们要设置Heaser Search Paths 设置路径 添加 "$(SRCROOT)/Pods/Headers/Public"

image.png

添加资源文件:

添加资源文件我一般可以简单创建一个bundle放到工程目录下,使用时添加工程下就行了。这种方式很简单也是可以用的,但是这样的方式不容易管理我们的资源文件。在这里我推荐把资源文件也当作一个target添加到静态库组件中,过程和上面创建测试target差不多只是需要一些配置。

点击+好到创建target界面,tab页选中macOS下面的 Bundle,下一步 我取名为StaticKit_res按自己需要可以改名字

image.png

创建好之后是这样的

image.png

创建的时候你可以看到我们创建的是macOSbundle,至于为什么要用mac不用iOS很简单因为iOS没有这个选项,所以为了适配iOS 我们需要做下面两个配置

  1. 配置Base SDKiOS 配置路径看下图
image.png
  1. 一般我们图片有@2x @3x这样放在bundle会导致读取图片失败,所以我们要改下配置,把COMBINE_HIDPI_IMAGES设置为NO
image.png

读取资源文件:

我们的组件的资源文件基础配置已经好了,接下来要添加一个工具类来读取资源了,在这里我们以读取图片资源为例,其他的资源大同小异。

  1. 我们添加几张测试图片放到staticKit_res文件夹下,记得target的选择
image.png
  1. 创建我们的工具类名称为StaticKitHelper代码如下
@interface StaticKitHelper : NSObject


+ (NSBundle *)resBundle:(Class)classtype;
    
+ (UIImage*)imageName:(NSString*)name;
    
@end

#import "StaticKitHelper.h"

@implementation StaticKitHelper
    
    
+ (NSBundle *)resBundle:(Class)classtype {
    static NSBundle *framworkBundle = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        framworkBundle = [NSBundle bundleForClass:classtype];
        if (framworkBundle) {
            NSString *resourceBundlePath = [framworkBundle pathForResource:@"StaticKit_res" ofType:@"bundle"];
            if (resourceBundlePath && [[NSFileManager defaultManager] fileExistsAtPath:resourceBundlePath]) {
                framworkBundle = [NSBundle bundleWithPath:resourceBundlePath];
            }
        }
    });
    return framworkBundle;
}
    
+ (UIImage*)imageName:(NSString*)name {
    
    if (name.length == 0) {
        return nil;
    }
    NSBundle *bundle = [StaticKitHelper resBundle:[self class]];
    NSString *path = [bundle pathForResource:name ofType:@"png"];
    
    return [UIImage imageWithContentsOfFile:path];
}
@end

//调用
UIImage *image = [StaticKitHelper imageName:@"PlayButtonOverlayLarge"];

添加测试代码:

通过上面的设置我们的.a静态库组件基础配置已经好了,接下来我们要添加测试代码,我这里把默认的头文件普通的类改成一个控制器类,设置背景为蓝色,并添加了一张图片:

#import "StaticKit.h"
#import "StaticKitHelper.h"
#import <Masonry/Masonry.h>


@implementation StaticKit

    
- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"StaticKit控制器";
    
    
    UIImage *image = [StaticKitHelper imageName:@"PlayButtonOverlayLarge"];
    
    UIImageView *imageView = [UIImageView new];
    imageView.image = image;
    [self.view addSubview:imageView];
    [imageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view).offset(100);
        make.top.equalTo(self.view).offset(100);
        make.size.mas_equalTo(CGSizeMake(40, 40));
    }];
    
    self.view.backgroundColor = [UIColor blueColor];
}

    
@end

到这里StaticKit组件已经是一个合格的静态库组件了,它可以参与模块的开发了,最后总结下大概的步骤:

  1. 打开xcode创建Cocoa Touch Static Library设置组件名字
  2. 添加测试target,创建podfile设置依赖的target为测试StaticKitTests
  3. 添加资源文件target StaticKit_res 设置两个编译参数,导入测试图片
  4. 添加读取资源工具类,添加测试代码
  5. 编写的代码在自己的静态库组件内编译通过

添加壳工程调试:

  • 准备工作

所谓的壳工程就是我平常创建可以直接运行的工程,你可以随便创建一个带导航栏的控制器,用于push到我们的静态库组件供调试,这个步骤很简单就不废话了默认你已经创建好了壳工程。

  • 添加到壳工程
  1. 打开壳工程将StaticKit.xcodeproj拖到壳工程下
image.png
  1. 点击壳工程选中Build PhasesTarget Dependencies下点+号 添加StaticKitStaticKit_res
image.png
  1. 在同一个地方的Link Binary With Libraries添加StaticKit
image.png
  1. 在静态库中的Products文件夹下的StaticKit_res拖到Copy Bundle Resources
image.png
  1. 编译下如果显示成功就算大功告成了,如果有报错你可以回头看上面那个步骤做错了或者漏了。

这里解释下

第一步没什么好解释的。
第二步是我们把两个target当作子target依赖壳工程。
第三步表示代码执行我们链接的是StacKit这个target而不包含StaticKit_res
第四步是把我们静态库的资源文件添加到mainBundle里面这样我们才可以通过代码找得到它。

添加壳工程测试代码:

//第三方方式访问,这个头文件在我们创建的时候有说要设置才能访问
#import <StaticKit/StaticKit.h>

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"点击跳转到库";
}[图片上传中...(show.gif-f0b9fe-1530268184126-0)]



- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    StaticKit *sk = [[StaticKit alloc]init];
    [self.navigationController pushViewController:sk animated:YES];
}

@end

运行截图

show.gif

到这里自己手动创建.a静态库的全过程就完了,接下来会说.a静态库和.framework静态库配置,framework的创建和.a基本流程是一致的,某些配置有细微差别。

.framework静态库的差异

  1. framework的静态库创建的时候默认都是动态的,但是上架是不允许动态的所以我要在Build Settings里面的Mach-O Type设置为Static Library
image.png

2.framework设置的头文件不一样,framework创建的时候头文件都会默认显示在Project下我们需要把它拖到Public

image.png

3.最后一个不同点就是加人壳工程是frameworkKit.framework不需要加入到Target Dependencies

image.png

本文到这里就交代完手动创建静态库到调试的全部内容了,如果有写错的地方或者有什么问题你可以在本文下方评论,也希望大家都交流学习。下篇带大家编译静态库到远程私有库,敬请期待!

参考资料

https://www.raywenderlich.com/65964/create-a-framework-for-ios
https://github.com/jverkoey/iOS-Framework

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容