今天我们来看看制作framework---dynamic和static这两中库需要注意的
1 基本的framework配置
配置(如下图)选择dynamic library
2 代码与文件
我们使用xib方式创建了tableView和cell以及一个viewcontroller
3 需要暴漏给外部使用h文件
好了基本的工程已经出来了,现在我们来看看怎么玩这两种形式的framework
1 dynamic library
我们先将库编译一下
我们此时可以将framework拖到工程中使用啦,但是xib对应的此时是无法加载的。为什么?
对于此时的动态库来说,是在需要是动态载入的
对于这个库其实我们可以选择为Option形式,这样的话App启动时它是不会载入的,只有当使用到时才会动态的检测载入(这也是为啥称之为动态库啦),也正是因为此,我们的main bundle中不包含xib编译后的nib文件,也就造成我们加载是产生资源无法找到的crash
怎么验证我们的说法呢?
Xcode中Products找到编译后的App,右键finder找到对应的app文件显示包内容即可
此时里面并没有对应的dynamic Libray(也就是我们动态库)
好了,说了这么多我们怎么来加载呢?
其实这些资源文件都是在我们的动态库中,我们需要从动态库中去加载他们
那么怎么来获取动态库,那当然是动态获取啦
//自定义framework Mach-O Type 为 dynamic 的时候bundle可以采用这两个加载
NSBundle * dyBundle = [NSBundle bundleWithIdentifier:@"xsk.EmbededFramework"];
NSBundle * bundle = [NSBundle bundleForClass:EmViewController.class];
UIViewController *vc = [[EmViewController alloc] initWithNibName:@"EmViewController" bundle:dyBundle];
UIImage * image = [UIImage imageWithContentsOfFile:[dyBundle pathForResource:@"test" ofType:@"png"]];
[self.tableView registerNib:[UINib nibWithNibName:@"TableViewCell" bundle:bundle
] forCellReuseIdentifier:@"TableViewCell"];
通过class来动态查询出关联的bundle 或者 通过 framework的identifier
下面是官方的解释
Returns the NSBundle
instance that has the specified bundle identifier.
Returns the NSBundle
object with which the specified class is associated.
好了,动态库基本就这些,下面就是静态库啦
2 static library
配置大致与上面类似只是Mac-O Type 选择了static library
首先我们要说一下静态库的加载,它会在App启动是伴随着加载,
其次 太会被放置到App的包中也就是我们ipa文件的Payload里面
我们主要说不同点:
1 图片 plist等资源加载
我们可以将这些依赖的资源文件制作为bundle(简单制作就是创建个文件夹,把文件放进去,然后为修改文件夹为xx.bundle即可), 在导入我们的静态库是也将另外制作的bundle文件导入工程即可
UIImage *staticImage = [UIImage imageNamed:@"res.bundle/test.png"];
因为此时它是游离于静态库之外,在main bundle中的我们可以采用传统的从main bundle加载资源的方式按照名称加载(此时多了个壳,因为bundle采用路径方式查询资源,我们就按照路径拼接上资源所在的bungle即可)
2 xib加载
对于xib这个资源比较特殊,虽然是静态库但是依然被编译成为了nib文件存放在framework中
同样App默认也是从Payload这个里去按照名称搜索,不过此时想要拿到对应的nib则需要先进入framework然后才是对应资源名称,因此可以我们就需要加载个库名称啦
也就是:库名称.framework/xxxx.nib才是bundle能够搜索到的资源
UIViewController *vc = [[EmViewController alloc] initWithNibName:@"EmbededFramework.framework/EmViewController" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:[UINib nibWithNibName:@"EmbededFramework.framework/TableViewCell" bundle:nil
] forCellReuseIdentifier:@"TableViewCell"];
那么可能你会有疑问为啥此时的EmViewController加载xib需要initWithNibName而我们的主工程不需要呢?
其实啊,这个里面有个隐含问题:默认情况会搜素main bundle中医ViewController同名的xib,而我们的库需要加前缀才能定位,因此要手动使用加载nib的方式创建我们的Controller
此时运行的话我们的例子会报错需要进行下面的配置
将Link Binary With Library 中引入 ===》 目的是在头文件中可以导入查找文件声明
Copy Bundle Resources
将静态库与resource对应的bundle导入项目 ====》目的是将我的库导入可在main bundle中可查找