我使用Azure Mobile Service作为iOS应用程序的后端。我设置了所有可以使用离线同步的功能,即使没有网络连接,也可以查看,添加或修改数据。我在表中添加新对象时遇到了问题。添加在本地运行良好,但是当我同步数据时,它在本地数据库上创建一个重复的项目,具有稍微不同的objectId。创建的项目不会在服务器端重复。
这是我的设置方式。顺便说一下,感谢@TheBasicMind发布这个模型。
以下是他对模型的解释的链接:enter link description here
以下是我设置同步上下文和同步表的方法:
// Initialize the Mobile Service client with your URL and key
MSClient *client = self.hpc.client;
NSManagedObjectContext *context = self.hpc.syncContext;
MSCoreDataStore *store = [[MSCoreDataStore alloc] initWithManagedObjectContext:context];
client.syncContext = [[MSSyncContext alloc] initWithDelegate:syncDelegate dataSource:store callback:nil];
// Add a Mobile Service filter to enable the busy indicator
self.client = [client clientWithFilter:self];
// Create an MSSyncTable instance to allow us to work with the Athlete table
self.syncAthleteTable = [self.client syncTableWithName:@"Athlete"];
以下是我暂时添加记录的方法:
NSDictionary *newItem = @{@"firstname": firstname, @"lastname": lastname, @"laterality" : laterality};
[self.athletesService addItem:newItem completion:^{
NSLog(@"New athlete added");
}];
-(void)addItem:(NSDictionary *)item completion:(CompletionBlock)completion
{
// Insert the item into the Athlete table
[self.syncAthleteTable insert:item completion:^(NSDictionary *result, NSError *error)
{
[self logErrorIfNotNil:error];
// Let the caller know that we finished
dispatch_async(dispatch_get_main_queue(), ^{
completion();
});
}];
}
添加按预期工作,它被添加到UITableView中,因为我有一个NSFetchedResultsController监听我的主上下文。
此处出现问题。当我使用此功能与服务器同步数据时:
-(void)syncData:(CompletionBlock)completion
{
// push all changes in the sync context, then pull new data
[self.client.syncContext pushWithCompletion:^(NSError *error) {
[self logErrorIfNotNil:error];
[self pullData:completion];
}];
}
-(void)pullData:(CompletionBlock)completion
{
MSQuery *query = [self.syncAthleteTable query];
// Pulls data from the remote server into the local table.
// We're pulling all items and filtering in the view
// query ID is used for incremental sync
[self.syncAthleteTable pullWithQuery:query queryId:@"allAthletes" completion:^(NSError *error) {
[self logErrorIfNotNil:error];
[self refreshDataOnSuccess:completion];
}];
}
- (void) refreshDataOnSuccess:(CompletionBlock)completion
{
MSQuery *query = [self.syncAthleteTable query];
[query readWithCompletion:^(MSQueryResult *results, NSError *error) {
[self logErrorIfNotNil:error];
NSLog(@"Data that pulled from local store: ");
for ( NSDictionary *dict in results.items ) {
NSLog(@"%@ %@", [dict objectForKey:@"firstname"], [dict objectForKey:@"lastname"] );
}
// Let the caller know that we finished
dispatch_async(dispatch_get_main_queue(), ^{
completion();
});
}];
}
在同步之后,对于具有略微不同的objectID的相同记录,第二次调用NSFetchedResultsChangeInsert。这是第一个和第二个objectID的示例:
tD7ADE77E-0ED0-4055-BAF6-B6CF8A6960AE9
tD7ADE77E-0ED0-4055-BAF6-B6CF8A6960AE11
我被困在这里。
非常感谢任何帮助。谢谢!
答案 0 :(得分:2)
在过去,当我看到这种情况发生时,因为" id"服务器逻辑正在更改或忽略客户端正在发送的字段。
本地商店使用该字段在核心数据中找到对象,因此对其进行更改可能会导致客户端SDK认为需要插入新对象而不更新现有对象。
确认这一点的一种简单方法是在数据委托上使用tableOperation:complete:方法并比较" id"最初项目与操作执行返回的列之间的列。