從零開始,打造自己的首個 iOS 框架
如果你曾試圖建立自己的iOS框架,你知道這不是一個頭腦發熱作出的決定 — 管理依賴以及寫測試用例一點也不簡單。本教程將會帶你從頭到尾建立你的第一個iOS框架,讓你可以建立自己的框架。
我們將在框架暴露一個名為 RGBUIColor(red:green:blue)
的函式,這個函式根據引數返回一個新的UIColor
。我們將使用 Swift 建立它,並使用 Carthage 作為依賴管理器。在 Carthage、CocoaPods 或者 git submodules 中都可以使用我們的框架。
讓我們開始吧!
設定 Xcode 工程
- 選擇 File → New → Project。
- 在左邊欄選擇 iOS → Framework & Library,然後在右側選擇 “Cocoa Touch Library”。
- 點選“Next”並且填寫彈出的選項。確保勾選了“Include Unit Tests”複選框。
- 選擇工程的儲存位置。
- 取消選擇“在我的 Mac 上建立 Git 版本庫”,我們稍後將手動建立它。
- 點選“建立”,工程將在 Xcode 中開啟。
- 轉到File → Save As Workspace,使用同樣的名字將你的 Xcode 工程儲存到相同的路徑下。我們之所以將工程放到工作區中,是因為我們將把Carthage依賴作為子模組加入進來;Xcode必須確保它們在一個工作區中才能 build 它們。
- 用 File → Close Project 關閉 Xcode 工程。
- 用 File → Open 開啟工作區。
- 點選 Xcode 左上方的 scheme 並選擇“Manage Schemes”。我們需要將我們的 scheme 標記為“shared”,以便工程可以用Carthage構建。
- 定位到“RGB”scheme,選中“Shared”複選框然後點選“Close”。
讓我們移步到終端去。
初始化 Git
首先,導航到你儲存工程所在的目錄。
- 執行
git init
來初始化一個空的版本庫。 - 建立一個
.gitignore,
將我們不希望在git中追蹤的一些討厭的Xcode檔案和依賴檔案排除出去。
這裡是一個稍作修改的,Swift工程使用的標準的.gitignore檔案。我們增加了.DS_Store
,並刪除了fastlane和多餘的註釋。
1234567891011121314151617181920212223242526272829303132 | .DS_Store## Build generatedbuild/DerivedData## Various settings*.pbxuser!default.pbxuser*.mode1v3!default.mode1v3*.mode2v3!default.mode2v3*.perspectivev3!default.perspectivev3xcuserdata## Other*.xccheckout*.moved-aside*.xcuserstate*.xcscmblueprint## Obj-C/Swift specific*.hmap*.ipa# Swift Package Manager.build/# CarthageCarthage/Build |
新增 Carthage 和依賴
- 在你的工程目錄下建立一個名為
Cartfile
的檔案,並新增執行時依賴。我們將新增 Curry。
Objective-C1 github"thoughtbot/Curry" - 建立一個
Cartfile.private
檔案。它將包含私有的依賴,例如我們的測試框架。我們將使用 Quick 和 Nimble。
Objective-C12 github"Quick/Quick"github"Quick/Nimble" - 建立一個
bin/setup
指令碼。它用來給我們的貢獻者(以及我們)一個簡單的方法來設定工程以及依賴。
Objective-C123 mkdir bintouch bin/setupchmod+xbin/setup - 開啟
bin/setup
,寫入如下內容:
123456789 | #!/usr/bin/env shif!command-vcarthage>/dev/null;thenprintf'Carthage is not installed.n'printf'See https://github.com/Carthage/Carthage for install instructions.n'exit1ficarthage update--platform iOS--use-submodules--no-use-binaries |
在這段指令碼中,我們確保使用者安裝了Carthage,並且執行它的 update
命令來安裝iOS依賴。
我們使用了 --use-submodules
已使我們的依賴作為子模組被新增進來。這樣當用戶希望脫離 Carthage 的時候,也能使用我們的框架。我們使用 --no-use-binaries
,這樣我們的依賴就是在我們的系統上 build 的。
bin/setup建立好之後,讓我們執行它,以便Carthage下載我們的依賴。
- 在終端中執行
bin/setup
。
現在我們需要設定我們的工程,來構建和連結新的依賴。
向工作區新增依賴
因為我們的依賴是一些子模組,我們需要把他們新增到我們的工作區。
開啟 Carthage/Checkouts
,然後把每一項依賴的.xcodeproj
新增到工作區的根目錄。可以把他們從 Finder 拖入 Xcode 工程的導航器。
當你完成之後,導航器應該看起來像這樣:
連結執行時依賴
- 在導航器中選擇“RGB”並且在中間的工具條選擇“RGB”目標,選擇“Build Phases”選項卡並展開“Link binary with libraries”小節。
- 點選“+”圖示並從
Curry-iOS
目標中選擇Curry.framework
。 - 點選“Add”。
連結開發依賴
- 在中間的工具條選擇“RGBTests”目標。
- 使用跟上文相同的過程,在該目標的“Link binary with libraries”小節新增 Quick 以及 Nimble 框架。當我們在每個目標新增依賴的時候,Xcode 會自動將他們新增到“Build Settings”選項卡的“Framework Search Paths”中。我們可以將它們從“RGB”和“RGBTests”目標中移除,由於是在相同的工作區中,Xcode將他們看作隱式依賴。
- Select the target, locate the “Framework Search Paths” setting, highlight it, and press “backspace” on your keyboard.
- 選擇該目標,定位到“Framework Search Paths”設定,使其高亮,然後點選鍵盤上的退格鍵。
- 接著,看一下導航器中的“RGB”工程;你將會看見根級有三個新的框架。為了保持這個區域有序,高亮所有這三項,右擊並選擇“New group from selection”,將它們放入一個有名字的組。我將給我的組取名“Frameworks”。
現在 Carthage 設定好了,讓我們新增 CocoaPods。
新增 CocoaPods 支援
要新增 CocoaPods 支援,我們需要在工程的根目錄建立一個 .podspec
檔案,並且寫入我們的工程資訊。
- 建立一個名為
RGB.podspec
的檔案。 - 把下面的示例複製貼上到該檔案中。
- 在選項中填入你工程的細節。有更多的選項可供你填寫,但下面這些是這個專案需要的。
12345678910111213141516 | Pod::Spec.newdo|spec|spec.name="RGB"spec.version="1.0.0"spec.summary="Sample framework from blog post, not for real world use."spec.homepage="https://github.com/jakecraige/RGB"spec.license={type:'MIT',file:'LICENSE'}spec.authors={"Your Name"=>'[email protected]'}spec.social_media_url="http://twitter.com/thoughtbot"spec.platform=:ios,"9.1"spec.requires_arc=truespec.source={git:"https://github.com/jakecraige/RGB.git",tag:"v#{spec.version}",submodules:true}spec.source_files="RGB/**/*.{h,swift}"spec.dependency"Curry","~> 1.4.0"end |
需要注意的一行是 spec.dependency "Curry", '~> 1.4.0'
。因為我們要支援 CocoaPods,我們期望我們框架的使用者使用 CocoaPods 而不是 Carthage,所以我們必須在這裡以及 Cartfile
中指定依賴。
一旦設定好之後我們可以執行 pod lib lint
命令來測試一切是否配置妥當。如果執行沒問題,我們將看到類似這樣的結果:
當工程和依賴設定好之後,我們已經基本就緒,可以寫程式碼了。當我們這麼做之前,讓我們建立我們的第一個 commit。
Shell1 | git commit-am"Project and dependencies set up" |
編寫第一個測試
開啟 RGBTests/RGBTests.swift
來看一看預設的模板。它使用 @testable
以及 XCTest
,但我們將把兩者都換掉。
我們將移除 @testable
,因為我們想要測試公有 API,也就是框架的使用者將會使用的部分。當我們的框架發展變大,我們可能需要 @testable
來測試沒有公開暴露的部分;總的來說我們想要避免這樣的情況,使得我們要測試的是暴露給使用者的部分。這個特性在測試應用而不是框架的時候最有用。
下面是 Apple Docs中關於可測試性的部分:
通過可測試性,你現在可以在不暴露內部程式的情況下,編寫 Swift 2.0 框架及應用的測試。在測試原始碼中使用 @testable import {ModuleName} 使得所有公有或內部的程式對 XCTest 目標可用,而對其它框架或應用目標不可用。
我們將使用 Quick 和 Nimble 用於測試。Quick 提供了一個良好的測試介面,擁有十分類似於 RSpec 和 Specta 的行為驅動的風格;Nimble 給予我們很多強大的斷言,以及用更少的樣本檔案編寫匿名程式碼的能力。
一旦做了這些改變,測試檔案看起來將類似於這樣:
Shell12345678910111213 | import Quickimport Nimbleimport RGBclassRGBTests:QuickSpec{override func spec(){describe("RGB"){it("works"){expect(true).to(beTrue())}}}} |
用 ⌘U 或 Product → Test 執行測試,它們應該是綠的。
然後……我們成功了!
開玩笑的。讓我們寫點真正的測試。
我們希望呼叫 RGBUIColor(red: 195, green: 47, blue: 52)
返回一個漂亮的“thoughtbot red”UIColor
。
程式碼看起來類似於:
Shell12345678910111213 | 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”組,選擇“New File”。
建立一個名為 RGBUIColor.swift
的 Swift 檔案並儲存。在裡面寫上如下實現:
1234567891011121314 | import Curryfunc RGBUIColor(red red:Int,green:Int,blue:Int)->UIColor{returncurry(createColor)(red)(green)(blue)}private func createColor(red:Int,green:Int,blue:Int)->UIColor{returnUIColor(red:CGFloat(red/255),green:CGFloat(green/255),blue:CGFloat(blue/155),alpha:1)} |
這裡 curry
的使用是一個使用執行時依賴的示例。這是一個非標準的用法,並且不提供任何的值。
現在讓我們執行這個測試!
乍一看,這個錯誤可能看起來有點奇怪。我們明明定義了 RGBUIColor
函式,不是嗎?
我們確實定義了,但是沒有把它標記為 public
。
這意味著如果有人嘗試使用我們的框架,他們將看不到這個函式。如果你想看見這些不同起作用,把 @testable
添加回來,然後你的測試就通過了。
正因為有這個錯誤的經驗,我們在開始的時候從 import
中移除了 @testable
。這有助於我們在向其它人釋出我們的框架之前,早點捕捉到這類錯誤。
為了糾正這個錯誤,讓我們把這個函式標記為 public
,就像這樣:
123 | public func RGBUIColor(red red:Int,green:Int,blue:Int)->UIColor{returncurry(createColor)(red)(green)(blue)} |
讓我們執行測試!
我們綠了!
讓我們提交這個小婊砸。
Shell1 | git commit-
相關推薦從零開始,打造自己的首個 iOS 框架如果你曾試圖建立自己的iOS框架,你知道這不是一個頭腦發熱作出的決定 — 管理依賴以及寫測試用例一點也不簡單。本教程將會帶你從頭到尾建立你的第一個iOS框架,讓你可以建立自己的框架。 我們將在框架暴露一個名為 RGBUIColor(red:green:blue) 的函式,這個函 GPU 挖礦:從零開始,擁有自己的比特幣以比特幣為代表的數字貨幣作為區塊鏈技術的重要應用,正在慢慢進入人們的視野,擁有自己的數字資產也是一件很酷的事情,如果你不想買,那麼最好的獲取方法就是挖礦。挖礦之前,我需要作幾個簡單的說明,以澄清潛在的誤區:首先,是不是數字貨幣只有比特幣呢?答案顯然是否定的。數字貨幣行情分析網站非小號目前共收錄了 1700+ 【微框架】之一:從零開始,輕鬆搞定SpringCloud微框架系列--開山篇一、SpringCloud專案簡介 Spring Cloud: 微服務工具包,為開發者提供了在分散式系統的配置管理、服務發現、斷路器、智慧路由、微代理、控制匯流排等開發工具包。 Spring Boot: 旨在簡化建立產品級的 Spring 從零開始,5分鐘建立並玩轉屬於自己的區塊鏈(圖文攻略)宣告 : 此文件只做學習交流使用,請勿用作其他商業用途 author : 朝陽_tony E-mail : [email protected] Create Date: 2016-7-18 10:31:15 Monday Last Change Python爬蟲系列(一):從零開始,安裝環境tar 公司 pip nal 網頁 解析 目標 http caption 在上一個系列,我們學會使用rabbitmq。本來接著是把公司的celery分享出來,但是定睛一看,celery4.0已經不再支持Windows。公司也逐步放棄了服役多年的celery項目。恰好,公司找 從零開始,從有到無,階段性回顧1達內網絡層的基礎交換及原理 網絡設備介紹: 交換機 - 連接相同網絡的設備; 路由器 - 連接不同網絡的設備; 防火墻 - 配置網絡權限控制策略;網絡設備的分類: 傻瓜式設備 網管型設備 IP地址: 需要上網的設備,必須都配置一個 IP 地址; IP地址相當於人類世界中每個人的名字 從零開始,輕松搞定SpringCloud微服務系列markdown class net 配置中心 html div .html href .com 本系列博文目錄 【微服務】之一:從零開始,輕松搞定SpringCloud微服務系列–開山篇(spring boot 小demo) 【微服務】之二:從零開始,輕松搞定Spring 第1天,萬事開頭難,重新從零開始,加油吧,少年!百度 堅持 買車 曾經 努力 未來 一些事 過去 從零開始 現在是下午的三點多,天氣是太陽高照,晴空萬裏。老媽出去放鴨子了,老爸又騎著摩托去做建築的活了。我一個待在家裏,不知道幹些什麽,發現自己這幾年都在迷茫中度過,始終發現自己還是有心裏落差,放不下一些事,也是十分的不懂 從零開始,使用Docker Swarm部署集群教程att 擴展應用 主機 從零開始 均衡集 這就是 url參數 登陸 簡單 本文首先從Dockerfile創建了一個簡單web鏡像 然後將web鏡像推送到了遠程倉庫,以備後面集群中不同機器自動下載 之後使用docker-compose.yml配置了一個應用 而後新建了2臺 從零開始,如何閱讀一篇論文轉自:https://blog.csdn.net/GitChat/article/details/78019743 這裡的從零開始,指的是我們要從零瞭解這篇文章做了什麼事情、使用了什麼方法、得到什麼結果,這樣的方法和結果對我有沒有什麼借鑑。 而不是說,接觸到一個全新的領域,從讀論文開始入手。 從零開始,構建資料化運營體系資料化運營是一個近年來興起的概念,它在運營的基礎上,提出了以資料驅動決策的口號。 在瞭解資料化運營前,運營們有沒有過如下的問題: 不同渠道,效果究竟是好是壞? 活躍數下降了,到底是因為什麼原因? 這次活動推廣成效如何? 技術乾貨:從零開始,教你設計一個百萬級的訊息推送系統1、點評 本文主要分享的是如何從零設計開發一箇中大型推送系統,因限於篇幅,文中有些鍵技術只能一筆帶過,建議有這方面興趣的讀者可以深入研究相關知識點,從而形成橫向知識體系。 本文適合有一定開發、架構經驗的後端程式設計師閱讀,文內個別技術點可能並非最佳實踐,但至少都是生動的實踐分享,至少能起到拋磚引玉的作用 從零開始,編寫簡單的課程資訊管理系統(使用jsp+servlet+javabean架構)一、相關的軟體下載和環境配置 1、下載並配置JDK。 2、下載eclipse。 3、下載並配置apache-tomcat(伺服器)。 4、下載MySQL(資料庫)。 5、下載Navicat for MySQL(資料庫視覺化工具),方便對資料庫的操作。 6、下載jdbc用來實現eclipse中的專案 從零開始,laydate的常規使用,並且日期最大不能超過當前日期laydate的常規使用,分為兩種方式實現日期元件 一、在 layui 模組中使用 下載layui 地址 :https://www.layui.com/ 引入資源路徑 js 和 css 通過下面這樣載入 <input id="birthDate" name 現代前端開發路線圖:從零開始,一步步成為前端工程師編者按:很多人都想學程式設計。但是苦於沒有具體的步驟和指導。比如想找份前端開發的工作,卻不知道應該先學習什麼再學習什麼,也不知道該選擇什麼樣的工具。因為經常被人問到類似的問題,全棧開發者Kamran Ahmed索性在github上制訂了一份現代前端開發的路線圖,並且用一篇文章 梳理Python基本認識基本型別,從零開始,學習Python先羅列一下Python提供的基本資料型別:數值(整型、浮點型、複數、布林型等)、字串、列表、元組、字典、集合等,將它們簡單分類如下: 推薦下小編的Python學習群;629440234,不管你是小白還是大牛,小編我都歡迎,不定期分享乾貨,包括小編自己整理的一份2018最新的Python和0基礎入 Python+Flask+Gunicorn 專案實戰(一) 從零開始,寫一個Markdown解析器 —— 初體驗(一)前言 在開始學習之前,你需要確保你對Python, JavaScript, HTML, Markdown語法有非常基礎的瞭解。專案的原始碼你可以在 https://github.com/zhu-y/markdown-toolkit 找到,最後的 No.1——從零開始,有始有終本人是一名計算機專業大三的學生,由於前兩年荒廢了大量的時間,到現在為止沒有掌握一門程式語言,最近才意識到時間的緊迫和形勢的嚴峻,現在打算認真的學習一門程式語言,確保能在明年的九月份秋招中拿到一份滿意的offer。關於語言的選擇,經過一番深思熟慮之後我選擇C語言作 從零開始,學習web前端之HTML基礎我在大學的專業是計算機網路技術,大學期間有這樣一門課是“網頁設計與製作”,當時對這門課挺感興趣,就學習了下。通過簡單的html、css和js能展現出自己想要的東西,感覺挺有意思的。 雖然陰差陽錯之下成為了一名Android開發工程師,但是前端方面的知識也一直在 從零開始,通過docker實現mysql 主從複製,主主複製,圖文並茂,保證可以實現!建立docker 容器(可以根據一個映象建立多個容器) docker run -tid 映象ID/usr/sbin/init //centos7版本。使用/usr/sbin/init解決systemctl報錯不能使用的問題docker run -tid 映象ID/bin/bash //非cen |