2016-11-23 79 views
1

我遇到了iOS核心數據非常奇怪的行爲,我從Web服務下載項目並使用核心數據在本地存儲它,我有一個UTTableViewController顯示什麼是存儲在本地實體中,相同的tableController也允許對選定項目進行刪除操作。 我也有屬性「的itemId」的約束,以避免重複和我使用的默認行爲拋出一個錯誤,如果的itemId是一個重複的Xcode 8.1 IOS10.1 CoreData刪除並沒有真正刪除

的問題如下

當我從下載的項目webservice第一次完全按照預期工作。

如果我嘗試重新加載數據,約束正確顯示我存在衝突的錯誤。

然後我進入UITableViewController並刪除其中一個項目,這個按預期工作,ViewCOntroller顯示剩餘的項目。

現在我從Web服務重新加載項目,現在它不能加回被刪除的項目,該限制告訴我存在衝突。

這就好像該項目沒有真正刪除,仍然掛在背景中但不可見。

(1)調試告訴我,一切看起來不錯

有人可以幫我解釋一下,當我重裝,我刪除了相同的itemId爲什麼我收到的約束錯誤。

這是下載方法

+ (void)fetchTillData:(int)tillId; { 

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

NSString *finalURL = [NSString stringWithFormat:@"https://foo.bar.com:5443/api/till/tilldata/%d?StartAtRow=0&TakeNoOfRows=10",tillId]; 

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

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

            if(responseHTTP.statusCode != 200) { 
             if ([NWTillHelper isDebug] == 1) { 
              NSLog(@"WebServices:fetchTillData:Server Error %d", (int) responseHTTP.statusCode); 
             } 
            } else { 
             NSArray *tillBasicDataArray = [NSJSONSerialization JSONObjectWithData:data 
                             options:0 
                             error:NULL]; 
             if ([NWTillHelper isDebug] == 1) { 
              NSLog(@"WebServices:fetchTillData:tillBasicDataArray count = %lu", (unsigned long)[tillBasicDataArray count]); 
              NSLog(@"WebServices:fetchTillData: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 *companyId = [tillBasicDataDict objectForKey:@"companyId"]; 
              NSString *languageId = [tillBasicDataDict objectForKey:@"languageCode"]; 
              NSString *colorCode = [tillBasicDataDict objectForKey:@"colorCode"]; 
              NSString *discountable = [tillBasicDataDict objectForKey:@"discountable"]; 
              NSString *exchangeable = [tillBasicDataDict objectForKey:@"exchangeable"]; 
              NSString *noos14 = [tillBasicDataDict objectForKey:@"noos14"]; 
              NSString *sizeCode = [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]; 

              //AppDelegate *appDelegate = 
              //[[UIApplication sharedApplication] delegate]; 

              NSManagedObjectContext *context = 
              appDelegate.persistentContainer.viewContext; 
              NSManagedObject *newPimItem = Nil; 
              newPimItem = [NSEntityDescription 
                  insertNewObjectForEntityForName:@"TillData" 
                  inManagedObjectContext:context]; 

              [newPimItem setValue:itemId forKey:@"itemId"]; 
              [newPimItem setValue:companyId forKey:@"companyId"]; 
              [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:fetchTillData:ItemId in loop = %@", itemId); 
               NSLog(@"WebServices:fetchTillData:newPimItem = %@", newPimItem); 
               NSLog(@"WebServices:fetchTillData:CoreData error = %@", error); 
              } 

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

的(1)調試告訴我,我沒有任何NIL/NULL值的任何地方

的(1)調試也表明我,每個變量持有期望值

下面是使用的NSLog從web服務的JSON陣列,所有的值都是正確

WebServices:fetchTillData:tillBasicDataArray looks like (
    { 
    colorCode = 95; 
    companyId = "BE_HM"; 
    discountable = 1; 
    exchangeable = 1; 
    itemId = 101064025138010; 
    languageCode = eng; 
    noos14 = "09258384374953,09258387354952"; 
    sizeCode = "163-010"; 
    status = 1; 
    taxGroupId = 1; 
    taxRegion = BE; 
    tradeItemDesc = "Jersey basic"; 
    withTax = 1; 
}, 
    { 
    colorCode = 95; 
    companyId = "BE_HM"; 
    discountable = 1; 
    exchangeable = 1; 
    itemId = 101064025138011; 
    languageCode = eng; 
    noos14 = "09258384394951,09258387434951"; 
    sizeCode = "163-011"; 
    status = 1; 
    taxGroupId = 1; 
    taxRegion = BE; 
    tradeItemDesc = "Jersey basic"; 
    withTax = 1; 
}, 
    { 
    colorCode = 95; 
    companyId = "BE_HM"; 
    discountable = 1; 
    exchangeable = 1; 
    itemId = 101064025138012; 
    languageCode = eng; 
    noos14 = "09258385254957,09258389874953"; 
    sizeCode = "163-012"; 
    status = 1; 
    taxGroupId = 1; 
    taxRegion = BE; 
    tradeItemDesc = "Jersey basic"; 
    withTax = 1; 
} 
) 

但我仍然收到此錯誤即使我已經刪除了所有條目和tableViewController表明,我的數據庫是空的

2016-11-23 15:07:36.714 NWMobileTill[674:9231] WebServices:fetchTillData:ItemId in loop = 101064025138010 
2016-11-23 15:07:36.715 NWMobileTill[674:9231] WebServices:fetchTillData:newPimItem = <TillData: 0x6000002ce9a0> (entity: TillData; id: 0x600000624620 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D15> ; data: { 
    colorCode = 95; 
    companyId = "BE_HM"; 
    discountable = 1; 
    exchangeable = 1; 
    itemId = 101064025138010; 
    languageCode = eng; 
    noos14 = "09258384374953,09258387354952"; 
    sizeCode = "163-010"; 
    status = 1; 
    taxGroup = 1; 
    taxRegion = BE; 
    tradeItemDesc = "Jersey basic"; 
    withTax = 1; 
}) 
2016-11-23 15:07:36.717 NWMobileTill[674:9231] WebServices:fetchTillData:CoreData error = Error Domain=NSCocoaErrorDomain Code=133021 "(null)" UserInfo={conflictList=(
    "NSConstraintConflict (0x60000086dcc0) for constraint (\n itemId\n): database: (null), conflictedObjects: (\n \"<TillData: 0x6000000de4c0> (entity: TillData; id: 0x600000435500 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D7> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138012;\\n languageCode = eng;\\n noos14 = \\\"09258385254957,09258389874953\\\";\\n sizeCode = \\\"163-012\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\",\n \"<TillData: 0x6000002ce3f0> (entity: TillData; id: 0x60000023bda0 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D13> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138012;\\n languageCode = eng;\\n noos14 = \\\"09258385254957,09258389874953\\\";\\n sizeCode = \\\"163-012\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\",\n \"<TillData: 0x6080002cfc00> (entity: TillData; id: 0x60800022f920 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D4> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138012;\\n languageCode = eng;\\n noos14 = \\\"09258385254957,09258389874953\\\";\\n sizeCode = \\\"163-012\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\"\n)", 
    "NSConstraintConflict (0x60000067fd40) for constraint (\n itemId\n): database: (null), conflictedObjects: (\n \"<TillData: 0x6080002d0760> (entity: TillData; id: 0x608000233320 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D6> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138011;\\n languageCode = eng;\\n noos14 = \\\"09258384394951,09258387434951\\\";\\n sizeCode = \\\"163-011\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\",\n \"<TillData: 0x6080002cfb20> (entity: TillData; id: 0x60800022f9e0 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D3> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138011;\\n languageCode = eng;\\n noos14 = \\\"09258384394951,09258387434951\\\";\\n sizeCode = \\\"163-011\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\",\n \"<TillData: 0x6080002d3be0> (entity: TillData; id: 0x608000221ea0 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D12> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138011;\\n languageCode = eng;\\n noos14 = \\\"09258384394951,09258387434951\\\";\\n sizeCode = \\\"163-011\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\"\n)", 
    "NSConstraintConflict (0x60000067fc00) for constraint (\n itemId\n): database: (null), conflictedObjects: (\n \"<TillData: 0x6080002cecb0> (entity: TillData; id: 0x6080002218e0 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D5> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138010;\\n languageCode = eng;\\n noos14 = \\\"09258384374953,09258387354952\\\";\\n sizeCode = \\\"163-010\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\",\n \"<TillData: 0x6080002cf2d0> (entity: TillData; id: 0xd000000000180002 <x-coredata://6A608EA5-F8C8-4272-8C10-8621BB730066/TillData/p6> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138010;\\n languageCode = eng;\\n noos14 = \\\"09258384374953,09258387354952\\\";\\n sizeCode = \\\"163-010\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\",\n \"<TillData: 0x6000002ce9a0> (entity: TillData; id: 0x600000624620 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D15> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138010;\\n languageCode = eng;\\n noos14 = \\\"09258384374953,09258387354952\\\";\\n sizeCode = \\\"163-010\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\",\n \"<TillData: 0x6080002d1e20> (entity: TillData; id: 0x608000229160 <x-coredata:///TillData/t7807C999-528C-4616-A012-592A3D77D28D11> ; data: {\\n colorCode = 95;\\n companyId = \\\"BE_HM\\\";\\n discountable = 1;\\n exchangeable = 1;\\n itemId = 101064025138010;\\n languageCode = eng;\\n noos14 = \\\"09258384374953,09258387354952\\\";\\n sizeCode = \\\"163-010\\\";\\n status = 1;\\n taxGroup = 1;\\n taxRegion = BE;\\n tradeItemDesc = \\\"Jersey basic\\\";\\n withTax = 1;\\n})\"\n)" 
)} 

刪除代碼看起來如下,它顯示了當刪除完成後沒有錯誤

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSManagedObjectContext *context = self.persistentContainer.viewContext; 

    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete object from database 
     [context deleteObject:[self.pimItems objectAtIndex:indexPath.row]]; 

     NSError *error = nil; 
     if (![context save:&error]) { 
      if([NWTillHelper isDebug] == 1) { 
      NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]); 
      return; 
      } 
     } 

     // Remove device from table view 
     [self.pimItems removeObjectAtIndex:indexPath.row]; 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
    } 
    } 

