2017-06-13 4 views
2

JSON配列をアプリケーションに戻すWebサービスから大量のデータを取得しています。コアデータエンティティごとに1つずつ異なる2つのWebサービスを使用していますが、コアデータから楽観的なロックエラーが発生しています。コアデータオプティミスティックロックエラー

エンティティごとにコアデータのロックが行われていませんか?私は同時に2つの異なるエンティティにオブジェクトを挿入できますか?

私のコードは

以下のWebサービス1

+(void)fetchPricelistAll:(int)pricelistId :(int)startAtRow :(int)takeNoOfRows; 
{ 
    if ([NWTillHelper isDebug] == 1) { 
     NSLog(@"WebServices:fetchPriceList:priceListId = %d", pricelistId); 
    } 

    if([[NWTillHelper getUserName] isEqual: @"matt"]) { 
     takeNoOfRows = 100; 
    } 

    NSString *finalURL = [NSString stringWithFormat:@"https://host.domain.com:5443/api/till/tillpricelistv2/%d?StartAtRow=%d&TakeNoOfRows=%d",pricelistId, startAtRow, takeNoOfRows]; 

    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:finalURL] 
           completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 

            if (error != nil) { 
             if ([NWTillHelper isDebug] == 1) { 
              NSLog(@"WebServices:fetchPriceList:Transport error %@", error); 
             } 
            } else { 
             NSHTTPURLResponse *responseHTTP; 
             responseHTTP = (NSHTTPURLResponse *) response; 

             if(responseHTTP.statusCode != 200) { 
              if ([NWTillHelper isDebug] == 1) { 
               NSLog(@"WebServices:fetchPriceList:Server Error %d", (int) responseHTTP.statusCode); 
              } 
             } else { 
              NSArray *priceListObjectArray = [NSJSONSerialization JSONObjectWithData:data 
                              options:0 
                               error:NULL]; 
              if ([NWTillHelper isDebug] == 1) { 
               NSLog(@"WebServices:fetchPriceList:count = %lu", (unsigned long)[priceListObjectArray count]); 
               NSLog(@"WebServices:fetchPriceList:PricelistObjectArray looks like %@",priceListObjectArray); 
              } 

              NSDictionary *priceListObjectDict; 

              //Loop through the array and for each dictionary insert into local DB 
              for (id element in priceListObjectArray){ 
               priceListObjectDict = element; 

               NSString *currencyName = [priceListObjectDict objectForKey:@"currencyName"]; 
               NSString *price = [priceListObjectDict objectForKey:@"price"]; 
               NSString *priceIncTax = [priceListObjectDict objectForKey:@"priceIncTAX"]; 
               NSString *validFrom = [priceListObjectDict objectForKey:@"validFromDate"]; 
               NSString *validTo = [priceListObjectDict objectForKey:@"validToDate"]; 
               NSString *itemId = [priceListObjectDict objectForKey:@"itemID"]; 

               NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 
               [dateFormat setDateFormat:@"YYYY-MM-dd'T'HH:mm:ss"]; 
               NSDate *validToDate = [dateFormat dateFromString:validTo]; 
               NSDate *validFromDate = [dateFormat dateFromString:validFrom]; 

               if([NWTillHelper isDebug] == 1) { 
                NSLog(@"WebServices:fetchPriceList:validToDate: >>>> %@ <<<<", validToDate); 
                NSLog(@"WebServices:fetchPriceList:validFromDate: >>>> %@ <<<<", validFromDate); 
               } 

               // Use Core Data FMD 
               AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate]; 

               NSManagedObjectContext *context = 
               appDelegate.persistentContainer.viewContext; 
               context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy; 

               if([NWTillHelper isDebug] == 1) { 
                NSLog(@"PimItemListView:tableView:context = %@", context); 
               } 

               NSManagedObject *newPrlItem = Nil; 
               newPrlItem = [NSEntityDescription 
                   insertNewObjectForEntityForName:@"PriceList" 
                   inManagedObjectContext:context]; 

               [newPrlItem setValue:itemId forKey:@"itemId"]; 
               [newPrlItem setValue:validToDate forKey:@"validTo"]; 
               [newPrlItem setValue:validFromDate forKey:@"validFrom"]; 
               [newPrlItem setValue:price forKey:@"price"]; 
               [newPrlItem setValue:priceIncTax forKey:@"priceIncTax"]; 
               [newPrlItem setValue:currencyName forKey:@"currencyName"]; 

               NSError *error = Nil; 
               [context save:&error]; 

               if ([NWTillHelper isDebug] == 1) { 
                NSLog(@"WebServices:fetchTillData:ItemId in loop = %@", itemId); 
                NSLog(@"WebServices:fetchTillData:newPrlItem = %@", newPrlItem); 
                NSLog(@"WebServices:fetchTillData:CoreData error = %@", error); 
               } 

               if(error != nil) { 
                // TODO: Useful error message to user 
               } else { 
                NSUserDefaults *tillUserDefaults = [NSUserDefaults standardUserDefaults]; 
                [tillUserDefaults setInteger:1 forKey:@"hasPriceList"]; 
                [tillUserDefaults synchronize]; 
               } 

              } 
             } 
            } 
           }] resume]; 
} 

Webサービス2

