2017-06-13 32 views
2

我從Web服務中提取大量數據,該服務將JSON數組傳回給我的應用程序,我使用兩種不同的Web服務,一種用於每個核心數據實體來加載數據,但我我正在從核心數據中獲得樂觀的鎖定錯誤。核心數據樂觀鎖定錯誤

是否核心數據鎖定不是按每個實體完成的?所以我可以同時將對象插入兩個不同的實體?

我的代碼看起來像下面

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

Webservice的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()方法爲此操作創建新的託管上下文。