iOS制作framework以及引入到工程

转载 2016年08月30日 19:05:47

http://www.2cto.com/kf/201607/523967.html

Framework常识

苹果平台的链接库除了静态库 .a 和 动态库.dylib 之外,Mac OS/iOS 平台还可以使用 Framework。Framework 实际上是一种打包方式,将库的二进制文件,头文件和有关的资源文件打包到一起,方便管理和分发,这样 Xcode 能够很容易的将其集成到你的工程中去。

在 iOS 8 之前,iOS 平台不支持使用动态 Framework,开发者可以使用的 Framework 只有苹果自家的 UIKit.Framework,Foundation.Framework 等。这种限制可能是出于安全的考虑。换一个角度讲,因为 iOS 应用都是运行在沙盒当中,不同的程序之间不能共享代码,同时动态下载代码又是被苹果明令禁止的,没办法发挥出动态库的优势,实际上动态库也就没有存在的必要了。

由于上面提到的限制,开发者想要在 iOS 平台共享代码,唯一的选择就是打包成静态库 .a 文件,同时附上头文件(例如微信的SDK)。但是这样的打包方式不够方便,使用时也比较麻烦,大家还是希望共享代码都能能像 Framework 一样,直接扔到工程里就可以用。于是人们想出了各种奇技淫巧去让 Xcode Build 出 iOS 可以使用的 Framework,Framework 还有 “伪”(Fake) Framework 和 “真“(Real) Framework 的区别。

iOS 8/Xcode 6 推出之后,iOS 平台添加了动态库的支持。为什么 iOS 8 要添加动态库的支持?唯一的理由大概就是 Extension 的出现。Extension 和 App 是两个分开的可执行文件,同时需要共享代码,这种情况下动态库的支持就是必不可少的了。但是这种动态 Framework 和系统的 UIKit.Framework 还是有很大区别。系统的 Framework 不需要拷贝到目标程序中,我们自己做出来的 Framework 哪怕是动态的,最后也还是要拷贝到 App 中(App 和 Extension 的 Bundle 是共享的),因此苹果又把这种 Framework 称为 Embedded Framework。

系统会在需要的时候将framework载入内存中,多个应用程序可以同时使用同一个framework。这种方法可以使得你的代码易分享,在多个工程中复用,并且可以隐藏实现细节,控制公开的头文件。

苹果平台的静态库和动态库的概念与其他平台的概念不尽相同。

静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。

总结来说:其实就是加载时机和加载次数的不同。

