今年はSwift6対応もしたのでその内容を記載
・最初に
SWIFT_STRICT_CONCURRENCY = complete
SWIFT_VERSION = 6.0
Combineをasync/awaitに置き換える
・関数の書き換え
関数の戻り値でFutureで返却されているものをasync-awaitに置き換える
func aaa() async throws -> HogeHoge {
}
以下で呼び出しができる
// 呼び出し側 try await aaa()
非同期処理を呼ぶときにはTaskで呼び出す必要がある。
Task {
try await aaa()
}
メインスレッドで非同期処理を呼び出したい
Task { @MainActor in
try await aaa()
}
・Combineのままで行くなら
Combineのままで行くならwithCheckedThrowingContinuationでラップするのが良いと思います。
ただ、これは一時凌ぎだから辞めれるならasync-awaitに書き換えたほうが良いです
https://blog.personal-factory.com/2022/01/23/how-to-use-async-await-since-swift5_5/
MainActor
・MainActorを付与する
メインスレッドで動くものについて付与する
objective-cがある都合でdelegate使ってるのでprotocolについて付与する
@MainActor
@objc protocol AAADelegate {
}
・ViewModelのクラスに付与する
viewの仲間なのでメインスレッド
@MainActor
class AAAViewModel {
}
Sendable
・DataStoreとprotocolにSendableを付与する
データを取るだけなので基本的にはSendable付与で問題ない見込み
final class HogeHogeDataStore: HogeHogeProtocol, Sendable {
}
protocol HogeHogeProtocol: Sendable {
}
@preconcurrency
・@preconcurrencyをobjective-cのprotocolに付与する
warningが残ってしまうけど一旦諦める
objective-cについては付与するしかないと思う
@preconcurrency
@objc protocol HogeHogeDelegate {
}
Alamofire
・コールバックからasync-awaitに置き換える
//old
AFManager.request(url, method: .get).responseData(completionHandler: { response in
})
//new
let data = try await AFManager
.request(url)
.serializingData()
.value
エラー対応
・Cannot convert return expression of type ‘AnyPublisher<hogehoge, any Error>’ to return type ‘Future<hogehoge, any Error>’
FutureをAnyPublisherにすれば直る。
ただ、async-awaitにしたほうが良いと思う
・Call to actor-isolated instance method ‘configure’ in a synchronous main actor-isolated context
呼び出し側をasync-awaitにして呼ぶ
関連記事:
- iOS 15 Programming Fundamentals with SwiftのI-5とI-6を読んだので不明点をまとめる
- SwiftからObjective-cを呼んだときに循環参照になった場合の解決策
- RxSwiftからCombineに乗り換えた