後,我從的tableView和C刪除任何幫助將是非常有益的

------編輯------

失去應用程序,重新啓動應用程序我能夠按預期再次加載數據,但不會長久,因爲我仍然在應用程序中導航到應用程序的不同部分,然後返回即使調試告訴我輸入時在的tableView其空,但是當我嘗試加載數據出現錯誤

調試顯示出持久性存儲是空的

2016-11-23 16:09:04.106 NWMobileTill[1554:32365] pimItemsArray holds (
) 
2016-11-23 16:09:04.106 NWMobileTill[1554:32365] fetchReuestError holds (null) 

,你可以看到備份的實現代碼如下數組是空的讀取請求有NULL,所以持久性存儲爲空,如果爲空,爲什麼我不能重新加載數據?

這是填充的tableView

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

NSError *error = nil; 

// Fetch the devices from persistent data store 
NSManagedObjectContext *context = self.persistentContainer.viewContext; 
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"TillData"]; 
self.pimItems = [[context executeFetchRequest:fetchRequest error:&error] mutableCopy]; 

if([NWTillHelper isDebug] == 1) { 
    NSLog(@"pimItemsArray holds %@", self.pimItems); 
    NSLog(@"fetchReuestError holds %@", error); 
} 

[self.tableView reloadData]; 
} 
+0

對不起,我不確定你的意思,我讀鏈接,我做同樣的事情只是沒有循環NSManagedObject,因爲我只擔心表中的一行。所以我調用deleteObject,然後保存應該從持久存儲中刪除對象的上下文 –

+0

如果我在表中執行刪除操作,退出應用程序,啓動應用程序,然後它可以工作,但是如果我留在應用程序中並返回到主菜單並返回到管理菜單加載數據不起作用。 –

+0

我無法讀取它們,它們不在那裏,據我所見,以下調試確認了當我加載Tableview並從Persistent存儲中讀取其空的 –

回答

1

是我當時沒有使用的appDelegate在所有地方的問題的代碼一致

從符類下面一行是在所有地方

需要
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate]; 

感謝Vinodh和Flexicoder指出了這一點