+ (void)fetchTillDataAll:(int)tillId :(int)startAtRow :(int)takeNoOfRows { 

    if([[NWTillHelper getUserName] isEqual: @"matt"]) { 
     takeNoOfRows = 100; 
    } 

    if ([NWTillHelper isDebug] == 1) { 
     NSLog(@"WebServices:fetchTillDataAll:tillId = %d, startAtRow = %d, takeNoOfRows = %d", tillId, startAtRow, takeNoOfRows); 
    } 

    NSString *finalURL = [NSString stringWithFormat:@"https://host.domain.com:5443/api/till/tilldatav2/%d?StartAtRow=%d&TakeNoOfRows=%d",tillId, startAtRow, takeNoOfRows]; 

    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:finalURL] 
           completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 

            if (error != nil) { 
             if ([NWTillHelper isDebug] == 1) { 
              NSLog(@"WebServices:fetchTillDataAll:Transport error %@", error); 
             } 
            } else { 
             NSHTTPURLResponse *responseHTTP; 
             responseHTTP = (NSHTTPURLResponse *) response; 

             if(responseHTTP.statusCode != 200) { 
              if ([NWTillHelper isDebug] == 1) { 
               NSLog(@"WebServices:fetchTillDataAll:Server Error %d", (int) responseHTTP.statusCode); 
              } 
             } else { 
              NSArray *tillBasicDataArray = [NSJSONSerialization JSONObjectWithData:data 
                              options:0 
                              error:NULL]; 
              if ([NWTillHelper isDebug] == 1) { 
               NSLog(@"WebServices:fetchTillDataAll:tillBasicDataArray count = %lu", (unsigned long)[tillBasicDataArray count]); 
               NSLog(@"WebServices:fetchTillDataAll:tillBasicDataArray looks like %@",tillBasicDataArray); 
              } 

              NSDictionary *tillBasicDataDict = Nil; 

              //Loop through the array and for each dictionary insert into local DB 
              for (id element in tillBasicDataArray){ 
               tillBasicDataDict = element; 

               NSString *itemId = [tillBasicDataDict objectForKey:@"itemId"]; 
               NSString *brandId = [tillBasicDataDict objectForKey:@"companyId"]; 
               NSString *languageId = [tillBasicDataDict objectForKey:@"languageCode"]; 
               NSString *colorCode = [NSString stringWithFormat:@"%@", [tillBasicDataDict objectForKey:@"colorCode"]]; 
               NSString *discountable = [tillBasicDataDict objectForKey:@"discountable"]; 
               NSString *exchangeable = [tillBasicDataDict objectForKey:@"exchangeable"]; 
               NSString *noos14 = [tillBasicDataDict objectForKey:@"noos14"]; 
               NSString *sizeCode = [NSString stringWithFormat:@"%@", [tillBasicDataDict objectForKey:@"sizeCode"]]; 
               NSString *taxGroup = [tillBasicDataDict objectForKey:@"taxGroupId"]; 
               NSString *taxRegion = [tillBasicDataDict objectForKey:@"taxRegion"]; 
               NSString *tradeItemDesc = [tillBasicDataDict objectForKey:@"tradeItemDesc"]; 
               NSString *withTax = [tillBasicDataDict objectForKey:@"withTax"]; 
               NSString *status = [tillBasicDataDict objectForKey:@"status"]; 

               // Use Core Data FMD 
               AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate]; 

               NSManagedObjectContext *context = 
               appDelegate.persistentContainer.viewContext; 
               context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy; 

               NSManagedObject *newPimItem = Nil; 
               newPimItem = [NSEntityDescription 
                   insertNewObjectForEntityForName:@"TillData" 
                   inManagedObjectContext:context]; 

               [newPimItem setValue:itemId forKey:@"itemId"]; 
               [newPimItem setValue:brandId forKey:@"brandId"]; 
               [newPimItem setValue:languageId forKey:@"languageCode"]; 
               [newPimItem setValue:colorCode forKey:@"colorCode"]; 
               [newPimItem setValue:discountable forKey:@"discountable"]; 
               [newPimItem setValue:exchangeable forKey:@"exchangeable"]; 
               [newPimItem setValue:noos14 forKey:@"noos14"]; 
               [newPimItem setValue:sizeCode forKey:@"sizeCode"]; 
               [newPimItem setValue:[NSNumber numberWithInt:[taxGroup intValue]] forKey:@"taxGroup"]; 
               [newPimItem setValue:taxRegion forKey:@"taxRegion"]; 
               [newPimItem setValue:tradeItemDesc forKey:@"tradeItemDesc"]; 
               [newPimItem setValue:[NSNumber numberWithInt:[withTax intValue]] forKey:@"withTax"]; 
               [newPimItem setValue:[NSNumber numberWithInt:[status intValue]] forKey:@"status"]; 

               NSError *error = Nil; 
               [context save:&error]; 

               if ([NWTillHelper isDebug] == 1) { 
                NSLog(@"WebServices:fetchTillDataAll:ItemId in loop = %@", itemId); 
                NSLog(@"WebServices:fetchTillDataAll:newPimItem = %@", newPimItem); 
                NSLog(@"WebServices:fetchTillDataAll:CoreData error = %@", error); 
               } 

               if(error != nil) { 
                // Do something here 
               } else { 
                NSUserDefaults *tillUserDefaults = [NSUserDefaults standardUserDefaults]; 
                [tillUserDefaults setInteger:1 forKey:@"hasTillData"]; 
                [tillUserDefaults synchronize]; 
               } 
              } 
             } 
            } 
           }] resume]; 
} 

なぜ、このオプティミスティック・ロック・エラー・メッセージを引き起こすように見えますか?

+0

管理されたコンテキストにはどのような並行性タイプが使用されましたか? –

+0

NSManagedObjectContext * context = appDelegate.persistentContainer.viewContext; context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy; –

+0

並行処理の種類を指定するにはどうすればよいですか? –

答えて

1

問題は管理コンテキストで発生していました。 viewContextプロパティを使用する場合は、メインスレッドですべての操作を実行する必要があります。

異なるスレッド(メインスレッドではない)で長い操作を実行する場合は、newBackgroundContext()メソッドを使用して、この操作のための新しい管理コンテキストを作成することをお勧めします。