OC與Swift混編專案遷移到Swift4.2小記
自從 Xcode10
正式版釋出之後, 先吃螃蟹的朋友讚歎了 Dark Mode
的驚豔, 同時也報告說, 打包上傳到 APPStroe
後, 監測到線上 iOS9.3
裝置大面積crash的記錄, 最後被證實是 Xcode10
的問題.
出於此原因考慮, 我便一直在使用 Xcode9.4.1
及 Swift4
進行混編專案的開發.
然而每每使用低版本的 Xcode
打包上傳 APPStore
時, 就會收到蘋果的官方警告郵件

如郵件內容所示, 到 2019
年的 3
月份便不可以再使用低版本 Xcode
進行打包上傳操作了.
於是, 我只好開始了遷移之路.
開始遷移
使用當前 Xcode10.1(10B61)
開啟之後, 在 Build Setting
中搜索 Swift Language Version
, 將對應的值改為 Swift 4.2
,然後開始編譯, 此時會出現非常多的 Error
, 多為 ABI
的變動, 根據提示進行修改即可.
AVAudioSession的更改
然而有一處例外:
當專案中通過 Swift
使用了 AVAudioSession setCategory
這個方法時, 會被告知方法在 Swift
中不可用.跳轉才發現 API
已經變化成了
/* set session category and mode with options */ @available(iOS 10.0, *) open func setCategory(_ category: AVAudioSession.Category, mode: AVAudioSession.Mode, options: AVAudioSession.CategoryOptions = []) throws 複製程式碼
為了相容低版本, 思來想去, 比較合適的方案就是使用OC編寫一個 AVAudioSession
的分類用來橋接:
// AVAudioSession+Swift.h: @import AVFoundation; NS_ASSUME_NONNULL_BEGIN @interface AVAudioSession (Swift) - (BOOL)swift_setCategory:(AVAudioSessionCategory)category error:(NSError **)outError NS_SWIFT_NAME(setCategory(_:)); - (BOOL)swift_setCategory:(AVAudioSessionCategory)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError NS_SWIFT_NAME(setCategory(_:options:)); @end NS_ASSUME_NONNULL_END // AVAudioSession+Swift.m: #import "AVAudioSession+Swift.h" @implementation AVAudioSession (Swift) - (BOOL)swift_setCategory:(AVAudioSessionCategory)category error:(NSError **)outError { return [self setCategory:category error:outError]; } - (BOOL)swift_setCategory:(AVAudioSessionCategory)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError { return [self setCategory:category withOptions:options error:outError]; } @end 複製程式碼
然後在你專案的 <#target_name#>-Bridging-Header.h
中 import
這個分類:
#import "AVAudioSession+Swift.h" 複製程式碼
然後就可以像之前一樣呼叫了.
try AVAudioSession.sharedInstance().setCategory(.playback) 複製程式碼
While deserializing SIL vtable for 'Class' in module 'module' error: Abort trap: 6
這類問題分兩種, 一種是 module
是其他的 target
, 如 Pods
中的, 另一種是 module
是自己的建立的 target
.
第一種
第一種 只需要將 Error
所指向的三方庫更新到最新版本即可, Xcode10
已經發布了快半年了, 這些問題之前也有, 半年的時間, 基本上流行的三方庫都已經適配了 Swift4.2
第二種
而第二種比較棘手, 一般都是由於 Error
中的 Class
所指向的類, 自己是 Swift
類, 但是卻繼承自 Object-C
宣告編寫的類. 我在自己試過一些微調之後發現於事無補, 所以只好將出錯的類使用 Object-C
重寫, 然後在橋接檔案中引入, 好在報錯的不多, 沒用費太多力氣.
其他奇怪的錯誤
遷移完成後 專案跑起來時, 還會出現很多奇怪的問題. 比如呼叫了某個方法A 會報 unrecognize selector *
, 以及莫名的 函式呼叫
, 如:

(setupNavibar函式中並沒用呼叫任何初始化建構函式)
這類錯誤, 一般跟以上的倆種問題是一個本質, 需要自己仔細區別, 然後做出相應更新/更改即可.
除開以上的問題, 專案編譯時還會在 Pods
引用的第三方的類中報ABI需要修改的 Error
, 這時, 只需要找到隊形的 Target
, 在其 Build Settings
中修改 Swift Language Version
為其對應版本即可.