建立混合語言專案的完整步驟,涵蓋 Bridging Header、Generated Header、存取控制映射、私有類型可見性、原始碼查看與常見坑點。
ProductModuleName-Bridging-Header.h → 選擇建立Swift Compiler - General → Objective-C Bridging Header 確認路徑正確Build Settings → Defines Module = YES (模組化必要)| Swift 宣告 | ObjC 可見 | Generated Header 中 | 條件 |
|---|---|---|---|
@objc public class | ✅ | ✅ | 模組公開 + @objc |
@objc class (internal) | ✅ | ✅ | 同模組內預設 internal 也會匯出 |
@objc private class | ❌ | ❌ | private 限定檔案內 |
public class (無 @objc) | ❌ | ❌ | 無 @objc 不匯出 ObjC |
class (internal, 無 @objc) | ❌ | ❌ | 同上 |
private class (無 @objc) | ❌ | ❌ | 檔案私有 |
// 1. Bridging Header 中匯入 ObjC 標頭
#import "MyObjCClass.h"
// 2. Swift 中直接使用 (自動轉換)
let obj = MyObjCClass()
obj.property = 42
obj.methodWithArg(10, completion: { result in ... })
// 3. 對應規則
// ObjC: - (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
// Swift: init(name: String, age: Int)
// ObjC: @property (nonatomic, copy) NSString *name;
// Swift: var name: String
// ObjC: id _Nullable / _Nonnull → Swift: Optional / Non-optional
ProductModuleName-Swift.h 由 Xcode 自動生成,包含:
@objc public / @objc internal 類別介面_TtC (編碼模組+類別名)| 問題 | 原因 | 解決 |
|---|---|---|
| 找不到 Swift 類別 | 未加 @objc 或非 NSObject 子類 | 加 @objc、繼承 NSObject |
| Bridging Header 匯入失敗 | 路徑錯誤、Target Membership 未勾選 | 檢查 Build Settings 路徑、檔案 Target 勾選 |
| Swift 無法存取 ObjC 類別 | 未在 Bridging Header 匯入 | 在 .h 中 #import |
| 循環匯入 | Swift 匯入 ObjC,ObjC 又匯入 Swift Header | 前向宣告 @class、移除不必要匯入 |
| 私有 Swift 類別在 ObjC 可見 | 誤以為 private 等同 ObjC 私有 | Swift private = 檔案私有,用 fileprivate (同模組) 或移除 @objc |
public:模組外可見,但 不可繼承/覆寫 (除非 open)open:模組外可見、可繼承、可覆寫@objc public → ObjC 看到 public 類別Build Libraries for Distribution = YES 穩定 ABIProduct → Perform Action → Preprocess 查看展開後原始碼