处理回调 - Amazon Cognito
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

处理回调

如果您是 Amazon Cognito Sync 的新用户,请使用 Amazon AppSync。像 Amazon Cognito Sync 一样,Amazon 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] 解决与全新值的冲突。此方法返回无将阻止同步继续进行,并且下一次同步过程开始时会再次出现冲突。

您可以在客户端层面设置冲突解决方法处理程序:

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] 解决与全新值的冲突。此方法返回无将阻止同步继续进行,并且下一次同步过程开始时会再次出现冲突。

您可以在客户端层面设置冲突解决方法处理程序:

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

打开或创建数据集之后,您可以为其设置不同的回调,以在使用 Synchronize 方法时触发。以下就是将回调注册到数据集的方法:

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

打开或创建数据集之后,您可以为其设置不同的回调,以在使用 Synchronize 方法时触发。以下就是将回调注册到数据集的方法:

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