iOS SDK开发中的情形

说在SDK开发之前的话:

iOS SDK开发就是为某一个应用场景、或领域、或需求,提供一个已实现的、封装好的、可供直接使用的模块。

其主要由两部分组成:用来为类型或常量声明的头文件列表、具体实现的二进制文件。

所以SDK开发中的主要问题点集中在:

1. 头文件是否能被使用的工程索引到

2. 二进制文件是否能被使用的工程搜索到

本篇文章不写制作SDK的具体步骤,仅仅讨论制作SDK时的一些情形。

下面进入正题:

SDK开发中关于头文件设置:

        凡是提供给外界使用的类、结构体、枚举、常量等,定义它们的头文件必须要在工程的Build Phases->Headers->public下面。并且这些头文件都需要包含在与SDK工程同名的头文件中(这条不是必须,只是这么做会显得更加规范。别人使用SDK的时候,只需要引入SDK同名的头文件即可)

设置库文件生成动态的还是静态的:

        Project Name->Target Name->Build Settings->搜索框搜“Mach”->修改“Mach-O Type”为动态或静态,则相应可生成动态或静态的库文件。

先解释说明以下图片中出现的工程名字:

SDKDemo:制作的向外提供的SDK库文件(与SDK工程名同名)

SDKApp:引用SDK库文件(本文指的是SDKDemo)的App工程

SDKStatic:新建工程时,选择iOS->Framework & Library->Cocoa Touch Static Library. 用来生成.a文件的工程

SDKFramework:  是个Framework库文件(可能是动态的,也可能是静态的),用于模拟被SDK依赖的.framework文件

下面分几种情况来讨论SDK开发的注意事项:

一、SDK中只有源码文件

1. 生成动态SDK库文件。

创建工程的时候,根据默认配置编译是生成动态库的。

App工程中引入动态库的时候,需要在

App工程:Project Name->Target Name->General->Embedded Binaries下添加引入的动态库。否则运行时会报如下类型错误:

App中找不到动态库时报错信息

嵌入动态库编译后,生成的App文件中会多一个Frameworks目录(可右键.App文件查看包内容),里面全是Embedded Binaries下添加的动态库

2. 打包为静态库

SDK工程:Project Name->Target Name->Build Settings->搜索框搜“Mach”->修改“Mach-O Type”为静态库

App工程引入静态库很简单,直接引入就行,不需要额外配置:

tips:

合并真机与模拟器版本时的命令格式为:

lipo -create 模拟器版本的路径 真机版本的路径 -output 合并后的版本存放路径

1. 合并时lipo -create接收的模拟器版本和真机版本两个参数的前后顺序没有关系,合并后的版本通过命令查看架构信息显示结果是完全一致的。模拟器架构信息显示在前,真机架构信息在后。

2. 合并后的版本无论替换真机版本的Framework中的目标文件还是模拟器版本的Framework中的目标文件,App工程中引入被替换的Framework后在真机和模拟器上都能跑起来

二、SDK包含并依赖于.a文件

首先创建SDKStatic工程,生成一个.a文件。

该工程只是简单继承了UIButton,并重写了initWithFrame方法。为每一个MyButton对象默认生成标题和背景色:

头文件声明MyButton继承UIButton
实现文件默认生成的MyButton对象是带标题和背景色的

生成的.a文件如下,可以看到里面包含了MyButton.o文件:

生成的.a文件的一些信息

在SDK工程中引入.a文件。下面分两种情况来看生成的SDK库文件:

1. SDK库文件做成动态库(设置方法看开头部分)

.a文件内容被整合进了SDK动态库文件中,引入App工程中时,只需要引入SDK动态库就可以了

2. SDK库文件做成静态库(设置方法看开头部分)

包中的信息:

.a文件内容同样被整合进了SDK静态库文件中,这个更好理解。引入App工程中时,只需要引入SDK静态库就可以了