framework分为真机—Debug(调试)版本、真机—Release(发布)版本、模拟器—Debug版本、模拟器—Release版本;开发中一般都打包Release(发布)版本,将真机和模拟器版本合并,提供外界。(注意:debug和release要和引入framework的工程对应

在项目开发的过程中,例如两个公司之间业务交流,不可能把源代码都发送给另一个公司,这时候将私密内容打包成framework,别人只能调用接口,而不能知道其中实现的细节。

制作framework

步骤

1,新建工程

这里写图片描述
选择左边那个framework,右边那个是创建.a静态库的。

2,创建接口代码

这里写图片描述
在工程中创建类,写一些开放给外部用的接口。
第一个类,做点简单的加法,需要公开的api就写在h里面

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<code class="hljs objectivec">//
//  Compute.h
//  FrameworkTest
//
//  Created by yxhe on 16/7/6.
//  Copyright ? 2016年 yxhe. All rights reserved.
//
 
#import <foundation foundation.h="">
 
@interface Compute : NSObject
- (NSInteger)addNumber:(NSInteger)a withNumber:(NSInteger)b;
@end</foundation></code>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<code class="hljs objectivec">//
//  Compute.m
//  FrameworkTest
//
//  Created by yxhe on 16/7/6.
//  Copyright ? 2016年 yxhe. All rights reserved.
//
 
#import "Compute.h"
 
@implementation Compute
- (NSInteger)addNumber:(NSInteger)a withNumber:(NSInteger)b
{
    return a + b;
}
@end
</code>

第二个类,打印

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code class="hljs objectivec">//
//  Print.h
//  FrameworkTest
//
//  Created by yxhe on 16/7/6.
//  Copyright ? 2016年 yxhe. All rights reserved.
//
 
#import <foundation foundation.h="">
 
@interface Print : NSObject
- (void)printWords:(NSString *)words;
@end
</foundation></code>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<code class="hljs objectivec">//
//  Print.m
//  FrameworkTest
//
//  Created by yxhe on 16/7/6.
//  Copyright ? 2016年 yxhe. All rights reserved.
//
 
#import "Print.h"
 
@implementation Print
- (void)printWords:(NSString *)words
{
    NSLog(@"%@", words);
}
@end
</code>

最后在自动生成的导出头文件里把这两个类的h都import进去

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<code class="hljs objectivec">//
//  FrameworkTest.h
//  FrameworkTest
//
//  Created by yxhe on 16/7/6.
//  Copyright ? 2016年 yxhe. All rights reserved.
//
 
#import <uikit uikit.h="">
 
//! Project version number for FrameworkTest.
FOUNDATION_EXPORT double FrameworkTestVersionNumber;
 
//! Project version string for FrameworkTest.
FOUNDATION_EXPORT const unsigned char FrameworkTestVersionString[];
 
// In this header, you should import all the public headers of your framework using statements like #import <frameworktest publicheader.h="">
#import <frameworktest compute.h="">
#import <frameworktest print.h="">
 
</frameworktest></frameworktest></frameworktest></uikit></code>

3,修改buildsettings

这里写图片描述

这里写图片描述
选择TARGETS里面

Linking下面:Dead Code Stripping选No,Mach-O Type选择static或者dynamic都行(在后面有点区分) Architectures下增加armv7s,并选中。将Build Active Architecture Only 设置为NO

4,设置Headers

这里写图片描述
把需要公开调用的头文件一道public里面,需要隐藏的放在private里面。

5,打包framework

选择一个模拟器,编译工程(command + B) 选择一个真机或者Generic Device(建议),编译工程(command + B) 在Finder中找到.framework文件

生成成功后工程目录里的product从红色变成了正常颜色。
这里写图片描述
会看到分成了 模拟器和真机两个文件夹,此时就可以把这两个.framework分别引入到对应的模拟器或者真机项目使用了。

6,合并framework

通过终端命令将两个framework合为一个模拟器和真机都可使用的framework。

打开控制台输入

?
1
<code class="hljs sql">lipo -create iphoneos下frameworkTest的路径 simulator下frameworkTest的路径 -output 新的路径,这样就完成了模拟器和真机版本的合并,新路径下的frameworkTest就是你合并后的文件,将这个文件名字改成和你未合并之前的Test一样的名字,放到framework文件夹下,替换掉原来的frameworkTest文件。</code>

例如我的

?
1
<code class="hljs lasso">lipo -create /Users/yxhe/Library/Developer/Xcode/DerivedData/FrameworkTest-gajdcpnghsabghalspugjmolohhd/Build/Products/Debug-iphoneos/FrameworkTest.framework/FrameworkTest /Users/yxhe/Library/Developer/Xcode/DerivedData/FrameworkTest-gajdcpnghsabghalspugjmolohhd/Build/Products/Debug-iphonesimulator/FrameworkTest.framework/FrameworkTest -output /Users/yxhe/Library/Developer/Xcode/DerivedData/FrameworkTest-gajdcpnghsabghalspugjmolohhd/Build/Products/FrameworkTest</code>

在目标文件夹里找到那个FrameworkTest文件,拖到真机.framework文件夹里替换掉原来的,这样,真机.framework就可以当做universal的framework使用了。

tips

合并还有另外一种方法,没试成功,是创建Aggregate跑脚本,不会写T_T 带有图片资源的需要把图片打包成Bundle文件,和framework一起拷贝到相应的项目中。 公开的类中如果引用的private的类,打包以后对外会报错,找不到那个private的类,可以把那个private的.h放到private里面

使用framework

引用系统framework

1)选中项目名称
2)选中TARGETS
3)选中Build Phases
4)在Link Binary With Libraries中添加。
5)点击“+”号,加入所需的系统提供的.framework文件
6)引入头文件,就行了

