2014-06-11 4 views
0

12 월 13 일에 제출 된 AppStore의 앱에 Xcode 4.3을 사용하여 제출 한 앱에 핵심 데이터 모델 (버전 2)이 있습니다. 이제 핵심 데이터 모델을 업데이트 한 다음 버전을 출시 할 예정입니다. 디버그 모드에서 코드를 실행할 때 마이그레이션이 정상적으로 작동합니다. 하지만 TestFlight를 통해 릴리스를 수행하면 마이그레이션이 실패하고 아래 오류가 발생합니다. 보안상의 이유로 앱을 종료 할 때마다 데이터베이스를 삭제하고 (암호화 된 사본 저장) 다음 번에이 DB의 암호를 해독합니다.iOS7.1에서 기존 앱의 핵심 데이터 업데이트가 실패했습니다

PersistentStoreCoordinator를 초기화하는 데 사용되는 코드입니다.

NSError *error = nil; 
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
NSDictionary *options = @{ 
          NSMigratePersistentStoresAutomaticallyOption : @YES, 
          NSInferMappingModelAutomaticallyOption : @YES 
          }; 


// Check if we need a migration 
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeURL error:&error]; 
NSManagedObjectModel *destinationModel = [_persistentStoreCoordinator managedObjectModel]; 
BOOL isModelCompatible = (sourceMetadata == nil) || [destinationModel isConfiguration:nil compatibleWithStoreMetadata:sourceMetadata]; 
if (! isModelCompatible) { 
    // We need a migration, so we set the journal_mode to DELETE 
    options = @{NSMigratePersistentStoresAutomaticallyOption:@YES, 
       NSInferMappingModelAutomaticallyOption:@YES, 
       NSSQLitePragmasOption: @{@"journal_mode": @"DELETE"} 
       }; 
} 

NSPersistentStore *persistentStore = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]; 
if (! persistentStore) { 


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documents = [paths objectAtIndex:0]; 
    NSString *databasePath = [documents stringByAppendingPathComponent:@"Store"]; 
    NSString *sqlite = [databasePath stringByAppendingPathComponent:@"myDatabase.sqlite"]; 

    [[NSFileManager defaultManager] removeItemAtPath:sqlite error:nil]; 

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

// Reinstate the WAL journal_mode 
if (! isModelCompatible) { 
    [_persistentStoreCoordinator removePersistentStore:persistentStore error:NULL]; 
    options = @{NSMigratePersistentStoresAutomaticallyOption:@YES, 
       NSInferMappingModelAutomaticallyOption:@YES, 
       NSSQLitePragmasOption: @{@"journal_mode": @"WAL"} 
       }; 
    [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]; 
} 

return _persistentStoreCoordinator; 

persistentStoreCoordinator를 초기화하려고하면 벨로우 오류가 발생합니다.

해결되지 않은 오류 오류 도메인 = NSCocoaErrorDomain 코드 = 259 사용자 정보 = 0x15df4dc0 {NSUnderlyingException는 = 경로에서 파일이 SQLite 데이터베이스로 표시되지 않습니다 "작업을 완료 할 수 없습니다 (코코아 오류 259)."/ VAR/모바일/응용 프로그램/9B623099-5591-4C55-BA83-77A057B94690/문서/저장/myDatabase.sqlite}, {

NSUnderlyingException = "File at path does not appear to be a SQLite database: /var/mobile/Applications/9B623099-5591-4C55-BA83-77A057B94690/Documents/Store/myDatabase.sqlite";} 

이상한 부분은 그 iOS7.0.6에 업그레이드 시나리오는 괜찮 았는데입니다 Dev 및 Release 구성 모두에서 사용할 수 있지만 iOS7.1에서는 Dev 구성에서만 작동하는 것으로 보입니다. 나는 WAL 및 SHM 파일을 삭제하는 데 지쳤지만 아무 소용이 없습니다.

답변

1

오류 메시지가 여기에 표시됩니다. 그것은 말한다 :

NSUnderlyingException = "File at path does not appear to be a SQLite database: /var/mobile/Applications/9B623099-5591-4C55-BA83-77A057B94690/Documents/Store/myDatabase.sqlite";}

나는 다음이 때문에 업데이트 된 핵심 데이터 SQLite는과 WAL 파일 사이의 불일치가 될 수 있다는 생각되었지만 오류가 동안 키 불일치로 할 더이었다 밝혀 암호화 - 해독 프로세스. 이것은 내 첫 번째 추측이었고 동료에게이 사실을 확인해달라고 요청했지만 그는이 사실을 어떻게 든 입증했으며 우리는이 이론을 비 승인했습니다.

우리의 암호화는 런타임 생성 된 암호화 키의 일부를 키 체인에 저장하여 작동합니다. 이제 앱 업그레이드 전과 업그레이드 후 키 체인의 값이 계속 유지된다는 전제가 있습니다. 그러나 잘못된 번들 식별자가 사용 되었기 때문에 업그레이드 된 앱은 키 체인에서 값을 가져 오지 않았고 자체 런타임 값을 만들었습니다.

키 체인에 저장된 값은 전체 번들 식별자가 동일한 경우에만 앱과 앱 업데이트간에 공유됩니다.

APP1 역방향 도메인은 동일하기 때문에이 app1.1 .com.yourcompany.appname

BundleIdentifierPrefix2번들 식별자를 가지고 BundleIdentifierPrefix1 .com.yourcompany.appname 번들 식별자를 가지고, 앱 업데이트로 설치되었지만 접두어가 다르므로 키 체인 값이 공유되지 않았습니다.

관련 문제