mirror of
https://github.com/yattee/yattee.git
synced 2026-07-21 06:42:01 +00:00
Run CloudKit record mapping on the main actor to fix SwiftData race
CloudKitRecordMapper was a standalone actor, so 'await recordMapper.toCKRecord' from the @MainActor sync engine hopped off the main actor and read live SwiftData @Model properties (e.g. LocalPlaylistItem.authorName) from the wrong executor. SwiftData models are bound to the main ModelContext and are not thread-safe, so this raced the backing store and crashed with EXC_BAD_ACCESS. Make the mapper @MainActor (it must touch main-isolated models regardless) and drop the now-redundant awaits. Fixes the crash for all synced model types. Fixes an EXC_BAD_ACCESS seen in TestFlight build 261.
This commit is contained in:
@@ -9,7 +9,15 @@ import CloudKit
|
||||
import Foundation
|
||||
|
||||
/// Maps SwiftData models to CloudKit records and vice versa.
|
||||
actor CloudKitRecordMapper {
|
||||
///
|
||||
/// This MUST be `@MainActor`: the `toCKRecord(...)` methods read live SwiftData
|
||||
/// `@Model` properties (e.g. `LocalPlaylistItem.authorName`) and the `to<Model>`
|
||||
/// methods create/insert models. SwiftData models are bound to the main
|
||||
/// `ModelContext` and are not thread-safe — when this was a standalone `actor`,
|
||||
/// `await recordMapper.toCKRecord(...)` hopped off the main actor and read the
|
||||
/// backing store from the wrong executor, causing EXC_BAD_ACCESS crashes.
|
||||
@MainActor
|
||||
final class CloudKitRecordMapper {
|
||||
private let zone: CKRecordZone
|
||||
|
||||
/// Current schema version for CloudKit records.
|
||||
|
||||
Reference in New Issue
Block a user