處理回呼 - Amazon Cognito

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

處理回呼

如果您第一次使用 Amazon Cognito Sync,請改用 AWS AppSync。像 Amazon Cognito Sync 一樣,AWS AppSync 是讓您在裝置間同步應用程式資料的服務。

可同步使用者資料,如應用程式偏好設定或遊戲狀態。也擴充這些功能,允許多個使用者在共用資料上即時同步及協作。

本節說明如何處理回呼。

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()方法指示用戶端軟體開發套件要如何處理本機資料。

@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;

請注意,SyncSuccessSyncFailure 是使用 +=,而不是 =,因此您可以向其訂閱多個回呼。

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;

請注意,SyncSuccessSyncFailure 是使用 +=,而不是 =,因此您可以向其訂閱多個回呼。

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; }