###### tags: `第14屆IT邦鐵人賽文章` # 【在 iOS 開發路上的大小事2-Day19】Swift Framework 封裝 (基本款) Xcode 開新專案,選 Framework  輸入 Framework 的名稱  如果是 Xcode 13 以上的話 要先將隱藏的 Products 資料夾開啟,因為待會產生的 Framework 會出現在這裡 ``` Terminal 先切換到專案底下 => cd 專案路徑 => open 專案名稱.xcodeproj/pbxproj 找到 productRefGroup (請善用 Command+F,除非你眼力很好) 將 mainGroup 的值複製到 productRefGroup,存檔 神奇的 Products 資料夾就出現了 ``` 然後新增 Swift 檔案  輸入檔案名稱  接著在 class 前面加上 **public** 修飾字,像是下面這樣 ```swift // 原本長這樣 class Manager { } // 加完 public 後長這樣 public class Manager { } ``` 這是因為要封裝成 Framework,所以為了要讓外層檔案可以使用 (也就是要裝這套件的專案) 所以必須要設為 **public**,如果是要可以 override 或是繼承的話,則是要設為 **open** ```swift // 原本長這樣 class Manager { } // 加完 open 後長這樣 open class Manager { } ``` [Swift 的檔案存取層級參考](https://medium.com/@wuufone/swift-%E7%9A%84%E5%AD%98%E5%8F%96%E6%8E%A7%E5%88%B6%E6%A9%9F%E5%88%B6-access-control-e9f89bb73f2b) 接著就可以寫我們要的東西了 這邊用換背景色、輸入輸出的 func 做示範 ```swift import Foundation import UIKit public class Manager { /// 更換 ViewController 的背景色 /// - Parameters: /// - vc: UIViewController,放你想要改變的 UIViewController /// - color: UIColor,放你想要更換的顏色 public func changeVCBackgroundColor(vc: UIViewController, color: UIColor) { vc.view.backgroundColor = color } /// 你輸入什麼,我輸出什麼 /// - Parameters: /// - text: String?,輸入字串 public func inputAndOutPut(text: String?) { print("You Input: \(text), and I Output: \(text)") } } ``` 然後切到 專案名稱.xcodeproj 檔案 * 修改 SDK 最低支援的版本 (紅框處) ``` TARGETS → Framework 名稱 → General → Deployment Info → Deployment Target ```  * 修改 SDK 支援的裝置 (紅框處裡面的藍色那條) ``` TARGETS → Framework 名稱 → Build Settings → Architectures → Build Active Architecture Only 將 Debug 改成 Yes,是為了讓編譯當下,只編譯所選的裝置,而不是編譯所有的裝置,可以加快編譯效率 將 Release 改成 No,是為了讓每個裝置都可以用,而不會受限於只有編譯的那個裝置可以用 ```  * 修改 SDK 配置 (紅框處裡面的藍色那兩條) ``` TARGETS → Framework 名稱 → Build Settings → Linking 將 Dead Code Stripping 改成 No,是將對程式不會造成影響的 Code 移除,讓編譯最佳化 將 Mach-O Type 改成 Static Library,因為非官方的 Framework 貌似不能用動態庫 ```  * 添加要暴露出的標頭檔 (Header) ``` TARGETS → Framework 名稱 → Build Phases → Headers Swift 不用做但 Objective-C 要做的事 因為 Swift 在產生 Project 的時候已經預設產生並添加好了 Objective-C 的話,需要將要暴露出來的標頭檔放在 Public 裡面 ```  * 修改 Scheme 裡面的 Build Configuration (紅框處) ``` 裝置旁邊的公事包 (target) → Edit Scheme → Build Configuration 將 Build Configuration 改為 Release ```  如果要讓 Objective-C 的專案可以用的話 要將 class 繼承 NSObject,並且要是 public 跟加上 @objc 如果用前面的範例來改寫的話,像下面這樣 ```swift import Foundation import UIKit @objc public class Manager: NSObject { /// 更換 ViewController 的背景色 /// - Parameters: /// - vc: UIViewController,放你想要改變的 UIViewController /// - color: UIColor,放你想要更換的顏色 @objc public func changeVCBackgroundColor(vc: UIViewController, color: UIColor) { vc.view.backgroundColor = color } /// 你輸入什麼,我輸出什麼 /// - Parameters: /// - text: String?,輸入字串 @objc public func inputAndOutPut(text: String?) { print("You Input: \(text), and I Output: \(text)") } } ``` ## 要注意的事情 **!!模擬器產生的 Framework 跟 實機產生的 Framework 是不能混用的!!** 所以我們要將模擬器跟實機各自產生的 Framework 進行合併,這樣兩者才能通用 ``` 先 Command+B 模擬器的 SDK 再 Command+B 實機的 SDK 打開 Terminal,切到 Framework 所在的資料夾路徑 Tips:點擊 Products 裡面的 Framework,選 Show in Finder (這邊的 Products 指的是 Xcode 專案裡面那個,也就是上面我們叫出來的隱藏資料夾) 這樣就可以開啟 Framework 所在的資料夾 下圖紅框處,就是剛才 Command+B 後的 模擬器的 SDK 和 實機的 SDK Release-iphoneos:實機的 SDK Release-iphonesimulator:模擬器的 SDK ```  ``` 在 Terminal 輸入指令 => cd Framework 所在的資料夾路徑 (也就是 Products) ```  ``` Framework名稱 要自行替換成實際自己設的名稱喔!!! 以下圖來說,Framework名稱 就是 SDK_Demo => lipo -create Release-iphoneos/Framework名稱.framework/Framework名稱 Release-iphonesimulator/Framework名稱.framework/Framework名稱 -output Framework名稱 這邊我不使用腳本的原因是因為每次用腳本合併,總是無法讓模擬器跟實機都可以用 ```  ``` 輸入完上面的指令後,這樣就將 模擬器的 SDK 和 實機的 SDK 的二進制檔案合併完成了 下圖的紅框處就是合併後的二進制檔案 ```  ``` 要如何驗證有沒有合併成功的話,可以在 Terminal 輸入下面的指令 Framework名稱 要自行替換成實際自己設的名稱喔!!! 以下圖來說,Framework名稱 就是 SDK_Demo => lipo -info Framework名稱 看到下面這行的話就算合併成功了 「Architectures in the fat file: Framework名稱 are: x86_64 arm64」 ```  ``` 接著複製一份實機的資料夾,並將他改名,名稱的話隨意~ 但為了要方便找的話,取名為「Release-iphoneUniversal」會比較好一點 像是下圖紅框處這樣 ```  ``` 然後將模擬器 SDK 裡面的 Modules/Framework名稱.swiftmodule 的 四個檔案跟 Project 資料夾裡面的兩個檔案 個別複製到 「Release-iphoneUniversal/Framework名稱.framework/Modules/Framework名稱.swiftmodule」 裡面對應的資料夾內 複製完成後,會長的像下圖一樣 Framework名稱.swiftmodule 資料夾裡面: 副檔名為 .swiftdoc 會有四個 (arm64、x86_64 各兩個) 副檔名為 .swiftmodule 會有四個 (arm64、x86_64 各兩個) Framework名稱.swiftmodule/Project 資料夾裡面: 副檔名為 .swiftsourceinfo 會有四個 (arm64、x86_64 各兩個) ```  這樣就算完成 Swift Framework 封裝了 ## 補充 如果是 Apple Silicon 的 Mac 要用的話 要在使用 SDK 的專案改用 My Mac (Design with iPad) 或是接手機來燒,**不能用模擬器燒**!! 因為 Xcode 的模擬器似乎是 x86_64 架構的 ## 參考資料 (來自各路大神,讚嘆大神~) > 1. [iOS Swift Framework靜態庫製作與發佈](https://www.twblogs.net/a/5db39dbfbd9eee310da05b46) > 2. [iOS-SDK开发经验分享](https://www.jianshu.com/p/cbb1f54b89d2) > 3. [Framework 嵌套与依赖](https://www.jianshu.com/p/b03d617917d6) > 4. [swift framework中引入第三方的framework或者.a](https://www.jianshu.com/p/1eaa63388594) > 5. [iOS静态库SDK制作(包含第三方静态库)](https://juejin.cn/post/6844903521465139214) > 6. [iOS開發~製作同時支持armv7,armv7s,arm64,arm64e,i386,x86_64的靜態庫.a](https://www.twblogs.net/a/5c67a9f8bd9eee01cc9e1133) > 7. [xcode 13新建工程找不到product文件夾](https://juejin.cn/post/7036384854782509063) > 8. [swift封装Framework静态库SDK](https://michaellynx.github.io/swift-with-static-library-framework/) > 9. [关于Xcode12静态库打包的一些心得](https://www.cnblogs.com/wgb1234/p/14258036.html) > 10. [【iOS】SDK靜態庫的封裝](https://juejin.cn/post/6844904178762907661) > 11. [iOS封装SDK](https://juejin.cn/post/6844903878094225422) > 12. [Creating and Publishing Custom iOS Framework using Cocoapods | Swift 5, XCode 11](https://youtu.be/vSMmZxmKIA4) > 13. [How to Create a Swift Framework using Xcode 11](https://www.youtube.com/watch?v=iFi1QnKHFnM&t=372s) > 14. [Swift Framework - Create a Custom Framework in iOS](https://youtu.be/oZloIsF1H4g)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.