IOS SDK开发详解(.framework、.a、Bundle资源文件创建、SDK中使用其他SDK等)

什么是SDK?

软件开发工具包(缩写:SDK,英语全称:Software Development Kit),一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。
在OC的开发中,我们涉及到的一般是静态库(.a)或者动态库(.framework)。(注:不是所有的.framework就一定是动态库)

静态库与动态库的区别?

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

a与.framework有什么区别?

.a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。 .a文件不能直接使用,至少要有.h文件配合(微信的SDK就是这种形式),.framework文件可以直接使用。 .a + .h + sourceFile = .framework。 建议用.framework。再者 静态方式开发,一直是iOS SDK开发的主流方式。

静态库.framework开发:

  1. 新建SDK .framework项目:
    • File -> New -> Project -> IOS -> Framework & Library -> Framework
      新建.framework SDK
    • 填写SKD名:
      填写SKD名
    • 选择SDK保存位置。
  2. 设置配置:
    • TARGETS -> General -> Deployment Info,设置支持iOS系统的最低版本和支持的设备。
      支持版本及设备
    • TARGETS -> Build Settings -> Linking -> Mach-O Type 更改为Static Library(静态库),默认为Dynamic Library(动态库)。
      更改为静态库
    • TARGETS -> Build Settings -> Linking -> Other Linker Flage 添加-Objc标志(在静态库中慎用Category,如果使用了Category就必须在SDK和SDK使用的项目中都要添加该标识,否则会报unrecognized selector sent to instance的异常
      Category 必填
    • TARGETS -> Build Settings -> Architectures 添加armv7s(Xcode6之后,默认不支持armv7s,如果需要添加SDK的工程是支持armv7s,那将会有冲突)
      支持armv7s
    • TARGETS -> Build Settings -> Build Options -> Link With Standard Libraries 设置为No,默认为YES。
  3. 添加要制作成SDK的代码。
  4. 配置公开文件:
    • TARGETS -> Build Phases -> Headers
      公开文件
  5. 在SDK的.h头文件中引用公开的文件:
//#import <SDK名字/公开文件名字.h>
#import <ETCOnlineServices/WebViewController.h>
  1. SDK.framework打包:
    模拟器 iPhone5s 以下是 i386 架构,iPhone5s 及以上是 x86_64 架构。如果想同时支持 i386 和 x86_64,设置:TARGETS -> Build Settings —> Architectures —> Build Active Architecture Only —> NO。
    真机iPhone5s 以下是 armv7 架构,iPhone5s 及以上是 arm64 架构。
    • Product -> Scheme -> Edit Scheme -> Run -> Build Configuration修改为release
      Build Configuration.png
    • 生成模拟器和真机使用的framework包:
      1. 真机包:模拟器选项中,选择Generic IOS Device, Command + B生成真机包。
      2. 模拟器包:模拟器选项中,选择任意模拟器, Command + B生成模拟器包。
      3. 查看真机包和模拟器包的位置:项目中的Product文件夹中选择SDK文件,右击选择Show in Finder
查看SDK
真机和模拟器包

- 通过终端命令行查看包是真机包还是模拟器包:lipo -info framework路径
SDK路径
lipo -info

终端输出为:armv7 arm64 是真机架构;i386 x86_64 是模拟器架构。

  1. 合并framework的真机包和模拟器包:
    • 通过终端命令行合并:lipo -create 真机路径 模拟器路径 -output 真机路径
      合并
    • 通过脚本语言合并:
      1. TARGETS -> Build Phases 点击加号创建Run Script
        Run Script
      2. Run Script中添加脚本运行代码:
        Run Script

        command + B 分别生成真机和模拟器包,再次按command + B合并真机包和模拟器包。脚本代码如下:

if [ "${ACTION}" = "build" ]
then
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}.framework
DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework
SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
#ditto "${DEVICE_DIR}/Headers" "${INSTALL_DIR}/Headers"
lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}"
#open "${DEVICE_DIR}"
open "${SRCROOT}/Products"
fi
  • lipo -info查看合并后的包支持的架构:
    合并后

静态库.a开发:

  1. 新建SDK .a项目:
    • File -> New -> Project -> IOS -> Framework & Library -> Static Library
      image
    • 填写SDK名:
      image
    • 选择SDK保存位置。
    • SDK中会生成.h和.m文件,.m文件可以直接删除。
    • SDK所支持的最低版本:PROJECT -> info -> Deployment Target
支持的最低版本
  1. 添加需要生成SDK的代码。
  2. 在SDK的.h头文件中引用公开调用的头文件:
//#import "公开文件名.h"
#import "WebViewController.h"
  1. Targets -> Build Settings -> Copy Files 添加公开的.h文件。并且清空Subpath中的路径,如果不清空,.a文件和.h文件不在同一个文件夹中。
    公开文件.h
  2. SDK.a打包:
    • Product -> Scheme -> Edit Scheme -> Run -> Build Configuration修改为release
      Edit Scheme
    • 生成模拟器和真机使用的framework包:
      1. 真机包:模拟器选项中,选择Generic IOS Device, Command + B生成真机包。
      2. 模拟器包:模拟器选项中,选择任意模拟器, Command + B生成模拟器包。
      3. 查看真机包和模拟器包的位置:项目中的Product文件夹中选择SDK文件,右击选择Show in Finder
真机和模拟器包

- 通过终端命令行查看包是真机包还是模拟器包:lipo -info SDK.a路径
.a的路径
终端

终端输出为:arm64 是真机架构;x86_64 是模拟器架构。

  1. 合并framework的真机包和模拟器包:
    • 通过终端命令行合并:lipo -create 真机路径 模拟器路径 -output 真机路径
      合并

Bundle资源文件创建:

手动创建Bundle资源:

  1. 创建一个文件夹,把这个文件夹的后缀改成.bundle
    image
  2. 右击该文件 -> 显示包内容:
    image
  3. 把资源文件直接copy到该文件中:
    image
  4. Bundle加入SDK中:
    添加Bundle
  5. 从Bundle资源文件中读取内容:
  • Html本地文件的读取:
NSString *htmlFilePath = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:@"Bundle名.bundle/transpay/index.html"];
NSURL * htmlFileURL = [NSURL URLWithString:htmlFilePath];
NSURLRequest * request = [NSURLRequest requestWithURL:htmlFileURL];
[self.webView loadRequest:request];
  • 图片/视频资源的读取:
NSString *imageFilePath = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:@"Bundle名.bundle/image/xingkong.png"];
imageView.image = [UIImage imageWithContentsOfFile:imageFilePath];
  • Storyboard、xib,需要在对应的视图控制器中添加以下代码:
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    NSBundle *bundle = [NSBundle bundleWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"Bundle名.bundle"]];
    if (bundle) {
        // 如果是storyboard
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"你的storyboard名称(例如Main)" bundle:bundle];
        self = [storyboard instantiateViewControllerWithIdentifier:@"你在storyboard中设置的此视图控制器的id"];
        return self;

        // 如果是xib
        self = [super initWithNibName:@"当前控制器的名称" bundle:bundle];
        return self;
    }
    return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}
  1. 把生成的SDK文件和Bundle资源文件放在同一个文件夹中:
    image.png

    Bundle文件创建和使用完成。

创建的SDK中使用其他的SDK

  1. 往SDK中拖入另一个SDK:
    添加SDK
  2. 在合适的地方,添加这个引入的SDK的相关代码。

Bundle 和 其他的SDK都要和创建的SDK放在同一个文件夹,然后拖入要使用的项目中,如果该项目中的SDK和创建的SDK中的引用的SDK重复,那么就只要保持存在一个就好了。

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