创建你自己的Framework

如果你想将你开发的控件与别人分享,一种方法是直接提供源代码文件。然而,这种方法并不是很优雅。它会暴露所有的实现细节,而这些实现你可能并不想开源出来。此外,开发者也可能并不想看到你的所有代码,因为他们可能仅仅希望将你的这份漂亮代码的一部分植入自己的应用中。

另一种方法是将你的代码编译成静态库(library),让其他开发者添加到自己的项目中。然而,这需要你一并公布所有的公开的头文件,实在是非常不方便。

你需要一种简单的方法来编译你的代码,这种方法应该使得你的代码易分享,并且在多个工程中易复用。你需要的是一种方法来打包你的静态库,将所有的头文件放到一个单元中,这样你就可以立刻将其加入到你的项目中并使用。

非常幸运,这正是本篇教程所要解决的问题。你将会学到制作并使用Framework,帮助你解决这个头疼的问题。OS X完美地支持这一点,因为Xcode就提供了一个项目模板,包含着默认构建目标(target)和可以容纳类似于图片、声音、字体等资源的文件。你可以为iOS创建Framework,不过这是一个比较复杂的手工活,如果你跟着教程走,你将学到怎么样跨过路障,顺利地完成Framework的创建。

当你跟着这篇教程走完后,你将能够:

  • 使用Xcode构建一个基本的静态库工程。

  • 依赖于该静态库工程构建一款应用。

  • 掌握如何将静态库工程转换为完整的、合格的Framework。

  • 最终,你将看到如何将一个图像文件同Framework一起打包到resource bundle下。

开始

这篇教程的主要目的是解释怎么样在你的iOS工程中创建并使用一个Framework。所以,不像其他网站上的教程,这篇教程将只使用一小部分Objective-C代码,并且这一小部分主要是为了说明我们将会遇到的一些概念。

这里下载可用的资源文件RWKnobControl。如果你在Creating a Static Library Project 这篇文章中完成了创建第一个项目的过程,这里你将会看到怎么样使用去它们。

在创建本工程时,你将要创建的所有的代码和项目文件都可以在Github上找到。对于本篇教程中每个创建阶段都有不同的commit。

什么是Framework?

Framework是资源的集合,将静态库和其头文件包含到一个结构中,让Xcode可以方便地把它纳入到你的项目中。

在OS X上,可能会创建一个动态连接(Dynamically Linked)的framework。通过动态连接,framework可以更新,不需要应用重新连接。在运行时,库中代码的一份拷贝被分享出来,整个工程都可以使用它,因此,这样减少了内存消耗,提高了系统的性能。正如你看到的,这是一个功能强大的特性。

