本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
處理事件回呼
如果您第一次使用 Amazon Cognito Sync,請改用 AWS AppSync
可同步使用者資料,如應用程式偏好設定或遊戲狀態。也擴充這些功能,允許多個使用者在共用資料上即時同步及協作。
身為 Amazon Cognito Sync 開發人員,您可以實作各種回呼來處理不同的同步事件和案例。Android 中的SyncCallback
介面會SDK設定有關資料集同步的通知,包括onSuccess()
何時成功下載資料集、onFailure()
何時發生例外狀況,以及onConflict()
解決本機與遠端資料之間的衝突。
在 iOS 中SDK,您可以註冊類似通知,例如 AWSCognitoDidStartSynchronizeNotification
並設定處理常式,例如 AWSCognitoRecordConflictHandler
以解決衝突。 JavaScript、Unity 和 Xamarin 平台具有類似的回呼機制。當您實作這些回呼時,您的應用程式可以優雅地處理使用 Amazon Cognito Sync 時可能發生的各種同步事件和案例。
Android
SyncCallback 介面
藉由實作 SyncCallback
界面,您可以在您的應用程式上接收資料集同步的相關通知。然後,您的應用程式可以主動決定是否要刪除本機資料、合併未驗證和已驗證的設定檔,以及解決同步衝突。您應該實作界面所需的下列方法:
-
onSuccess()
-
onFailure()
-
onConflict()
-
onDatasetDeleted()
-
onDatasetsMerged()
請注意,如果您不想指定所有回呼,您也可以使用 DefaultSyncCallback
類別,它會為所有回呼提供預設的空實作。
onSuccess
從同步存放區成功下載資料集後,就會觸發 onSuccess()
回呼。
@Override public void onSuccess(Dataset dataset, List<Record> newRecords) { }
onFailure
onFailure如果在同步期間發生例外狀況,則會呼叫 ()。
@Override public void onFailure(DataStorageException dse) { }
onConflict
如果在本機存放區和同步存放區中修改相同的索引鍵,可能會發生衝突。onConflict()
方法會處理衝突解決方案。如果您不實作此方法,Amazon Cognito Sync 用戶端預設會使用最新的變更。
@Override public boolean onConflict(Dataset dataset, final List<SyncConflict> conflicts) { List<Record> resolvedRecords = new ArrayList<Record>(); for (SyncConflict conflict : conflicts) { /* resolved by taking remote records */ resolvedRecords.add(conflict.resolveWithRemoteRecord()); /* alternately take the local records */ // resolvedRecords.add(conflict.resolveWithLocalRecord()); /* or customer logic, say concatenate strings */ // String newValue = conflict.getRemoteRecord().getValue() // + conflict.getLocalRecord().getValue(); // resolvedRecords.add(conflict.resolveWithValue(newValue); } dataset.resolve(resolvedRecords); // return true so that synchronize() is retried after conflicts are resolved return true; }
onDatasetDeleted
刪除資料集後,Amazon Cognito 用戶端會使用 SyncCallback
界面來確認本機快取的資料集副本是否也要刪除。實作 onDatasetDeleted()
方法,告訴用戶端SDK如何處理本機資料。
@Override public boolean onDatasetDeleted(Dataset dataset, String datasetName) { // return true to delete the local copy of the dataset return true; }
onDatasetMerged
當先前未連接的兩個身分連結在一起時,其所有資料集都會合併。此時會透過 onDatasetsMerged()
方法來通知應用程式該合併狀況:
@Override public boolean onDatasetsMerged(Dataset dataset, List<String> datasetNames) { // return false to handle Dataset merge outside the synchronization callback return false; }
iOS - Objective-C
同步通知
Amazon Cognito 用戶端會在同步呼叫期間發出多個 NSNotification
事件。您可以註冊,以透過標準 NSNotificationCenter
來監控這些通知:
[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myNotificationHandler:) name:NOTIFICATION_TYPE object:nil];
Amazon Cognito 支援五種通知類型,列示如下。
AWSCognitoDidStartSynchronizeNotification
當同步操作開始時呼叫。userInfo
會包含索引鍵資料集,也就是正在同步之資料集的名稱。
AWSCognitoDidEndSynchronizeNotification
當同步操作完成時呼叫 (成功或其他)。userInfo
會包含索引鍵資料集,也就是正在同步之資料集的名稱。
AWSCognitoDidFailToSynchronizeNotification
當同步操作失敗時呼叫。userInfo
會包含索引鍵資料集 (也就是正在同步之資料集的名稱),以及索引鍵錯誤 (其中包含導致失敗的錯誤)。
AWSCognitoDidChangeRemoteValueNotification
當本機變更成功推播到 Amazon Cognito 時呼叫。userInfo
將包含金鑰資料集,也就是要同步的資料集名稱,以及將包含已推送之記錄金鑰NSArray的金鑰。
AWSCognitoDidChangeLocalValueFromRemoteNotification
因為同步操作而導致本機值變更時呼叫。userInfo
將包含金鑰資料集,也就是要同步的資料集名稱,以及包含變更之記錄金鑰NSArray的金鑰。
衝突解決處理常式
在同步操作期間,如果在本機存放區和同步存放區中修改相同的索引鍵,可能會發生衝突。如果您尚未設定衝突解決處理常式,Amazon Cognito 預設會選擇最新的更新。
透過實作和指派 AWSCognitoRecordConflictHandler ,您可以變更預設衝突解決方法。 AWSCognitoConflict 輸入參數衝突包含本機快取資料和同步存放區中衝突記錄的 AWSCognitoRecord 物件。使用 AWSCognitoConflict 可以解決與本機記錄的衝突:【conflict resolveWithLocalRecord】、遠端記錄:【conflict resolveWithRemoteRecord】 或全新的值:【conflict resolveWithValue:value】。從這個方法傳回 nil 會阻止同步繼續進行,而且下次同步程序開始時,還會再出現衝突。
您可以在用戶端層級設定衝突解決處理常式:
client.conflictHandler = ^AWSCognitoResolvedConflict* (NSString *datasetName, AWSCognitoConflict *conflict) { // always choose local changes return [conflict resolveWithLocalRecord]; };
或是在資料集層級:
dataset.conflictHandler = ^AWSCognitoResolvedConflict* (NSString *datasetName, AWSCognitoConflict *conflict) { // override and always choose remote changes return [conflict resolveWithRemoteRecord]; };
刪除資料集處理常式
刪除資料集後,Amazon Cognito 用戶端會使用 AWSCognitoDatasetDeletedHandler
來確認本機快取的資料集副本是否也應刪除。如果未實作 AWSCognitoDatasetDeletedHandler
,將會自動清除本機資料。如果您希望先保留一份本機資料副本,再進行抹除,或是要保留本機資料,請實作 AWSCognitoDatasetDeletedHandler
。
您可以在用戶端層級設定資料集刪除處理常式:
client.datasetDeletedHandler = ^BOOL (NSString *datasetName) { // make a backup of the data if you choose ... // delete the local data (default behavior) return YES; };
或是在資料集層級:
dataset.datasetDeletedHandler = ^BOOL (NSString *datasetName) { // override default and keep the local data return NO; };
資料集合併處理常式
當先前未連接的兩個身分連結在一起時,其所有資料集都會合併。此時會透過 DatasetMergeHandler
來通知應用程式該合併狀況。處理常式將會收到根資料集的名稱,以及標示為根資料集合併的資料集名稱陣列。
如果未實作 DatasetMergeHandler
,將會忽略這些資料集,但是這些資料集會繼續耗用身分最大總數 20 個資料集中的空間。
您可以在用戶端層級設定資料集合併處理常式:
client.datasetMergedHandler = ^(NSString *datasetName, NSArray *datasets) { // Blindly delete the datasets for (NSString *name in datasets) { AWSCognitoDataset *merged = [[AWSCognito defaultCognito] openOrCreateDataset:name]; [merged clear]; [merged synchronize]; } };
或是在資料集層級:
dataset.datasetMergedHandler = ^(NSString *datasetName, NSArray *datasets) { // Blindly delete the datasets for (NSString *name in datasets) { AWSCognitoDataset *merged = [[AWSCognito defaultCognito] openOrCreateDataset:name]; // do something with the data if it differs from existing dataset ... // now delete it [merged clear]; [merged synchronize]; } };
iOS - Swift
同步通知
Amazon Cognito 用戶端會在同步呼叫期間發出多個 NSNotification
事件。您可以註冊,以透過標準 NSNotificationCenter
來監控這些通知:
NSNotificationCenter.defaultCenter().addObserver(observer: self, selector: "myNotificationHandler", name:NOTIFICATION_TYPE, object:nil)
Amazon Cognito 支援五種通知類型,列示如下。
AWSCognitoDidStartSynchronizeNotification
當同步操作開始時呼叫。userInfo
會包含索引鍵資料集,也就是正在同步之資料集的名稱。
AWSCognitoDidEndSynchronizeNotification
當同步操作完成時呼叫 (成功或其他)。userInfo
會包含索引鍵資料集,也就是正在同步之資料集的名稱。
AWSCognitoDidFailToSynchronizeNotification
當同步操作失敗時呼叫。userInfo
會包含索引鍵資料集 (也就是正在同步之資料集的名稱),以及索引鍵錯誤 (其中包含導致失敗的錯誤)。
AWSCognitoDidChangeRemoteValueNotification
當本機變更成功推播到 Amazon Cognito 時呼叫。userInfo
將包含金鑰資料集,也就是要同步的資料集名稱,以及將包含已推送之記錄金鑰NSArray的金鑰。
AWSCognitoDidChangeLocalValueFromRemoteNotification
因為同步操作而導致本機值變更時呼叫。userInfo
將包含金鑰資料集,也就是要同步的資料集名稱,以及包含變更之記錄金鑰NSArray的金鑰。
衝突解決處理常式
在同步操作期間,如果在本機存放區和同步存放區中修改相同的索引鍵,可能會發生衝突。如果您尚未設定衝突解決處理常式,Amazon Cognito 預設會選擇最新的更新。
您可以實作並指派 AWSCognitoRecordConflictHandler
,以更改預設的衝突解決方案。針對本機快取資料,以及同步存放區中的衝突記錄,AWSCognitoConflict
輸入參數衝突都有包含 AWSCognitoRecord
物件。使用 AWSCognitoConflict
可以解決與本機記錄的衝突:【conflict resolveWithLocalRecord】、遠端記錄:【conflict resolveWithRemoteRecord】 或全新的值:【conflict resolveWithValue:value】。從這個方法傳回 nil 會阻止同步繼續進行,而且下次同步程序開始時,還會再出現衝突。
您可以在用戶端層級設定衝突解決處理常式:
client.conflictHandler = { (datasetName: String?, conflict: AWSCognitoConflict?) -> AWSCognitoResolvedConflict? in return conflict.resolveWithLocalRecord() }
或是在資料集層級:
dataset.conflictHandler = { (datasetName: String?, conflict: AWSCognitoConflict?) -> AWSCognitoResolvedConflict? in return conflict.resolveWithLocalRecord() }
刪除資料集處理常式
刪除資料集後,Amazon Cognito 用戶端會使用 AWSCognitoDatasetDeletedHandler
來確認本機快取的資料集副本是否也應刪除。如果未實作 AWSCognitoDatasetDeletedHandler
,將會自動清除本機資料。如果您希望先保留一份本機資料副本,再進行抹除,或是要保留本機資料,請實作 AWSCognitoDatasetDeletedHandler
。
您可以在用戶端層級設定資料集刪除處理常式:
client.datasetDeletedHandler = { (datasetName: String!) -> Bool in // make a backup of the data if you choose ... // delete the local data (default behaviour) return true }
或是在資料集層級:
dataset.datasetDeletedHandler = { (datasetName: String!) -> Bool in // make a backup of the data if you choose ... // delete the local data (default behaviour) return true }
資料集合併處理常式
當先前未連接的兩個身分連結在一起時,其所有資料集都會合併。此時會透過 DatasetMergeHandler
來通知應用程式該合併狀況。處理常式將會收到根資料集的名稱,以及標示為根資料集合併的資料集名稱陣列。
如果未實作 DatasetMergeHandler
,將會忽略這些資料集,但是這些資料集會繼續耗用身分最大總數 20 個資料集中的空間。
您可以在用戶端層級設定資料集合併處理常式:
client.datasetMergedHandler = { (datasetName: String!, datasets: [AnyObject]!) -> Void in for nameObject in datasets { if let name = nameObject as? String { let merged = AWSCognito.defaultCognito().openOrCreateDataset(name) merged.clear() merged.synchronize() } } }
或是在資料集層級:
dataset.datasetMergedHandler = { (datasetName: String!, datasets: [AnyObject]!) -> Void in for nameObject in datasets { if let name = nameObject as? String { let merged = AWSCognito.defaultCognito().openOrCreateDataset(name) // do something with the data if it differs from existing dataset ... // now delete it merged.clear() merged.synchronize() } } }
JavaScript
同步回呼
在資料集上執行 synchronize() 時,您可以選擇指定回呼來處理下列每個狀態:
dataset.synchronize({ onSuccess: function(dataset, newRecords) { //... }, onFailure: function(err) { //... }, onConflict: function(dataset, conflicts, callback) { //... }, onDatasetDeleted: function(dataset, datasetName, callback) { //... }, onDatasetMerged: function(dataset, datasetNames, callback) { //... } });
onSuccess()
從同步存放區成功更新資料集後,就會觸發 onSuccess()
回呼。如果您不定義回呼,同步成功時將不提示。
onSuccess: function(dataset, newRecords) { console.log('Successfully synchronized ' + newRecords.length + ' new records.'); }
onFailure()
如果在同步期間發生例外狀況,將會呼叫 onFailure()
。如果您不定義回呼,同步失敗時將不提示。
onFailure: function(err) { console.log('Synchronization failed.'); console.log(err); }
onConflict()
如果在本機存放區和同步存放區中修改相同的索引鍵,可能會發生衝突。onConflict()
方法會處理衝突解決方案。如果您不實作此方法,當有衝突時,同步將會中止。
onConflict: function(dataset, conflicts, callback) { var resolved = []; for (var i=0; i<conflicts.length; i++) { // Take remote version. resolved.push(conflicts[i].resolveWithRemoteRecord()); // Or... take local version. // resolved.push(conflicts[i].resolveWithLocalRecord()); // Or... use custom logic. // var newValue = conflicts[i].getRemoteRecord().getValue() + conflicts[i].getLocalRecord().getValue(); // resolved.push(conflicts[i].resovleWithValue(newValue); } dataset.resolve(resolved, function() { return callback(true); }); // Or... callback false to stop the synchronization process. // return callback(false); }
onDatasetDeleted()
刪除資料集後,Amazon Cognito 用戶端會使用 onDatasetDeleted()
回呼來決定本機快取的資料集副本是否也應刪除。依預設,不會刪除該資料集。
onDatasetDeleted: function(dataset, datasetName, callback) { // Return true to delete the local copy of the dataset. // Return false to handle deleted datasets outside the synchronization callback. return callback(true); }
onDatasetMerged()
當先前未連接的兩個身分連結在一起時,其所有資料集都會合併。此時會透過 onDatasetsMerged()
回呼來通知應用程式該合併狀況。
onDatasetMerged: function(dataset, datasetNames, callback) { // Return true to continue the synchronization process. // Return false to handle dataset merges outside the synchronization callback. return callback(false); }
Unity
在您開啟或建立的資料集之後,您可以為其設定當您使用同步方法時所要觸發的不同回呼。這是向其註冊回呼的方式:
dataset.OnSyncSuccess += this.HandleSyncSuccess; dataset.OnSyncFailure += this.HandleSyncFailure; dataset.OnSyncConflict = this.HandleSyncConflict; dataset.OnDatasetMerged = this.HandleDatasetMerged; dataset.OnDatasetDeleted = this.HandleDatasetDeleted;
請注意,SyncSuccess
和 SyncFailure
是使用 +=,而不是 =,因此您可以向其訂閱多個回呼。
OnSyncSuccess
從雲端成功更新資料集後,就會觸發 OnSyncSuccess
回呼。如果您不定義回呼,同步成功時將不提示。
private void HandleSyncSuccess(object sender, SyncSuccessEvent e) { // Continue with your game flow, display the loaded data, etc. }
OnSyncFailure
如果在同步期間發生例外狀況,將會呼叫 OnSyncFailure
。如果您不定義回呼,同步失敗時將不提示。
private void HandleSyncFailure(object sender, SyncFailureEvent e) { Dataset dataset = sender as Dataset; if (dataset.Metadata != null) { Debug.Log("Sync failed for dataset : " + dataset.Metadata.DatasetName); } else { Debug.Log("Sync failed"); } // Handle the error Debug.LogException(e.Exception); }
OnSyncConflict
如果在本機存放區和同步存放區中修改相同的索引鍵,可能會發生衝突。OnSyncConflict
回呼會處理衝突解決方案。如果您不實作此方法,當有衝突時,同步將會中止。
private bool HandleSyncConflict(Dataset dataset, List < SyncConflict > conflicts) { if (dataset.Metadata != null) { Debug.LogWarning("Sync conflict " + dataset.Metadata.DatasetName); } else { Debug.LogWarning("Sync conflict"); } List < Amazon.CognitoSync.SyncManager.Record > resolvedRecords = new List < Amazon.CognitoSync.SyncManager.Record > (); foreach(SyncConflict conflictRecord in conflicts) { // SyncManager provides the following default conflict resolution methods: // ResolveWithRemoteRecord - overwrites the local with remote records // ResolveWithLocalRecord - overwrites the remote with local records // ResolveWithValue - to implement your own logic resolvedRecords.Add(conflictRecord.ResolveWithRemoteRecord()); } // resolves the conflicts in local storage dataset.Resolve(resolvedRecords); // on return true the synchronize operation continues where it left, // returning false cancels the synchronize operation return true; }
OnDatasetDeleted
刪除資料集後,Amazon Cognito 用戶端會使用 OnDatasetDeleted
回呼來決定本機快取的資料集副本是否也應刪除。依預設,不會刪除該資料集。
private bool HandleDatasetDeleted(Dataset dataset) { Debug.Log(dataset.Metadata.DatasetName + " Dataset has been deleted"); // Do clean up if necessary // returning true informs the corresponding dataset can be purged in the local storage and return false retains the local dataset return true; }
OnDatasetMerged
當先前未連接的兩個身分連結在一起時,其所有資料集都會合併。此時會透過 OnDatasetsMerged
回呼來通知應用程式該合併狀況。
public bool HandleDatasetMerged(Dataset localDataset, List<string> mergedDatasetNames) { foreach (string name in mergedDatasetNames) { Dataset mergedDataset = syncManager.OpenOrCreateDataset(name); //Lambda function to delete the dataset after fetching it EventHandler<SyncSuccessEvent> lambda; lambda = (object sender, SyncSuccessEvent e) => { ICollection<string> existingValues = localDataset.GetAll().Values; ICollection<string> newValues = mergedDataset.GetAll().Values; //Implement your merge logic here mergedDataset.Delete(); //Delete the dataset locally mergedDataset.OnSyncSuccess -= lambda; //We don't want this callback to be fired again mergedDataset.OnSyncSuccess += (object s2, SyncSuccessEvent e2) => { localDataset.Synchronize(); //Continue the sync operation that was interrupted by the merge }; mergedDataset.Synchronize(); //Synchronize it as deleted, failing to do so will leave us in an inconsistent state }; mergedDataset.OnSyncSuccess += lambda; mergedDataset.Synchronize(); //Asnchronously fetch the dataset } // returning true allows the Synchronize to continue and false stops it return false; }
Xamarin
在您開啟或建立的資料集之後,您可以為其設定當您使用同步方法時所要觸發的不同回呼。這是向其註冊回呼的方式:
dataset.OnSyncSuccess += this.HandleSyncSuccess; dataset.OnSyncFailure += this.HandleSyncFailure; dataset.OnSyncConflict = this.HandleSyncConflict; dataset.OnDatasetMerged = this.HandleDatasetMerged; dataset.OnDatasetDeleted = this.HandleDatasetDeleted;
請注意,SyncSuccess
和 SyncFailure
是使用 +=,而不是 =,因此您可以向其訂閱多個回呼。
OnSyncSuccess
從雲端成功更新資料集後,就會觸發 OnSyncSuccess
回呼。如果您不定義回呼,同步成功時將不提示。
private void HandleSyncSuccess(object sender, SyncSuccessEventArgs e) { // Continue with your game flow, display the loaded data, etc. }
OnSyncFailure
如果在同步期間發生例外狀況,將會呼叫 OnSyncFailure
。如果您不定義回呼,同步失敗時將不提示。
private void HandleSyncFailure(object sender, SyncFailureEventArgs e) { Dataset dataset = sender as Dataset; if (dataset.Metadata != null) { Console.WriteLine("Sync failed for dataset : " + dataset.Metadata.DatasetName); } else { Console.WriteLine("Sync failed"); } }
OnSyncConflict
如果在本機存放區和同步存放區中修改相同的索引鍵,可能會發生衝突。OnSyncConflict
回呼會處理衝突解決方案。如果您不實作此方法,當有衝突時,同步將會中止。
private bool HandleSyncConflict(Dataset dataset, List < SyncConflict > conflicts) { if (dataset.Metadata != null) { Console.WriteLine("Sync conflict " + dataset.Metadata.DatasetName); } else { Console.WriteLine("Sync conflict"); } List < Amazon.CognitoSync.SyncManager.Record > resolvedRecords = new List < Amazon.CognitoSync.SyncManager.Record > (); foreach(SyncConflict conflictRecord in conflicts) { // SyncManager provides the following default conflict resolution methods: // ResolveWithRemoteRecord - overwrites the local with remote records // ResolveWithLocalRecord - overwrites the remote with local records // ResolveWithValue - to implement your own logic resolvedRecords.Add(conflictRecord.ResolveWithRemoteRecord()); } // resolves the conflicts in local storage dataset.Resolve(resolvedRecords); // on return true the synchronize operation continues where it left, // returning false cancels the synchronize operation return true; }
OnDatasetDeleted
刪除資料集後,Amazon Cognito 用戶端會使用 OnDatasetDeleted
回呼來決定本機快取的資料集副本是否也應刪除。依預設,不會刪除該資料集。
private bool HandleDatasetDeleted(Dataset dataset) { Console.WriteLine(dataset.Metadata.DatasetName + " Dataset has been deleted"); // Do clean up if necessary // returning true informs the corresponding dataset can be purged in the local storage and return false retains the local dataset return true; }
OnDatasetMerged
當先前未連接的兩個身分連結在一起時,其所有資料集都會合併。此時會透過 OnDatasetsMerged
回呼來通知應用程式該合併狀況。
public bool HandleDatasetMerged(Dataset localDataset, List<string> mergedDatasetNames) { foreach (string name in mergedDatasetNames) { Dataset mergedDataset = syncManager.OpenOrCreateDataset(name); //Implement your merge logic here mergedDataset.OnSyncSuccess += lambda; mergedDataset.SynchronizeAsync(); //Asnchronously fetch the dataset } // returning true allows the Synchronize to continue and false stops it return false; }