前言
翻译已与 raywenderlich 社区取得联系(可翻译10篇文章),原文链接
是否想过把参与过的多个项目中功能相近的代码拆分成可复用的模块,是否想过与其他开发者分享你写的模块?
也许你想像 iOS SDK 按功能来组织 API 一样来模块化你的代码,也许也想像知名三方库那样发布自己的代码。
通过这篇文章你将会学会如何创建 Framework 以及如何进行发布。
iOS 8,Xcode 6 中,苹果提供了一种新的开发模板,Cocoa Touch Framework。这使得创建 Framework 更加容易。
Framework 有一下三个主要目的:
- 代码封装
- 代码模块化
- 代码复用
你可以在你的其他 App 中,团队成员,或 iOS 社区分享你的 Framework。swift 的访问控制机制使得 framework 在代码模块之间提供了健壮可靠的接口。
swift 中,module 是作为一个编译发布的代码单元。framework 和 App 都是一种 module。
在这篇教程中,我们将会拆解一个已存在的 App 为例子,通过下面的步骤把部分代码拆分出来打包成 framework :
- 为 rings widget 创建一个新的 framework
- 将代码和测试单元移植到 framework 中
- 导入 framework 到 App 中
- 打包成 cocoapods
- 为你的 framework 设置代码仓库
完成上面步骤后,你已经成功将该 App 中的部分代码打包成了可移植的 framework。
开始
Phonercise 是一款简单的呈现苹果手表 Activity 应用数据的 App,另外还会记录你手机的物理状态。主界面的三个环分别代表移动,站立,运动。
该项目需要在真机上进行调试,并打开音量,开始吧。
移动手机,摇晃手机,保持站立来分别记录移动,运动,站立的数据。
该 App 的逻辑如下:
- ActionViewController 包含 view 的生命周期管理和动作逻辑。
- 所有包含视图逻辑的文件都在 Three Ring View 这个文件夹下。该文件夹下有管理视图的 ThreeRingView.swift 类,管理音频的 Fanfare.swift 类,和管理管理自定义视图的其他类。
下面开始将环的控制打包成可复用的 framework。
创建 Framework
framework 是自包含,可复用的代码和其他资源的组织单元。你可以将 framework 导入其他 App 中,甚至可以在 iOS,tvOS,watchOS 和 macOS 跨平台使用。
如果你使用过其他编程语言,你应该听过节点模块,包,gems,jars 等等。framework 是 Xcode 对于包或者模块的实现方式。比如 iOS SDK 中通用的 framework:Foundation, UIKit, AVFoundation, CloudKit 等。
设置 Framework
Xcode 6˙中开始新增了 Cocoa Touch Framework 代码模板,这使得创建 framework 变得非常容易。首先创建 framework 的项目。
- Xcode 中,通过 File/New/Project 创建一个新项目。
- 选择 iOS/Framework & Library/Cocoa Touch Framework 创建一个新的 framework。
- 点击 Next
- 设置 Product Name 为 ThreeRingControl。使用你自己的 Organization Name 和 Organization Id恩替覅而。点击 Include Unit Tests。这样项目将会包含测试单元来确保项目中没有 bug。
- 点击 Next
- 在文件选择框中,选择在 Phonercise 项目同级目录中创建项目。
- 点击 Create
现在已成功创建了一个 framework。
添加代码和资源
现在你的 framework 中还没有代码。从 Phonercise 项目中把以下八个文件拖拽到当前项目中:
- CircularGradient.swift
- coin07.mp3
- Fanfare.swift
- RingLayer.swift
- RingTip.swift
- ThreeRingView.swift
- Utilities.swift
- winning.mp3
点击了 Copy items if needed,确保文件被拷贝进了新项目而不是只添加了文件的引用。framework 需要自己的源码文件而不是文件引用。
编译,确保编译没有任何警告和错误。
将 Framework 添加到项目中
回到 Phonercise 项目中。删除 Three Ring View 组下的六个文件和 Helper Files 文件夹下两个 MP3 文件。点击 Move to Trash。
编译,出现 “Use of undeclared type 'ThreeRingView” 错误信息。
Phonercise 项目导航器中右键,点击 Add Files to "Phonercise"。在文件选择器中选择 ThreeRingControl.xcodeproj。这样把 ThreeRingControl.xcodeproj 作为子项目添加进来。
注意:也可以直接添加 ThreeRingControl.framework 到项目中。然而添加整个项目会让同时开发 framework 和 App 变得更容易。你对 framework 项目做的任何改变都将自动应用到 App 上。
虽然这两个项目在同一工作空间中,Phonercise 仍然无法访问 ThreeRingControl。
通过链接 framework 到 App 的 target 能够解决这个问题。打开 ThreeRingControl 项目的 Products 文件夹,里面有一个 ThreeRingControl.framework 文件。该文件打包了二进制代码,头文件,资源等。
点击 Phonercise 项目的项目导航器,点击 Phonercise target,选择 General tab。
滚动到 Embedded Binaries 选择。把 ThreeRingControl.xcodeproj Products 文件夹下的 ThreeRingControl.framework 拖拽到该选项中。
这样同时为 Embedded Binaries 和 Linked Frameworks and Binaries 添加了 framework 的入口。
这样 App 就知道如何查找该 framework,编译,出现更多相同错误。
访问控制
此时虽然 framework 已经是该项目的一部分了,但该项目代码仍然无法访问。
进入 ActionViewController.swift,在该文件的顶部添加如下代码进行导入。
import ThreeRingControl
导入后仍然没有解决错误信息。因为 swift 使用了访问控制权限来让开发者决定哪些东西可以暴露给其他用户。
swift 默认使用 internal 访问控制权限,这使得代码仅在模块内可见。
虽然很麻烦,但访问控制权限让开发者能够隐藏核心功能以防被修改,或者显示的通过 internal 来暴露给其他用户。
swift 有三个等级的访问控制权限。通过下面的规则来进行选择:
- Public: 对 App 或其他 framework 可见。
- Internal: 对该 framework 可见
- Fileprivate: 对该编译文件可以见
- Private: 对该类可见
创建 Cocoapod 源
创建 Pod
在终端进入到 ThreeRingControl 目录下。运行下面命令:
pod spec create ThreeRingControl
该命令会在当前目录下创建 ThreeRingControl.podsepc 文件。该模板文件描述了 pod 以及如何进行编译。通过 vi 打开。
该模板文件包含大量注释和通用设置建议
- 使用下面代码替换 Spec Metadata:
s.name = "ThreeRingControl"
s.version = "1.0.0"
s.summary = "A three-ring control like the Activity status bars"
s.description = "The three-ring is a completely customizable widget that can be used in any iOS app. It also plays a little victory fanfare."
s.homepage = "http://raywenderlich.com"
2.该 iOS framework 使用了 MIT 协议,使用下面的代码替换 Spec License:
s.license = "MIT"
3.该 framework 仅用于 iOS 平台,使用下面的代码替换 Platform Specifics:
s.platform = :ios, "10.0"
4.使用下面代码替换 Source Location。当你想通过 pod 进行发布,需要将这里替换成 GitHub repo 的地址和提交的 tag。
s.source = { :path => '.' }
5.使用下面代码替换 Source Code:
s.source_files = "ThreeRingControl", "ThreeRingControl/**/*.{h,m,swift}"
6.添加 Resources 项:
s.resources = "ThreeRingControl/*.mp3"
这样可以把音频文件包含进 framework 的 bundle 中。
7.删除 Project Linking 和 Project Setting 项。
8.指定该 pod 代码使用的 swift 版本号。
s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3' }
9.删除多余的注释(注释以#开头)
使用 Pod
这一节会带领你完成最后一步,发布 pod 到 GitHub。
发布到 Pod
创建代码仓库
如果你还没有 GitHub 账号,创建账号.
创建一个托管该 pod 代码的新仓库。把该仓库命名为 ThreeRingControl,也可以使用任何其他名字。确保 .gitignore 选项为 swift license 为 MIT。
点击创建仓库。
克隆仓库
回到终端创建一个新的文件夹。下面的命令会创建一个名为 repo 的文件夹。
mkdir repo
cd repo
克隆刚才创建的 GitHub 仓库。替换下面命令中 URL 为 GitHub 仓库的链接。
git clone URL
这会创建一个 Git 文件夹,并把之前创建的 README 和 LICENSE 文件克隆下来。
把代码拷贝到克隆下来的文件夹中
把 ThreeRingControl 文件夹中的文件拷贝到 repo/ThreeRingControl 文件夹中。
打开拷贝的 ThreeRingControl.podsepc,更新 s.source 信息:
s.source = { :git => "URL", :tag => "1.0.0" }
把 URL 设置你的 GitHub 上代码仓库链接。
提交代码
提交并把代码 push 到 GitHub 上。
cd ThreeRingControl/
git add .
git commit -m "initial commit"
git push
打标记
运行下面命令给仓库打上标记,以便 Podspec 能够匹配。
git tag 1.0.0
git push --tags
欢迎关注我的简书,我会定期做一些技术分享:)