在iOS上,你不能用这种方式添加为系统添加自定义的framework,因此仅有的动态链接的framework只能是Apple提供的那些。(编者注:在iOS 8中已加入此特性,开发者可以使用第三方的动态框架

然而,这并不意味着framework对于iOS而言是无关紧要的,静态连接的framework依然可以打包代码,使其在不同的应用中复用。

由于framework本质上是静态库的“一站式采购点”,因此在本篇教程中你所做的第一件事就是创建并使用静态库。当跟着教程走到如何创建framework时,你就能明白你所做的一切了,整体思路也不会那么烟雾缭绕了。

创建一个静态库工程

打开Xcode,点击File\New\Project,选择iOS\Framework and Library\Cocoa Touch Static Library新建一个静态库工程.

ios_framework_creating_static_lib-700x482.png

将工程命名为RWUIControls,然后将工程保存到一个空目录下。

ios_framework_options_for_static_lib-700x476.png

一个静态库工程由头文件和实现文件组成,这些文件将被编译为库本身。

为了方便其他开发者使用你的库和framework,你将进行一些操作,让他们仅需要导入一个头文件便可以访问所有你想公开的类。

当创建静态库工程时,Xcode会自动添加RWUIControls.h和RWUIControls.m。你不需要实现文件,因此右键单击RWUIControls.m选择delete,将它删除到废纸篓中。

打开RWUIControls.h,将所有内容替换为:

1
#import < UIKit/UIKit.h>

导入UIKit的头文件,这是创建一个库所需要的。当你在创建不同的组成类时,你将会将它们添加到这个文件中,确保它们能够被库的使用者获取到。

你所构建的项目依赖于UIKit,然而Xcode的静态库工程不会自动连接到UIKit。要解决这个问题,就要将UIKit作为依赖库添加到工程中。在工程导航栏中选择工程名,然后在中央面板中选择RWUIControls目标。

点击BuildPhases,展开Link Binary with Libraries这一部分,点击+添加一个新的framework,找到UIKit.framework,点击add添加进来。

ios_framework_add_uikit_dependency.gif

如果不结合头文件,静态库是没有用的,静态库编译一组文件,在这些文件中类和方法都以二进制数据的形式存在。在你创建的库中,有些类将能够被公开访问到,有些类只能由库内部访问并使用。

接下来,你需要在build栏中添加新的phase,来包含所有头文件,并将它们放到编译器可以获取到的某个地方。然后,你将会拷贝这些到你的framework中。

依然是在Xcode的Build Phases界面,选择Editor\Add Build Phase\Add Copy Headers Build Phase。

Note:如果你发现按上面找到的菜单项是灰色的(不可点击的),点击下方Build Phases界面的白色区域来获取Xcode的应用焦点,然后重新试一下。

ios_framework_add_copy_headers_build_phase.gif

把RWUIControls.h从项目导航栏中拖到中央面板的Copy Headers下的Public部分。这一步确保任何使用你的库的用户均可以获取该头文件。

ios_framework_add_header_to_public.gif

Note:显然,所有包含在你的公共头文件中的头文件必须是对外公开的,这一点非常重要。否则,开发者在使用你的库时会得到编译错误。如果Xcode在读取公共头文件时不能读到你忘记设为public的头文件,这实在是太令人沮丧了。

创建一个UI控件

既然你已经设置好你的工程了,是时候为你的库添加一些功能了。由于本篇教程的关键在于教你怎么样创建一个framework,而不是怎么样构建一个UI控件,这里你将使用上一篇教程中创建好的控件。在你之前下载好的压缩包文件中找到RWKnobControl目录,从Finder中拖到Xcode下RWUIControls目录下。

ios_framework_drop_rwuiknobcontrol_from_finder-700x466.png

选择Copy items into destination group’s folder,点击下方的选择框,确保RWUIControls静态库目标被选中。

ios_framework_import_settings_for_rwknobcontrol-700x475.png

这一步默认把实现文件添加到编译列表,把头文件添加到Project组。这意味着它们目前是私有的。

ios_framework_default_header_membership-700x327.png

Note:在你弄清楚之前,这三个组的名称可能会让你迷惑,Public是你期望的,Private下的头文件依然是可以暴露出来的,因此名字可能有些误导。讽刺的是,在Project下的头文件对你的工程来说才是“私有”的,因此,你将会更多地希望你的头文件或者在Public下,或者在Project下。

现在,你需要将控件的头文件RWKnobControl.h分享出来,有几种方式可以实现这一点,首先是在Copy Headers面板中将这个头文件从Project栏拖到Public栏。

ios_framework_drag_header_to_public.gif

或者,你可能会发现,更简单的方法是,编辑文件,改变Target Membership面板下的membership。这个选项更方便一些,可以让你不断添加文件,扩充你的库。

ios_framework_header_membership-407x320.png

Note:如果你不断往库中添加新的类,记得及时更新这些类的关系(membership),使尽可能少的类成为public,并确保其他非public的头文件都在Project下。

对你的控件的头文件需要做的另一件事是将其添加到库的主头文件RWControls.h中。在这个主头文件的帮助下,开发者使用你的库仅仅需要导入一个头文件,如下面的代码一样,而不是自己去选择自己需要的一块导入。

1
#import < RWUIControls/RWUIControls.h>

因此,在RWUIControls.h中添加下面的代码:

1
2
// Knob Control
#import

配置Build Settings

现在距离构建这个项目、创建静态库已经非常接近了。不过,这里要先进行一些配置,让我们的库对于用户来说更友好。

首先,你需要提供一个目录名,表示你将把拷贝的公共头文件存放到哪里。这样确保当你使用静态库的时候可以定位到相关头文件的位置。

在项目导航栏中点击项目名,然后选择RWUIControls静态库目标,选择Build Setting栏,然后搜索public header,双击Public Headers Folder Path,在弹出视图中键入如图所示内容:

ios_framework_public_headers_path-700x174.png

一会你就会看到这个目录了。

现在你需要改变一些其他的设置,尤其是那些在二进制库中遗留下的设置,编译器提供给你一个选项,来消除无效代码:永远不会被执行的代码。当然你也可以移除掉一些debug用符号,例如某些函数名称或者其他跟debug相关的细节。

因为你正在创建framework供他人使用,最好禁掉这些功能(无效代码和debug用符号),让用户自己选择对自己的项目有利的部分使用。和之前一样,使用搜索框,改变下述设置:

  • Dead Code Stripping设置为NO

  • Strip Debug Symbol During Copy 全部设置为NO

  • Strip Style设置为Non-Global Symbols

编译然后运行,到目前为止没什么可看的,不过确保项目可以成功构建,没有错误和警报是非常好的。

选择目标为iOS Device,按下command + B进行编译,一旦成功,工程导航栏中Product目录下libRWUIControls.a文件将从红色变为黑色,表明现在该文件已经存在了。右键单击libRWUIControls.a,选择Show in Finder。

ios_framework_successful_first_build-700x454.png

再此目录下,你将看到静态库,libRWUIControls.a,以及其他你为头文件指定的目录。注意到,正如你所期望的,那些定为public的头文件可以在此看到。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值