iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
Mobile Development

在 iOS 開發路上的大小事2系列 第 19

【在 iOS 開發路上的大小事2-Day19】Swift Framework 封裝 (基本款)

  • 分享至 

  • xImage
  •  

Xcode 開新專案,選 Framework

輸入 Framework 的名稱

如果是 Xcode 13 以上的話
要先將隱藏的 Products 資料夾開啟,因為待會產生的 Framework 會出現在這裡

Terminal 先切換到專案底下
=> cd 專案路徑
=> open 專案名稱.xcodeproj/pbxproj

找到 productRefGroup (請善用 Command+F,除非你眼力很好)
將 mainGroup 的值複製到 productRefGroup,存檔
神奇的 Products 資料夾就出現了

然後新增 Swift 檔案

輸入檔案名稱

接著在 class 前面加上 public 修飾字,像是下面這樣

// 原本長這樣
class Manager {
    
}
// 加完 public 後長這樣
public class Manager {
    
}

這是因為要封裝成 Framework,所以為了要讓外層檔案可以使用
(也就是要裝這套件的專案)
所以必須要設為 public,如果是要可以 override 或是繼承的話,則是要設為 open

// 原本長這樣
class Manager {
    
}
// 加完 open 後長這樣
open class Manager {
    
}

Swift 的檔案存取層級參考

接著就可以寫我們要的東西了
這邊用換背景色、輸入輸出的 func 做示範

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
如果用前面的範例來改寫的話,像下面這樣

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靜態庫製作與發佈
  2. iOS-SDK开发经验分享
  3. Framework 嵌套与依赖
  4. swift framework中引入第三方的framework或者.a
  5. iOS静态库SDK制作(包含第三方静态库)
  6. iOS開發~製作同時支持armv7,armv7s,arm64,arm64e,i386,x86_64的靜態庫.a
  7. xcode 13新建工程找不到product文件夾
  8. swift封装Framework静态库SDK
  9. 关于Xcode12静态库打包的一些心得
  10. 【iOS】SDK靜態庫的封裝
  11. iOS封装SDK
  12. Creating and Publishing Custom iOS Framework using Cocoapods | Swift 5, XCode 11
  13. How to Create a Swift Framework using Xcode 11
  14. Swift Framework - Create a Custom Framework in iOS

上一篇
【在 iOS 開發路上的大小事2-Day18】Password AutoFill App Extension
下一篇
【在 iOS 開發路上的大小事2-Day20】如何將自己寫的套件上傳到 CocoaPods
系列文
在 iOS 開發路上的大小事230
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
nick55002
iT邦新手 5 級 ‧ 2023-03-14 17:17:34

請問一下,複製一份實機的資料夾,也將模擬機的檔案複製過去了,那原先合併好的「模擬器的 SDK 和 實機的 SDK 的二進制檔案」要放在哪裡呢?後續操作是什麼?

我要留言

立即登入留言