关于ios:iOS封装framework

4次阅读

共计 5548 个字符,预计需要花费 14 分钟才能阅读完成。

文章写于 2016/04/08,搬家到此处

第一篇 iOS 封装 Framework

如果咱们心愿与他人共享某些函数,却又不违心裸露实现的细节,怎么办呢?
这时候能够将咱们的代码封装成 framework,对外提供接口而不裸露实现;
不仅如此,将代码整合成 framework 还有很多其余的益处,这里就不一一列举。

上面就来看看如何打包成 framework 吧。

1、创立工程


通过 OS X > Framework&Library > Bundle 创立工程:

2、增加 Headers


在 Build Phases 中增加 Headers:

Headers 开展后是这样的:

3、增加我的项目代码


将须要封装打包的文件退出我的项目中,这里最好用 copy 的形式退出:

4、合并头文件


为了不便他人应用 framework,最好创立一个头文件, 并且在头文件下蕴含你所有想要公开的类,如此,当他人应用你的 framework 时只须要导入这一个头文件就能够了。

5、公开类


当代码退出了我的项目后,所有的 .h 文件都会主动呈现在 Headers 的 Project 上面,而后,咱们将须要公开的类拖到 Public 上面。

这里须要留神:Private 依然是公开的而不是公有的,不要被它的名字误导了,公有类保留在 Project 下就好。

6、更改一些设置:


6.1 info.plist > Bundle OS Type code = FMWK

6.2 Build Settings > Base SDK = Latest iOS,抉择最新的

6.3 Build Settings > Linking :

  • Dead Code Stripping = NO;
  • Link With Standard Libraries = NO;
  • Mach-O Type = Static Library.

对于 Mach-O Type 可能有两种状况:(1)抉择 Static Library 打进去的是动态库;(2)抉择 Relocatable Object File 打进去是动静库。

这里倡议应用动态库,动静库在提交 AppStore 审核的时候貌似会被拒;然而网上看了一些材料说动静库也是能够的,不过会有一些机审的规定须要留神下,比方不要把 x86/i386 的包和 arm 架构的包 lipo 在一起,就单纯应用真机包。(对于这个没有测试过,也不晓得是不是真的,如果有敌人测试过的心愿告知下,谢谢!)

6.4 Build Settings > Packaging > Wrapper Extension = framework.

7、批改输入门路


7.1 为了不便找到运行后生成的 framework,咱们提前在我的项目目录下创立一个目录 build,用来寄存运行后生成的文件;

7.2 而后,须要批改下输入门路:

Build Settings > Per-configuration Build Products Path = $(SRCROOT)/build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

8、编译


8.1 抉择 Generic iOS Device, 编译;

8.2 抉择模拟器,编译。

8.3 编译胜利后,会在 build 下产生 2 个文件夹,一个是 device 编译生成的,一个是 simulator 编译生成的,他们外面寄存着对应的 framework。

9、合并


此时,曾经有了实用于设施和模拟器的 2 个 framework,接下来,须要将他们合并,使其同时实用于设施与模拟器。

9.1 这里合并的并不是 2 个 framework,而是各自的二进制文件,如下图中的 JJFramework;

9.2 那么如何合并呢?首先,关上终端,cd 到 build 文件夹;而后输出命令:

lipo -create 设施二进制文件 模拟器二进制文件 -output 合成文件的名字 ;

留神:(1)留神空格。(2)合成后的文件名字须要和合成前的名字一样,否则应用 framework 时会报错。

如上图,合并 2 个 JJFramework 输出如下命令:

lipo -create Debug-iphoneos/JJFramework.framework/JJFramework Debug-iphonesimulator/JJFramework.framework/JJFramework -output JJFramework。

build 文件夹下的 JJFramework 就是合成后的二进制文件了。

9.3 将设施或模拟器运行生成的 framework 移出来,用合成的二进制文件替换本来二进制文件:

10、删除 info.plist


到这里就基本上功败垂成了。
另外,如果 framework 中没有用到过 info.plist,能够将其删除免得发生冲突。(我就遇到过一次这坑爹的状况)

OK, framework 打包实现。

其实封装 framework 有很多种办法,以上只是其中一种;而且应该还有更简略的办法,有工夫的话,后续会补上。

第二篇 应用 bundle 治理资源

上一篇通过 Bundle 创立 framework,这一篇间接通过 iOS 的 Framework 来实现,更加简略。

本篇应用的 Xcode 版本为 7.2.1。

一、首先,iOS -> Framework&Library -> Cocoa Touch Framework 创立工程。

工程的名字要与你所冀望的 SDK 名字一样。这里以 ExpeSDK 作为我的项目名。

二、工程创立实现后,删除自带的 ExpeSDK.h 和 ExpeSDKTests.m 文件,因为用不到的,移到废纸篓。

三、在 Build Settings 中更改一些配置

3.1 Architectures 默认是 armv7 和 arm64。能够减少 armv7s 架构,次要是为了兼容 5C,如果不思考 5C 的话,能够疏忽这一步。

3.2 更改输入门路:在我的项目根目录下创立一个 build 目录,更改如下配置,输入文件就会在 build 文件下,这一步只是为了不便找到输入文件而已。

Per-configuration Build Products Path > $(SRCROOT)/build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

3.3 举荐如下设置:

Mach-O Type > Static Library;(动态库,如果须要提审 Appstore 的话不容许应用动静库的)

Dead Code Stripping > NO;(是否打消有效代码)

