发布于 2016-03-03 04:53:25 | 166 次阅读 | 评论: 0 | 来源: 分享
iOS苹果移动操作系统
苹果iOS是由苹果公司开发的移动操作系统。苹果公司最早于2007年1月9日的Macworld大会上公布这个系统,最初是设计给iPhone使用的,后来陆续套用到iPod touch、iPad以及Apple TV等产品上。
如果你曾经试图去创建一个自己的iOS框架的话,你应该知道这件事并不是那些畏惧困难的人能够成功完成的-毕竟管理依赖和编写测试并不容易。这篇文章将从开始到最终完成一步步的进行讲解,以便你掌握后可以更好的创建自己的框架。
在教程中我们会构建一个框架,框架里面会暴露一个名为RGBUIColor(red:green:blue)的函数,该函数会返回使用这些参数创建的UIColor对象。我们会使用Swift语言,并且使用Carthage作为依赖项的管理工具。我们的框架将会支持通过Carthage、CocoaPods或者git来使用。
让我们开始吧!
首先,切换到工程所在的目录。
这里是一个标准的Swift工程的gitignore文件,我们只是添加了.DS_Store并移除了fastlane和一些多余的部分。
## 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
github "thoughtbot/Curry"
github "Quick/Quick"
github "Quick/Nimble"
mkdir bin
touch bin/setup
chmod +x bin/setup
#!/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添加到工作区。你可以使用直接拖拽到项目的工作区。
添加完结束后:
现在Carthage已经设置完成,接下来是CocoaPods。
为了添加CocoaPods支持,我们需要在工程的根目录新建.podspec,并且包含工程的信息。
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命令测试所有的东西是不是都配置好了。如果没错的话,我们能看见如下的提示:
当工程的依赖项设置好后,我们就可以写代码了。但是在我们开始之前,先提交代码。
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给我们提供了强大的断言以及少量模版就能写成异步代码的能力。
写完之后,代码如下:
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。
代码如下:
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的文件,并将下面的代码拷贝过去。
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,来修复这个问题。运行测试,问题解决了。然后我们提交代码。
git commit -am "Completed my first iOS framework!"
我写的代码。转载请表明出处,谢谢。