引用第三方framework

步骤

这里主要使用之前创建的framework测试
1)从Finder里面直接将.framework文件直接拖到工程目录中
这里写图片描述
2)在Link Binary With Libraries中添加framework
这里写图片描述
其实一般拖进去之后,这个项系统自动添加了
注意:如果是Dynamic Libray形式的framework,需要添加到Embedded Frameworks
3)在项目中引入头文件即可

测试结果

目录结构
这里写图片描述
代码的写法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<code class="hljs objectivec">//
//  ViewController.m
//  FrameWorkUseTest
//
//  Created by yxhe on 16/7/6.
//  Copyright ? 2016年 yxhe. All rights reserved.
//
 
#import "ViewController.h"
// 引入framework的头文件
#import <frameworktest compute.h="">
#import <frameworktest print.h="">
 
@interface ViewController ()
 
@end
 
@implementation ViewController
 
- (IBAction)onClick:(id)sender
{
    Compute *compute = [[Compute alloc] init];
    NSInteger sum = [compute addNumber:7 withNumber:5];
    Print *print = [[Print alloc] init];
    [print printWords:[NSString stringWithFormat:@"7 + 5 = %ld", (long)sum]];
    _numberLabel.text = [NSString stringWithFormat:@"7 + 5 = %ld", (long)sum];
}
 
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
 
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
 
@end
</frameworktest></frameworktest></code>

在模拟器和iphone6s真机上都成测试成功
这里写图片描述

源代码

csdn:diy的framwork
github:diy的framwork


相关文章推荐

ios中如何制作framewframework 以及用处

前言       如果你想将你开发的控件与别人分享,一种方法是直接提供源代码文件。然而,这种方法并不是很优雅。它会暴露所有的实现细节,而这些实现你可能并不想开源出来。此外,开发者也可能并不想看到你的所...

ios开发:Xcode8制作framework及使用

网上关于Framework制作的教程数不胜数,然而都过于陈旧,最新的也是使用Xcode7的教程,而且有些设置也只给出步骤,并没有给出原因,而且按照有些教程制作出的framework还有些问题,所以我把...

IOS制作framework动态SDK库

制作动态库工程主要要提取原工程的几部分文件: 1.图片等资源文件; 2.核心类文件,包括第三方插件类文件和自定义类文件; 3.预编译头文件; 4.导入和原工程一样的用到的系统库; 一....

Xcode8.0 制作.framework

最近公司要整理框架,想制作成静态库.framework,自己在也网上看了相关的资讯,在这里记录下自己操作步骤,自己没有做过多版本的测试,如果大家在制作和使用过程中遇到了其他的问题,希望可以留言一起讨论...

iOS - 制作 Framework

http://www.2cto.com/kf/201607/523967.html Framework常识 苹果平台的链接库除了静态库 .a 和 动态库.dylib 之外,Mac OS...

IOS开发中制作属于自己的静态库.a、资源库.bundle、.framework

一、.a静态库文件 1、点击创建Project 2、在.m和.h中进行代码编写 3、根据armv7和arm64打包两个.a进行合并 合并两个.a文件 lips -create /Users/t...

ios开发:Xcode8制作framework及使用

前言 网上关于Framework制作的教程数不胜数,然而都过于陈旧,最新的也是使用Xcode7的教程,而且有些设置也只给出步骤,并没有给出原因,而且按照有些教程制作出的framework还有些问...

ios 制作使用FrameWork

http://www.jianshu.com/p/ef3d5b7e7006  http://www.knowsky.com/884469.html  http://www.jianshu.com/...

iOS framework制作 带你走出那些坑

iOS framework制作 Xcode8,带你走出那些坑
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)