2015-10-27 73 views
-1

我試圖將數據插入coredata但我得到的錯誤一樣,IOS Coredata UNIQUE約束失敗:

CoreData: error: (1555) UNIQUE constraint failed: ZSIDETABLENAME.Z_PK

情景: -

第一:從appdelegate.m我從複製數據我SQL文件來記錄目錄的sql文件。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
    if (_persistentStoreCoordinator != nil) { 
     return _persistentStoreCoordinator; 
    } 


    // Create the coordinator and store 

     NSString* from; 
     NSString* to; 
     NSArray* mainPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDirectory = [mainPath objectAtIndex:0]; // Get documents folder 
     /*VoiceRecords.plist file*/ 
     from=[[NSBundle mainBundle]pathForResource:@"News" ofType:@"sqlite"]; 
     to=[documentsDirectory stringByAppendingPathComponent:@"News.sqlite"]; 
     [[NSFileManager defaultManager]copyItemAtPath:from 
               toPath:to error:nil]; 
     from=nil; 
     to=nil; 

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"News.sqlite"]; 

    NSError *error = nil; 
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { 
     /* 
     Replace this implementation with code to handle the error appropriately. 

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 

     Typical reasons for an error here include: 
     * The persistent store is not accessible; 
     * The schema for the persistent store is incompatible with current managed object model. 
     Check the error message to determine what the actual problem was. 


     If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory. 

     If you encounter schema incompatibility errors during development, you can reduce their frequency by: 
     * Simply deleting the existing store: 
     [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil] 

     * Performing automatic lightweight migration by passing the following dictionary as the options parameter: 
     @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES} 

     Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details. 

     */ 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    return _persistentStoreCoordinator; 
} 

它工作正常。然後,我試圖保存在mainviewcontroller.m中用戶輸入的coredata中的url。

- (void)feedParserDidFinish:(MWFeedParser *)parser { 

     NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"IWorld"]; 
       fetchRequest.predicate = [NSPredicate predicateWithFormat:@"feedurl = %@", self.Feedlink]; 
     NSManagedObjectContext *context = [self managedObjectContext]; 

     if ([[context executeFetchRequest:fetchRequest error:NULL] count] == 0) { 
       NSError *error = nil; 

      NSPredicate *predicate=[NSPredicate predicateWithFormat:@"feedurl contains %@",check]; 
      [fetchRequest setPredicate:predicate]; 
       NSMutableArray *checkp = [[context executeFetchRequest:fetchRequest error:&error]mutableCopy]; 


      if (checkp.count<=0) { 
       NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:@"IWorld" inManagedObjectContext:context]; 
       [newDevice setValue:self.Name forKey:@"name"]; 
       [newDevice setValue:self.WebsiteName forKey:@"websitename"]; 
       [newDevice setValue:self.Feedlink forKey:@"feedurl"]; 

            // Save the object to persistent store 
       if (![context save:&error]) { 
        NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]); 
       } 
        //Save value in lockbox 

       NSArray *keys = [[[newDevice entity] attributesByName] allKeys]; 
       NSDictionary *dict = [newDevice dictionaryWithValuesForKeys:keys]; 

      } 

     } 


    NSFetchRequest *fetchrequestforside=[NSFetchRequest fetchRequestWithEntityName:@"Sidetablename"]; //Sidetablename is entity 
    fetchrequestforside.predicate=[NSPredicate predicateWithFormat:@"feedurl = %@", self.Feedlink]; 
      NSManagedObjectContext *context = [self managedObjectContext]; 
    if ([[context executeFetchRequest:fetchrequestforside error:NULL] count] == 0) { 
        // Create a new managed object 

        NSError *error = nil; 

        NSPredicate *predicate=[NSPredicate predicateWithFormat:@"feedurl contains %@",check ]; //check is urlstring 
        [fetchrequestforside setPredicate:predicate]; 
        NSMutableArray *checkp = [[context executeFetchRequest:fetchrequestforside error:&error]mutableCopy]; 


        if (checkp.count<=0) //if coredata will find url then notstore in coredata else stored procedure 
      { 

        NSManagedObject *newDevice1 = [NSEntityDescription insertNewObjectForEntityForName:@"Sidetablename" inManagedObjectContext:context]; 

        if (self.Name) 
        { 
         [newDevice1 setValue:self.Name forKey:@"name"]; 


        } 
        if (self.WebsiteName) 
        { 
         [newDevice1 setValue:self.WebsiteName forKey:@"websitename"]; 

        } 

        if (self.Feedlink) 
        { 
         [newDevice1 setValue:self.Feedlink forKey:@"feedurl"]; 

        } 




        NSError *error = nil; 
        if (![context save:&error]) { 
          NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]); // Getting error here through nslog //CoreData: error: (1555) UNIQUE constraint failed: ZSIDETABLENAME.Z_PK 

         } 