Link With Standard Libraries 默认是 YES,如果没有特殊要求的话,默认就能够。

​ 设为 NO 也是能够打包的,然而应用 framework 时要配置 Other Linker Flags。

Enable Bitcode > NO;(反对旧库)

四、将须要共享的文件 copy 到工程。这里 copy 过去的文件是 config.h 和 config.m;

五、Build Phases -> Headers :

将须要共享的头文件拖入 Public, 公有的保留在 Project。

六、编译

模拟器编译:

Device 编译:

七、合并二进制文件

编译胜利后,在 build 目录下会生成模拟器和设施的 framework, 合并他们的二进制文件,使 framework 可能在设施和模拟器上通用;

device 的 framework:

simulator 的 framework:

7.1 关上终端,cd 到 build 目录:

cd build 文件门路

7.2 输出合成命令:(lipo -create 设施二进制文件 模拟器二进制文件 -output 合成文件的名字)

lipo -create Debug-iphoneos/ExpeSDK.framework/ExpeSDK Debug-iphonesimulator/ExpeSDK.framework/ExpeSDK -output ExpeSDK

合成结束后,build 目录下会生成一个新的二进制文件:

7.3 替换二进制文件

而后将新的二进制文件替换掉 device framework 中的二进制文件。

移出 framework。

OK,framework 制作实现!


很多时候,咱们须要用到图片,xib 等等这些资源,就须要 bundle 来治理。

创立 Bundle 最简略的办法:新建一个文件,命名为 xxx.bundle 就 OK 了。

此处,我新建一个 tuxiang.bundle,而后右击显示包内容,放入 2 张图片 tx_1.jpg 和 tx_2.png。

1、新建一个 app 工程 showApp

2、将下面的 ExpeSDK.framework 和 tuxiang.bundle 退出到我的项目中,如此,当程序运行时,xcode 会主动将 tuxiang.bundle 拷贝到 app mainBundle.

在 ExpeSDK.framework 的 config.m 中我曾经写好了获取 tuxiang.bundle 中图片的办法,代码如下:

- (UIView*)configUI
{UIImage * image = [config getPNGImage:@"tx_2"];
    UIImageView * imgView = [[UIImageView alloc] initWithImage:image];
    imgView.frame = CGRectMake(0, 20, 375, 600);
    return imgView;
}
+ (UIImage*)getPNGImage:(NSString*)_image_name
{NSBundle * txBundle = [self getBundle:@"tuxiang"];
    NSString * imgPath = [txBundle pathForResource:_image_name ofType:@"png"];
    return [UIImage imageWithContentsOfFile:imgPath];
}
+ (UIImage*)getJPGImage:(NSString*)_image_name
{NSBundle * bundle = [self getBundle:@"tuxiang"];
    NSString * imgPath = [bundle pathForResource:_image_name ofType:@"jpg"];
    return [UIImage imageWithContentsOfFile:imgPath];
}

+ (NSBundle*)getBundle:(NSString*)_bundle_name
{NSLog(@"mainBundle resourcePath = %@",[NSBundle mainBundle].resourcePath);
    
    /* 从 mainBundle 获取 tuxiang.bundle */
    // 办法 1
    //    NSString * component = [NSString stringWithFormat:@"%@.bundle",_bundle_name];
    //    NSString * bundlePath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:component];
    
    // 办法 2
    NSString * bundlePath = [[NSBundle mainBundle] pathForResource:_bundle_name ofType:@"bundle"];
    
    NSBundle * bundle = [NSBundle bundleWithPath:bundlePath];
    return bundle;
}

在 config.h 文件中提供对外的办法:

- (UIView*)configUI;

3、在 showApp 中调用 configUI:

先导入头文件

#import "ExpeSDK/config.h"

而后在 viewDidLoad 中调用函数

- (void)viewDidLoad 
{[super viewDidLoad];
    
    config * ObjCon = [[config alloc] init];
    [self.view addSubview:[ObjCon configUI]];
}

4、运行:

确实是预期的成果。

第三篇 在工程中间接制作 framework

如果咱们写了一个工程,能够间接在工程中制作 framework.

1、建设工程, 工程名 showLog

2、在 showLog 中新建一个类 LogMessage,在这里写一个函数,最终的目标是打包成 framework 共享这个函数办法;

LogMessage.h

@interface LogMessage : NSObject
+ (void)logInfo; // 共享的办法
@end

LogMessage.m

@implementation LogMessage
+ (void)logInfo
{NSLog(@"log info success!");
}
@end

3、接下来,在我的项目中建设 framework

会看到新建工程的界面,抉择 Cocoa Touch Framework。这里起名叫 LogSDK.

新的 target 建好当前,能够看到工程中多了 1、2 块文件,删除原生的 .h 与 .m 文件:

4、抉择新的 target: LogSDK,General > Deployment Info > Deployment Target 抉择最低;

依照下图批改配置:

5、定位到 LogSDK > Build Phases,将 .m 文件拖到 Compile Sources, 将须要公开的 .h 文件拖到 Headers > Pulic, 须要公有的拖到 Headers > Project:

6、更改输入门路:

在我的项目文件下新建 build 目录

LogSDK > Build Settings > Build Locations :

更改上图中的配置如下:

$(SRCROOT)/build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

7、编译:

须要先选定到 LogSDK:

而后别离进行模拟器和 Device 的编译;

8、编译胜利后,依照上一篇的第 7 步合并。

正文完
 0