总结下:

    制作SDK库时,如果有依赖的.a文件,则最终生成的SDK库文件会合并.a文件的内容,而不论SDK库文件是动态还是静态的。

三、SDK包含并依赖于.framework文件(实际开发中应该不会出现这种情况,这里纯粹看看结果)

下面的SDKFramework是个Framework库文件(可能是动态的,也可能是静态的)

SDKFramework工程添加的内容和SDKStatic工程是一样的。也是自定义MyButton,默认生成标题和背景色(拷贝文件到工程):

头文件声明MyButton继承UIButton
实现文件默认生成的MyButton对象是带标题和背景色的

SDKDemo工程自定义了MyView,默认生成的MyView对象添加了一个MyButton按钮和背景色:

头文件声明
实现文件添加MyButton按钮和背景色

1. 如果.framework文件是动态库

.framework文件是动态库

a. SDK打包为静态库,如下:

SDK打包为静态库

静态SDK包和动态SDKFramework.framework文件是彼此独立的。引入静态SDK包时,必须也导入SDKFramework.framework,否则编译不过,因为静态包有引入动态库中的符号。

b. SDK打包为动态库,如下:

SDK打包为动态库

两者还是彼此独立的。动态SDK包中会记录依赖的动态.framework rpath,App运行时,dyld会根据这个信息去加载对应的.framework依赖文件。如果找不到App将会在启动时奔溃...

2. 如果.framework文件是静态库

a. 首先SDK打包为动态库看看:

经实践,依赖的静态库会被整合进动态SDK包自身中。App中引入时,只需要导入SDK包就可以。我们在SDKApp中导入SDKDemo,运行可以看到如下效果:

b. 再看看SDK打包为静态库:

根据上面截图中信息,App中导入SDK包时,也必须导入依赖的.framework了。否则编译时将会出现如下图所示找不到符号的错误:

追加导入依赖的.framework,再次编译运行。OK!!!

总结:

1. 依赖的.framework为动态库

    制作的SDK库文件不论动态还是静态的。和依赖的.framework文件本身是彼此独立的,不会发生符号整合的现象

2. 依赖的.framework为静态库

    如果制作的SDK库文件是动态的,则依赖的.framework静态库内容会被整合进SDK库文件中

    如果制作的SDK库文件是静态的,则彼此是独立的

四、SDK中引入Pods管理第三方库

这里又得分几种情况讨论:

1. Podfile中不使用use_frameworks!  pods库生成的是.a文件

a. 如果SDK制作成静态库:

      SDK静态库不会整合Pods里三方库中的符号,最终导入App工程时,需要SDK静态库、Pods中的三方库文件一起导入

b. 如果SDK制作成动态库:

      Pods库中的符号会被合并整合进入SDK库中,导入工程时,只需要导入SDK包就OK了

2. Podfile中使用use_frameworks!  pods库生成的是.framework文件。其中Pods_工程名.framework文件是个静态库,管理的第三方库生成的是framework动态库

a.如果SDK制作成动态库:

    SDK中会包含引入三方库的rpath,App中引入SDK包时,也必须引入三方库,否则dyld加载不了指定库导致App启动时奔溃

b. 如果SDK制作成静态库:

    静态SDK中会忽略Pods中的库中定义的符号(也即彼此是独立的)。如果静态SDK中引用了动态pods库中定义的符号,只要在App工程中也导入pods中动态库,并在embeded binaries中添加。一样是可以编译运行的。

写在最后的话:

    其实怎么编译,SDK工程中是个什么情形都不重要。重要的是要明白库文件的本质,及它是如何发挥作用的?在什么阶段发挥作用?然后学会查看编译运行时的报错信息,并配合使用otool、nm、lipo、ar、file等这些命令去查看库文件的一些信息,最终追踪定位到问题。

    原谅我最后都没怎么贴图了,因为流程都和前面差不多。我也写的手累了。如果你还有什么疑惑可以在下面评论,我会尽量及时回复。

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

推荐阅读更多精彩内容