iOS Framework & CocoaPods 心得上架分享

公司計畫開發一套 iOS SDK 供合作廠商使用,需求如下

  • 程式碼必須隱藏
  • 上架到 CocoaPods

對我來說這是一段很難得的經驗,以一般的 iOS 獨立開發者來說,實務上很難有機會涉獵到這塊,同時在研究的過程中,也讓我更進一步了解 xcode 的環境設定,所以把這段研究歷程及心得記錄下來,並分享給有興趣的朋友們。

研究環境

  • Xcode:7.2.1
  • Swift 2.2.1

程式碼必須隱藏

由於牽涉到公司商業機密的部分,像是連線的 host、port、帳號密碼以及業務邏輯的部分,公司希望 SDK 能以黑箱的方式呈現,簡單來說就是編譯過的 Object Code。

想當然爾,一開始就來看看 xcode 有沒有包裝 library 的工具,打開 File->New->Project->iOS->Framework & Library,

我們可以看到 xcode 提供兩種類型的 Library 專案

螢幕快照 2016-05-31 下午5.05.45

OK,到這裡問題來了,這兩者有何不同?我應該使用哪一個才是最好?

用動態庫還是靜態庫?

在此之前,得先了解一下什麼是靜態庫與動態庫

靜態庫

靜態庫即靜態鏈接庫(Windows 下的.lib,Linux 和Mac 下的.a)。之所以叫做靜態,是因為靜態庫在編譯的時候會被直接拷貝一份,複製到目標程序裡,這段代碼在目標程序裡就不會再改變了。

靜態庫的好處很明顯,編譯完成之後,庫文件實際上就沒有作用了。目標程序沒有外部依賴,直接就可以運行。當然其缺點也很明顯,就是會使用目標程序的體積增大。

動態庫

動態庫即動態鏈接庫(Windows 下的.dll,Linux 下的.so,Mac 下的.dylib/.tbd)。與靜態庫相反,動態庫在編譯時並不會被拷貝到目標程序中,目標程序中只會存儲指向動態庫的引用。等到程序運行時,動態庫才會被真正加載進來。

參考網頁: iOS 靜態庫,動態庫與Framework

其實 Cocoa Touch Framework / Cocoa Touch Library 的區別就是,這兩者分別為動態庫和靜態庫。到目前為止還沒辦法判斷用哪個最好。

用 Swift 還是 Objevtive-C?

一開始非常強烈希望使用 Swift 來開發,因為 Swift 實在太好寫了,欲罷不能啦哈哈,不過在做更進一步設定後,會發現 Cocoa Touch Library 並沒有 Swift 的選項,只能強制用 Objective-C。

根據 Apple 的官方解釋,這是因為 Swift 版本還在不斷持續更新的關係,每一版相依的 Runtime 不一定會相同,而靜態庫會將 Runtime 給包進來,如果說 SDK 用的是 Swift 1.0,而客戶用 Swift 2.0 在開發,這將會造成 Runtime 有多重版本的問題,所以暫不支援。換句話說,等到 Swift 穩定了這問題就解決啦,只是不知道要等到什麼時候就是了。

Apple官方論壇:https://github.com/ksm/SwiftInFlux#static-libraries

指令集

模擬器和實體裝置的指令集是不同的,前者通常是x86,而後者是ARM系列
參考網頁:iOS armv7,armv7s, arm64

SDK 要可讓別人使用,在編譯時必須把會用到的指令集都編成 Object code,可惜的是 Xcode Library 並不會幫我們作這件事,我們得利用 Shell script 及 Aggregate 來完成。

Cocoa Touch Framework
http://stackoverflow.com/questions/24039470/xcode-6-ios-creating-a-cocoa-touch-framework-architectures-issues/26691080#26691080

Cocoa Touch Library
https://www.raywenderlich.com/65964/create-a-framework-for-ios

兩者都可以編成一套完整的指令集,但是根據 Apple 論壇,若某 App 使用的 Cocoa Touch Framework 有包含模擬器指令集,上架時將會被退回,而 Cocoa Touch Library 則沒有這個爭議。
Apple官方論壇:https://forums.developer.apple.com/thread/21496

上架到 CocoaPods

這是最理想的狀態,透過將 SDK 上架到 CocoaPods,全球的廠商都可下載來使用

在此之前,必須準備一份 podspec 供上架使用,一開始我是直接參考 GoogleMaps 的 podspec
https://github.com/CocoaPods/Specs/tree/master/Specs/GoogleMaps

這個網站有更詳細的上架教學
http://yulingtianxia.com/blog/2014/05/26/publish-your-pods-on-cocoapods-with-trunk/

目前嘗試的結果,Cocoa Touch Framework 所編譯出來的 Framework 無法直接被使用,可能是 CocoaPods 還不支援,又或者是需要更複雜的設定,總之由於時程的關係我到這邊就打住了,如果有熟知這塊的朋友請不吝與我分享。

另外一點補充,pod 可以先用 link 到 local 的方式開發,待功能穩定後再推上去,這會節省不少時間,畢竟上架是很麻煩的。
在 Podfile 的寫法如下:
pod ‘xxxSDK’, :path => ‘/Users/{yourName}/Desktop/xxxSDK/xxxSDK.podspec’

從 Cocoapods 下載後可以發現使用者是看不到 .m檔的,這就達到程式黑箱的目的了,如果想要進一步隱藏 .h檔,可以到 Build Phases -> 左上角的+ -> New Header Phases 新增一個 Headers 設定,再把想要隱藏的 .h檔放到 Private 或 Protect 即可。

螢幕快照 2016-05-31 下午5.07.57

綜上所述,可以很清楚的判斷使用 Cocoa Touch Library & Objective-C 是目前唯一解,雖然 Swift 很好用也只好忍痛捨棄,以上就是我的研究心得和分享,歡迎大家與我討論或給予建議,謝謝。

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *