iOS制作framework以及引入到工程

http://www.jianshu.com/p/ef3d5b7e7006
http://www.knowsky.com/884469.html
http://www.jianshu.com/p/6c033c39884a
http://my.oschina.net/u/856930/blog/196484
http://ios.jobbole.com/81583/
https://segmentfault.com/q/1010000002952316
网上有很多解释和写法,这里根据自己的实测做一下综合

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里面

//
//  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
//
//  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

第二个类,打印

//
//  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
//
//  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

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

//
//  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>

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。

打开控制台输入

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

例如我的

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

在目标文件夹里找到那个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)在项目中引入头文件即可

测试结果

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

//
//  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

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

源代码

csdn:diy的framwork
github:diy的framwork

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值