若是你曾经试图去建立一个本身的iOS框架的话,你应该知道这件事并非那些畏惧困难的人可以成功完成的-毕竟管理依赖和编写测试并不容易。这篇文章将从开始到最终完成一步步的进行讲解,以便你掌握后能够更好的建立本身的框架。html
在教程中咱们会构建一个框架,框架里面会暴露一个名为RGBUIColor(red:green:blue)的函数,该函数会返回使用这些参数建立的UIColor对象。咱们会使用Swift语言,而且使用Carthage做为依赖项的管理工具。咱们的框架将会支持经过Carthage、CocoaPods或者git来使用。ios
让咱们开始吧!git
选择 File -> New -> Projectgithub
在左侧的选择 iOS -> Framework & Library,右侧选择“Cocoa Touch Framework”。编程
点击“下一步”,并填写选项提示。确保以及勾选了“Include Unit Tests”。swift
选择工程保存的位置。segmentfault
不要勾选“Create Git repository on My Mac”,咱们在后面手动进行设置。xcode
点击“建立”而且打开工程。架构
选择File -> Save As Workspace并使用工程相同的名字保存到相同的目录中。之因此建立workspace是由于咱们须要添加Carthage中的依赖做为子模块;使用Xcode
编译他们的时候必须是在一个workspace中。app
选择File -> Close Project关闭工程。
而后选择File -> Open打开*workspace*文件。
Xcode左上角的scheme并选择“Manage Schemes”。咱们须要确保sheme勾选了“shared”,以便能使用“Carthage”来构建工程。
首先,切换到工程所在的目录。
运行git init初始化空版本库。
建立一个 .gitignore的文件。该文件会过滤一些Xcode或者依赖文件中一些咱们不想也不须要上传的文件。
这里是一个标准的Swift工程的gitignore文件,咱们只是添加了.DS_Store并移除了fastlane和一些多余的部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
## OS X Finder .DS_Store
## Build generated build/ DerivedData
## Various settings *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata
## Other *.xccheckout *.moved-aside *.xcuserstate *.xcscmblueprint
## Obj-C/Swift specific *.hmap *.ipa
# Swift Package Manager .build/
# Carthage Carthage/Build |
在工程的文件目录下建立一个名为Cartfile的文件以及运行时的依赖性。咱们添加**Curry]**([连接)
github "thoughtbot/Curry"
建立一个名为Cartfile.private的文件。它会负责私有的一些依赖就像咱们的测试框架同样。咱们使用Quick和Nimble。
1 2 |
github "Quick/Quick" github "Quick/Nimble" |
新建bin/setup脚本。它能够提供一个简单的方式来处理依赖和工程,不管时对于贡献者仍是咱们本身。
1 2 3 |
mkdir bin touch bin/setup chmod +x bin/setup |
打开bin/setup并将一下代码加入:
1 2 3 4 5 6 7 |
#!/usr/bin/env sh if ! command -v carthage > /dev/null; then printf 'Carthage is not installed.n' printf 'See https://github.com/Carthage/Carthage for install instructions.n' exit 1 fi carthage update --platform iOS --use-submodules --no-use-binaries |
在这个脚本里面,咱们假设用户一句安装了Carthage连接,而后咱们使用update命令来安装那些依赖项。
咱们使用–use-submodules,全部那些依赖项会以子模块的方式被添加。当用户须要的时候,他就能够直接使用咱们的框架而不须要使用Carthage。咱们使用了–no-use-binaries,全部这些依赖项都会在咱们本身的系统上进行编译。
当bin/setup建好后,咱们直接在终端运行脚本让Cartfile自行下载依赖项。
如今咱们就能够设置咱们的工程而且编译这些依赖项了。
由于咱们的依赖是做为子模块,咱们须要将这些自模块添加到工做区。
1.打开Carthage/Checkouts而后将每一个依赖项的.xcodeproj添加到工做区。你可使用直接拖拽到项目的工做区。
添加完结束后:
在工做区的导航栏选择”RGB” ,而后在中间选择”RGB”目标,进而选择”Build Phases”,展开”Link binary with libraries”。
点击”+”而后选择Curry.framework框架的Curry-iOS。
点击添加。
在中间的工具栏选择”RGBTests”。
使用上面同样的步骤,将”Quick”和”Nimble”框架添加到”Link binary with libraries”。
当咱们将依赖添加到两个目标的时候,Xcode会自动在”Build Settings”下添加”Framework Search Paths”。咱们能够在”RGB”和”RGBTests”中移除,由于同处同一工做区, Xcode将他们自己的一部分。
选择目标下的两个目标,选中”Build Settings”下的”Framework Search Paths”,而后按“退格键”删除。
接下来,在导航栏选择”RGB”工程的时候,你就会看见下面you三个刚刚添加的三个框架。而后全选这三个框架,而后右击选择”New group from selection”而后将他们放到一个组里, 我将组命名为”Frameworks”。
如今Carthage已经设置完成,接下来是CocoaPods。
为了添加CocoaPods支持,咱们须要在工程的根目录新建.podspec,而且包含工程的信息。
新建RGB.podspec文件。
将下面的实例拷贝并复制到文件中(自行对照修改相应的部分)。
使用项目的信息来设置那些选项。更多的选项详情连接,可是该工程中你所须要的那些选择以下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Pod::Spec.new do |spec| spec.name = "RGB" spec.version = "1.0.0" spec.summary = "Sample framework from blog post, not for real world use.Functional JSON parsing library for Swift." spec.homepage = "https://github.com/jakecraige/RGB" spec.license = { :type => 'MIT', :file => 'LICENSE' } spec.authors = { "Jake Craige" => 'james.craige@gmail.com', "thoughtbot" => nil, } spec.social_media_url = "http://twitter.com/thoughtbot" spec.source = { :git => "https://github.com/jakecraige/RGB.git", :tag => "v#{spec.version}", :submodules => true } spec.source_files ="RGB/**/*.{h,swift}" spec.requires_arc = true spec.platform = :ios spec.ios.deployment_target = "9.1" spec.dependency "Curry", '~> 1.4.0' end |
这里面须要注意到的一行是spec.dependency “Curry”, ‘~> 1.4.0′。由于咱们须要支持CocoaPods,咱们假设框架的使用者会使用CocoaPods而不是Carthage,
全部咱们咱们在最后一行也声明依赖而不只仅只在Carthfile声明。
当咱们设置好了以后,咱们在终端中运行pod lib lint命令测试全部的东西是否是都配置好了。若是没错的话,咱们能看见以下的提示:
当工程的依赖项设置好后,咱们就能够写代码了。可是在咱们开始以前,先提交代码。
1 |
git commit -am "Project and dependencies set up" |
打开RGBTests/RGBTests.swift文件,你能够看见一个默认的模版。她使用了@testable和XCTest(,可是接下来咱们会做出一些调整。
首先,咱们会移除@testable,由于咱们须要测试那些框架使用者可能调用的API接口。随着框架的增加,咱们可能会须要@testable去测试那些不是做为公共接口暴露的部分;总的来讲,就是咱们想避免测试那些暴露给使用者的接口。这个特性在测试应用的时候会更加有效,而不是在框架测试中。
来源于苹果关于测试部分的文档:
伴随者可测试性,你系那种可以在Swift 2.0框架和应用中编写测试而且不须要要测试全部的internal和public部分。在XCTest目标而不是其余框架或者应用的测试代码中
使用@testable import {ModuleName}。
咱们使用Quick和Nimble做测试。Quick提供以一个行为驱动类型的测试接口,与RSpec和Specta很是相近;Nimble给咱们提供了强大的断言以及少许模版就能写成异步代码的能力。
写完以后,代码以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import Quick import Nimble import RGB
class RGBTests: QuickSpec { override func spec() { describe("RGB") { it("works") { expect(true).to(beTrue()) } } } } |
使用快捷键CMD + U或者Product -> Test运行测试代码,会显示测试成功。
因此,到如今已经完成了!
开玩笑而已。让咱们来一些真正的测试。
咱们暴露一个RGBUIColor(red: 195, green: 47, blue: 52)调用接口,接口会返回一个漂亮的thoughtbot red的UIColor。
代码以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
describe("RGBUIColor") { it("is a correct representation of the values") { let thoughtbotRed = UIColor( red: CGFloat(195/255), green: CGFloat(47/255), blue: CGFloat(52/255), alpha: 1 ) let color = RGBUIColor(red: 195, green: 47, blue: 52)
expect(color).to(equal(thoughtbotRed)) } } |
若是你此时运行此时的话,会像预料中的那样-失败。由于Swift语言的类型检查会组织咱们运行一个没有定义的RGBUIColor函数。接下来让咱们完成它。
右击RGB选择新建一个文件。建立一个名为RGBUIColor.swift的文件,并将下面的代码拷贝过去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import Curry
func RGBUIColor(red red: Int, green: Int, blue: Int) -> UIColor { return curry(createColor)(red)(green)(blue) }
private func createColor(red: Int, green: Int, blue: Int) -> UIColor { return UIColor( red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/155), alpha: 1 ) } |
这里使用Curry做为一个运行时的依赖性的例子来使用。这里采用了一个不标准的使用斌强没有提供任何值。让咱们继续测试!
第一眼看过去,咱们可能会感到很奇怪。咱们明明已经定义了RGBUIColor函数啊?
确实咱们定义了该函数可是,咱们并无将她声明为public。
这意味着,若是有人系有人使用咱们的框架的话,他们是不能使用这个函数接口的。若是你想看见什么不一样的话,将@testable添加回来,你会发现你的测试经过了。
经过这个错误咱们就知道为何要在iomport前面将@testable移除。这能让咱们在发布框架以前更好的捕捉到错误。
让咱们将函数声明为public,来修复这个问题。运行测试,问题解决了。而后咱们提交代码。
1 |
git commit -am "Completed my first iOS framework!" |
原文出处: Jake Craige 译文出处:BNCoding(@BigNerdCoding )
问啊-定制化IT教育平台,牛人一对一服务,有问必答,开发编程社交头条 官方网站:www.wenaaa.com
QQ群290551701 汇集不少互联网精英,技术总监,架构师,项目经理!开源技术研究,欢迎业内人士,大牛及新手有志于从事IT行业人员进入!