版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.08.11 |
前言
很多时候我们可以用第三方库,比如是SDWebImage或者一些视频云播放器的框架或库,这些框架其实也是有人写好了封装起来的,不同的工程都可以直接拿来使用,以达到代码分享、模块化你的代码以及将其作为第三方库进行发布。
必要说明
您是否曾想在两个或多个应用程序之间共享一大堆代码,或者想与其他开发人员共享您的程序的一部分?
也许您希望以类似于iOS SDK按功能分离其API的方式模块化您的代码。 或许您希望以与流行的第三方库相同的方式发布您的代码。
在本教程中,您将学习如何使用Frameworks
完成上述所有操作!
框架有三个主要目的:
- 代码封装。
- 代码模块化。
- 代码重用。
您可以与其他应用,团队成员或iOS社区共享您的框架。 当与Swift的access control
结合使用时,框架有助于在代码模块之间定义强大,可测试的接口。
用Swift的说法,module
是一组编译在一起发布的代码。 框架是一种类型的模块,而应用程序是另一个示例。
在本教程中,您将通过以下方式了解框架的细节:
- 为旋钮控件创建一个新框架。
- 迁移现有代码。
- 将整个内容导回到应用程序中。
- 在Interface Builder中动态渲染自定义组件。
- 将其打包成超便携式CocoaPod。
-
Bonus
:为您的框架设置存储库。
当你完成时,应用程序将完全像以前一样运行,但将使用你开发的可移植框架!
开始
在Xcode中打开启动已有的项目。
KnobShowcase
是一个简单的应用程序,它演示了如何与控件(如圆形滑块)进行交互,例如在调音台上找到的控件。
构建并运行以了解其工作原理。
此控件的代码位于两个文件中:
-
Knob.swift
具有所有视图逻辑。 -
ViewController.swift
负责创建旋钮并与之交互。
这个旋钮控制很有趣,但是在更多的应用中使用到不是更好吗?框架就可以帮你做到这一点。
Creating a Framework - 创建一个框架
框架是独立的,可重复使用的代码和资源块,您可以将其导入任意数量的应用程序,甚至可以在iOS,tvOS,watchOS和macOS应用程序之间共享。
如果您使用其他语言编程,您可能听说过node modules
,packages
,gems
或jars
。 框架是这些的Xcode版本。 iOS SDK中常见框架的一些示例是Foundation
,UIKit
,AVFoundation
和CloudKit
。
注意:如果您想了解有关Frameworks的更多信息,请阅读What are Frameworks?
1. Framework Set Up - 框架设置
在Xcode 6中,Apple引入了Cocoa Touch Framework
模板以及access control
,因此创建框架从未变得如此简单。 首先要做的是为框架创建项目。
- 1)在Xcode中,选择
File ▸ New ▸ Project….
- 2)选择
iOS ▸ Framework & Library ▸ Cocoa Touch Framework
- 3)点击
Next
- 4)设置
Product Name
为KnobControl
,使用你自己的Organization Name
和Organization Identifier
- 5)点击
Next
- 6)在文件选择器中,选择在与
KnobShowcase
根文件夹相同的级别创建项目。
- 7)点击
Create
现在你有一个创建框架的项目(尽管很无聊)!
2. Add Code - 添加代码
您当前的状态是没有代码的框架,这与没有糖的巧克力一样吸引人。 在本节中,您将通过将现有文件添加到框架来引入代码。
从KnobShowcase
源目录中,将Knob.swift
文件拖到Xcode中的KnobControl
项目中。 如果需要,请务必选中Copy items if needed
,以便将文件实际复制到新项目中,而不是仅添加引用。 框架需要自己的代码才能独立,而不是引用。
仔细检查Knob.swift
在KnobControl
中是否具有Target Membership
,以确保它出现在最终框架中。 您可以在File inspector
中对此进行验证。
构建框架项目以确保您在没有构建警告或错误的情况下获得Build Succeeded。
Knob.swift
中包含三个不同的类:
-
Knob
- 旋钮:实际的自定义控件。 -
KnobRenderer
:一个私有类,用于跟踪与渲染旋钮本身相关的代码。 -
RotationGestureRecognizer
:一个私有类,可以与旋钮进行交互。
您的下一个任务是将这些组件分成不同的文件。 首先移动KnobRenderer
:
- 1)转到
File ▸ New ▸ File…
并选择iOS ▸ Source ▸ Swift File
。 - 2)点击
Next
。 - 3)在下一个屏幕截图上,将类名指定为
KnobRenderer
,然后选择KnobControl▸KnobControl
目录。
- 4)点击
Create
- 5)打开
Knob.swift
,剪切(Command-X
)整个KnobRenderer
类并将其粘贴(Command-V)
到import Foundation
语句正下方的KnobRenderer.swift
中。 - 6)删除
KnobRenderer
的私有修饰符。 当代码全部包含在Knob.swift
中时,这很好,但现在必须可以使用默认的internal
修饰符访问整个模块。
对RotationGestureRecognizer
类重复步骤1到6。 在这种情况下,当您执行第五步时,请确保您还获取导入UIKit.UIGestureRecognizerSubclass
语句,否则编译器将在构建阶段进行complain
。
创建了两个新文件后,Knob.swift
现在只包含Knob
类。
注意:将类分成它们自己的文件并不是绝对必要的,但为了使代码组织起来,这是一个很好的做法。 您不希望拥有难以理解和维护的庞大文件。
Add the Framework to the Project - 将框架添加到项目
关闭KnobControl
项目,然后返回KnobShowcase
项目。 删除Knob.swift
文件。 在确认对话框中选择Move to Trash
。
Build项目,你会看到几个可预测的错误,其中包含了Xcode不知道什么是旋钮。 好吧,你实际上会看到Use of undeclared type ‘Knob’
错误消息。
添加KnobControl
框架项目是解决这些问题的方法。
Embed Your Binary - 嵌入你的二进制
右键单击项目导航器中的根KnobShowcase
节点。 单击Add Files to “KnobShowcase”
。 在文件选择器中,导航到并选择KnobControl.xcodeproj
。 单击Add
以将KnobControl.xcodeproj
添加为子项目。
注意:将框架项目添加到app项目并不是绝对必要的。你可以添加
KnobControl.framework
输出。但是,组合这些项目可以更轻松地同时开发框架和应用程序。 您对框架项目所做的任何更改都会自动传播到应用程序。 它还使Xcode更容易解析路径并知道何时重建项目。
Build并运行,您将看到相同的编译错误!
即使这两个项目现在在一起,KnobShowcase
仍然没有得到KnobControl
。 这就像他们坐在同一个房间,但KnobShowcase
无法看到新的框架。
您将框架链接到应用程序的目标以解决此问题。 首先,展开KnobControl
项目以查看Products
文件夹,然后在其下面查找KnobControl.framework
。 此文件是框架项目的输出,用于打包二进制代码,标头,资源和元数据。
选择顶级KnobShowcase
节点以打开项目编辑器。 单击KnobShowcase
目标,然后转到General
选项卡。
向下滚动到Embedded Binaries
部分。 将KnobControl.framework
从KnobControl.xcodeproj
的Products
文件夹拖到此部分。
您刚刚在Embedded Binaries
和Linked Frameworks and Binaries
中添加了框架条目。
现在应用程序知道框架以及在哪里找到它,所以这应该足够了,对吧?
构建KnobShowcase
项目。 更多相同的错误。
Access Control - 访问获取控制
你的问题是虽然框架是项目的一部分,但是项目的代码并不知道它 - 看不见。
转到ViewController.swift
,并将以下行添加到文件顶部的导入列表中。
import KnobControl
这很关键,但是这种包含仍然无法解决构建错误。 这是因为Swift使用access control
来确定构造是否对其他文件或模块可见。
默认情况下,Swift仅在其自己的模块内部使internal
或可见。
要恢复应用程序的功能,您必须更新Knob
类的访问控制。
虽然它有点单调乏味,但更新访问控制的过程通过隐藏不应出现在框架之外的代码来提高模块性。 您可以通过将某些函数保留为无访问修饰符,或通过明确声明它们为internal
来实现此目的。
Swift有五个级别的访问控制。 创建自己的框架时,请遵循以下经验法则:
- Open and public:用于应用程序或其他框架调用的代码,例如 自定义视图。
- Internal:用于框架内的函数和类之间使用的代码,例如 该视图中的自定义图层。
- Fileprivate:用于单个文件中使用的代码,例如 一个帮助函数,用于计算布局高度。
- Private:用于封闭声明中使用的代码,例如单个类块,以及该声明在同一文件中的扩展。
当Knob
成为Showcase
应用程序的一部分时,内部访问不是问题。 现在它已经在一个单独的模块中,必须将其公开以供应用程序使用它。 你将在下一节中做到这一点。
注意:如果您想了解有关访问控制内部的更多信息并了解
open
和public
之间的区别,请查看 Access Control Documentation。
Update the Code - 更新代码
在KnobShowcase
中打开Knob.swift
。 通过将public
关键字添加到类定义来使类成为公共,如下所示:
public class Knob : UIControl {
现在任何导入KnobControl
框架的应用程序文件都可以看到Knob
。
现在将public
关键字添加到:
- 属性
minimumValue,maximumValue,value,isContinuous,lineWidth, startAngle,endAngle,pointerLength和color
。 注意value
,该属性将是public
的,而setter继续是私有的。 - 两个
init
函数。 - 方法
setValue(_:animated :)
和tintColorDidChange()
。
注意:您可能想知道为什么必须将
init
方法声明为public
。 Apple在其访问控制文档中解释了这个以及其他更精细的访问控制点。
现在构建并运行。 好消息是错误消失了,坏消息是你遇到了如下运行时崩溃:
这是怎么回事? 下一篇会进行介绍。
后记
本篇主要介绍了一个详细的框架创建流程,感兴趣的给个赞或者关注~~~