@@ -196,6 +196,7 @@ private enum SyncStatus {
196196 case idle
197197 case syncing
198198 case completed
199+ case aborted
199200}
200201
201202/**
@@ -326,12 +327,18 @@ final class iCloudSynchronizer {
326327
327328 - Parameter keys: If the keys parameter is an empty array, the method will use the keys that were added to `Defaults.iCloud`.
328329 - Parameter source: Sync keys from which data source (remote or local).
330+
331+ - Note: The synchronization task might be aborted if both the remote and local data sources do not exist.
329332 */
330333 func syncWithoutWaiting( _ keys: [ Defaults . Keys ] = [ ] , _ source: Defaults . iCloud . DataSource ? = nil ) {
331334 let keys = keys. isEmpty ? Array ( self . keys) : keys
332335
333336 for key in keys {
334- let latest = source ?? latestDataSource ( forKey: key)
337+ // If no data source is specified, we should abort this synchronization task.
338+ guard let latest = source ?? latestDataSource ( forKey: key) else {
339+ Self . logKeySyncStatus ( key, source: nil , syncStatus: . aborted, value: nil )
340+ continue
341+ }
335342 enqueue {
336343 await self . syncKey ( key, source: latest)
337344 }
@@ -483,16 +490,22 @@ final class iCloudSynchronizer {
483490 /**
484491 Determine which data source has the latest data available by comparing the timestamps of the local and remote sources.
485492 */
486- private func latestDataSource( forKey key: Defaults . Keys ) -> Defaults . iCloud . DataSource {
493+ private func latestDataSource( forKey key: Defaults . Keys ) -> Defaults . iCloud . DataSource ? {
494+ let remoteTimestamp = timestamp ( forKey: key, source: . remote)
495+ let localTimestamp = timestamp ( forKey: key, source: . local)
496+ return switch ( remoteTimestamp, localTimestamp) {
497+ // If the local timestamp does not exist, use the remote timestamp as the latest data source.
498+ case ( . some( _) , nil ) :
499+ . remote
487500 // If the remote timestamp does not exist, use the local timestamp as the latest data source.
488- guard let remoteTimestamp = timestamp ( forKey: key, source: . remote) else {
489- return . local
501+ case ( nil , . some( _) ) :
502+ . local
503+ case let ( . some( remoteTimestamp) , . some( localTimestamp) ) :
504+ localTimestamp > remoteTimestamp ? . local : . remote
505+ // If both remote and local timestamp does not exist, return nil
506+ case ( nil , nil ) :
507+ nil
490508 }
491- guard let localTimestamp = timestamp ( forKey: key, source: . local) else {
492- return . remote
493- }
494-
495- return localTimestamp > remoteTimestamp ? . local : . remote
496509 }
497510}
498511
@@ -575,7 +588,7 @@ extension iCloudSynchronizer {
575588
576589 private static func logKeySyncStatus(
577590 _ key: Defaults . Keys ,
578- source: Defaults . iCloud . DataSource ,
591+ source: Defaults . iCloud . DataSource ? ,
579592 syncStatus: SyncStatus ,
580593 value: Any ? = nil
581594 ) {
@@ -588,6 +601,8 @@ extension iCloudSynchronizer {
588601 " from local "
589602 case . remote:
590603 " from remote "
604+ case . none:
605+ " "
591606 }
592607
593608 let status : String
@@ -600,6 +615,8 @@ extension iCloudSynchronizer {
600615 valueDescription = " with value \( value ?? " nil " ) "
601616 case . completed:
602617 status = " Complete synchronization "
618+ case . aborted:
619+ status = " Aborting "
603620 }
604621
605622 let message = " \( status) key ' \( key. name) ' \( valueDescription) \( destination) "
0 commit comments