|
5 | 5 | import OrderedCollections |
6 | 6 | import OSLog |
7 | 7 | import Observation |
8 | | - import Perception |
9 | 8 | import StructuredQueriesCore |
10 | 9 | import SwiftData |
11 | 10 | import TabularData |
|
38 | 37 | private let observationRegistrar = ObservationRegistrar() |
39 | 38 | private let notificationsObserver = LockIsolated<(any NSObjectProtocol)?>(nil) |
40 | 39 | private let activityCounts = LockIsolated(ActivityCounts()) |
| 40 | + private let startTask = LockIsolated<Task<Void, Never>?>(nil) |
41 | 41 |
|
42 | 42 | /// The error message used when a write occurs to a record for which the current user does not |
43 | 43 | /// have permission. |
|
424 | 424 | } |
425 | 425 | } |
426 | 426 |
|
427 | | - private let _isReady = LockIsolated(false) |
428 | | - private var isReady: Bool { |
429 | | - get { |
430 | | - observationRegistrar.access(self, keyPath: \.isReady) |
431 | | - return _isReady.withValue(\.self) |
432 | | - } |
433 | | - set { |
434 | | - observationRegistrar.withMutation(of: self, keyPath: \.isReady) { |
435 | | - _isReady.withValue { $0 = newValue } |
436 | | - } |
437 | | - } |
438 | | - } |
439 | | - |
440 | 427 | /// Determines if the sync engine is currently running or not. |
441 | 428 | public var isRunning: Bool { |
442 | 429 | observationRegistrar.access(self, keyPath: \.isRunning) |
|
512 | 499 | ) |
513 | 500 | } |
514 | 501 |
|
515 | | - return Task { |
| 502 | + let startTask = Task<Void, Never> { |
516 | 503 | await withErrorReporting(.sqliteDataCloudKitFailure) { |
517 | 504 | guard try await container.accountStatus() == .available |
518 | 505 | else { return } |
|
523 | 510 | ) |
524 | 511 | try await cacheUserTables(recordTypes: currentRecordTypes) |
525 | 512 | } |
526 | | - isReady = true |
527 | 513 | } |
| 514 | + self.startTask.withValue { $0 = startTask } |
| 515 | + return startTask |
528 | 516 | } |
529 | 517 |
|
530 | 518 | /// Fetches pending remote changes from the server. |
|
538 | 526 | public func fetchChanges( |
539 | 527 | _ options: CKSyncEngine.FetchChangesOptions = CKSyncEngine.FetchChangesOptions() |
540 | 528 | ) async throws { |
541 | | - await isReady() |
| 529 | + await startTask.withValue(\.self)?.value |
542 | 530 | let (privateSyncEngine, sharedSyncEngine) = syncEngines.withValue { |
543 | 531 | ($0.private, $0.shared) |
544 | 532 | } |
|
560 | 548 | public func sendChanges( |
561 | 549 | _ options: CKSyncEngine.SendChangesOptions = CKSyncEngine.SendChangesOptions() |
562 | 550 | ) async throws { |
563 | | - await isReady() |
| 551 | + await startTask.withValue(\.self)?.value |
564 | 552 | let (privateSyncEngine, sharedSyncEngine) = syncEngines.withValue { |
565 | 553 | ($0.private, $0.shared) |
566 | 554 | } |
|
571 | 559 | _ = try await (`private`, shared) |
572 | 560 | } |
573 | 561 |
|
574 | | - private func isReady() async { |
575 | | - guard !isRunning else { return } |
576 | | - _ = await Perceptions { self.isReady }.first(where: { $0 }) |
577 | | - } |
578 | | - |
579 | 562 | /// Synchronizes local and remote pending changes. |
580 | 563 | /// |
581 | 564 | /// Use this method to ensure the sync engine immediately fetches all pending remote changes |
|
0 commit comments