OC與Swift混編項目遷移到Swift4.2小記

前言

自從Xcode10正式版發佈以後, 先吃螃蟹的朋友讚歎了Dark Mode的驚豔, 同時也報告說, 打包上傳到APPStroe後, 監測到線上 iOS9.3設備大面積crash的記錄, 最後被證明是Xcode10的問題.swift

出於此緣由考慮, 我便一直在使用Xcode9.4.1Swift4進行混編項目的開發.session

然而往往使用低版本的Xcode打包上傳APPStore時, 就會收到蘋果的官方警告郵件 函數

如郵件內容所示, 到2019年的3月份便不能夠再使用低版本Xcode進行打包上傳操做了.ui

因而, 我只好開始了遷移之路.spa

開始遷移

使用當前 Xcode10.1(10B61)打開以後, 在Build Setting中搜索 Swift Language Version, 將對應的值改成Swift 4.2,而後開始編譯, 此時會出現很是多的Error, 多爲ABI的變更, 根據提示進行修改便可.code

AVAudioSession的更改

然而有一處例外:
當項目中經過Swift使用了 AVAudioSession setCategory這個方法時, 會被告知方法在Swift中不可用.跳轉才發現 API已經變化成了cdn

/* 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的分類用來橋接:blog

// 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.himport這個分類:繼承

#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類, 可是卻繼承自Objective-C聲明編寫的類. 我在本身試過一些微調以後發現於事無補, 因此只好將出錯的類使用Objective-C重寫, 而後在橋接文件中引入, 好在報錯的很少, 沒用費太多力氣.

其餘奇怪的錯誤

遷移完成後 項目跑起來時, 還會出現不少奇怪的問題. 好比調用了某個方法A 會報unrecognize selector *, 以及莫名的函數調用, 如:

(setupNavibar函數中並沒用調用任何初始化構造函數)
這類錯誤, 通常跟以上的倆種問題是一個本質, 須要本身仔細區別, 而後作出相應更新/更改便可.

除開以上的問題, 項目編譯時還會在Pods引用的第三方的類中報ABI須要修改的Error, 這時, 只須要找到隊形的Target, 在其Build Settings中修改 Swift Language Version爲其對應版本便可.

最後, 但願未來適配Swift5時, 不要有這麼多坑了...

相關文章
相關標籤/搜索