注意:這一切都發生在第一次。第二次,我將運行應用程序都正常工作。不知道問題在哪裏?

+0

根據錯誤消息,您已將屬性sidetablename設置爲唯一,並且您試圖爲屬性sidetablename保存具有相同值的另一個對象。你是否已經通過調試器查看了你想要保存的對象以及實際的核心數據庫中的內容?你在嘗試自我診斷問題時做了什麼?這些測試的結果是什麼?在調試器中單步執行時會看到什麼? –

+0

你是如何創建你正在複製的SQLite文件的? –

+0

@TomHarrington先生我從文檔目錄中獲取了sql文件,我在其中輸入了靜態數據,然後將其複製到了包中,然後當應用程序第一次啓動時,我正在複製數據。 –

回答

3

您在sidetablename表上獲得主鍵約束違規。

因此,我相信你的問題在於你如何創建和複製你的種子數據庫。

不幸的是,您沒有提供該信息。因此,我只是猜測你是如何做到的。

我假設你使用mac應用程序創建了數據庫,或者你在iOS模擬器中創建了該數據庫。然後,將sqlite文件從創建位置複製到捆綁資源中。

由於WAL自iOS/OSX 7/10.9以來一直是默認模式,因此我假設您在WAL模式下創建了種子數據庫。這意味着你可能會錯過-wal和-shm文件。如果您指定任何數據屬性都應使用外部存儲,那麼您也錯過了該數據。

創建要複製的種子數據庫時,還需要複製-shm/wal文件,或者需要以回滾日記模式創建數據庫,這將在文件中添加所有數據。

通過在添加持久性存儲時設置以下選項(如果您已經使用選項,只需將其中的選項與其他選項合併)即可實現此目的。

NSDictionary *options = @{NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}}; 
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
               configuration:nil 
                 URL:storeURL 
                options:options 
                 error:&error]) { 
    // Handle error 
} 

這是您在創建要複製到捆綁包的數據庫時如何添加持久存儲的方式。它將確保一切都在實際的數據庫文件中。

現在,在運行代碼來創建種子文件後,應該轉到該目錄並查看是否有任何其他文件正在鋪設。最好的辦法是在終端。轉到該目錄,並執行「ls -lat」,它將列出按時間排序的所有文件。

警告:根據兩個實體的配置,SQLite和Core Data都可以創建與sqlite文件一起使用的額外文件。因此,您通常應該將每個核心數據持久性存儲視爲文件包。換句話說,您應該爲核心數據存儲創建一個單獨的目錄。這樣,當SQLite或核心數據決定創建額外的文件時,所有內容都被限制在一個目錄中。

將文件複製到創建種子數據庫的捆綁資源中時,需要確保複製所有內容。

同樣,您應該在部署時將所有內容從軟件包複製到設備。

但是,而不是使用文件系統,你應該考慮這些方法對NSPersistentStoreCoordinator ......

/* Used for save as - performance may vary depending on the type of old and 
    new store; the old store is usually removed from the coordinator by the 
    migration operation, and therefore is no longer a useful reference after 
    invoking this method 
*/ 
- (NSPersistentStore *)migratePersistentStore:(NSPersistentStore *)store 
             toURL:(NSURL *)URL 
             options:(nullable NSDictionary *)options 
            withType:(NSString *)storeType 
             error:(NSError **)error; 

/* copy or overwrite the target persistent store in accordance with the store 
    class's requirements. It is important to pass similar options as 
    addPersistentStoreWithType: ... SQLite stores will honor file locks, journal 
    files, journaling modes, and other intricacies. Other stores will default 
    to using NSFileManager. 
*/ 
- (BOOL)replacePersistentStoreAtURL:(NSURL *)destinationURL 
       destinationOptions:(nullable NSDictionary *)destinationOptions 
     withPersistentStoreFromURL:(NSURL *)sourceURL 
         sourceOptions:(nullable NSDictionary *)sourceOptions 
          storeType:(NSString *)storeType 
           error:(NSError**)error NS_AVAILABLE(10_11, 9_0); 

因此,我相信,如果你正確地創建數據庫,然後完全複製它,正確地連接到你的資源包和你的應用程序,那麼你的問題就會消失。

+0

什麼猜測!正確的先生。真的,你是偉大的先生。謝謝你,先生。非常感謝。 –

+0

我正在使用CoreData,創建數據庫是ios自己正在做的事情。我有時會得到這個錯誤「CoreData:錯誤:(1555)UNIQUE約束失敗:」。你能幫助我嗎,我不明白你是如何解決這個問題的? – hrast

+0

我將Boundite的sqlite-shm和sqlite-wam文件複製到Documents文件夾,但UNIQUE錯誤仍然存​​在。有什麼建議麼? – arniotaki