Core Data'nın modelleri otomatik olarak taşıması için ne yapmalıyım?


96

Çekirdek Veri modelleri için otomatik / hafif geçişle ilgili belgeleri okudum, ancak bunu uygularken sorunlar yaşıyorum.

Anladığım kadarıyla uygulama, sahip olduğu model ile bir cihazda bulunan modelin aynı olmadığını fark etmelidir. Yalnızca öznitelikler veya ilişkiler ve benzer basit değişiklikler eklediyseniz, model otomatik olarak yükseltilmelidir.

Herhangi bir işaret - Xcode'da bir şey ayarlamam gerekiyor mu?

Yanıtlar:


138

Şimdi bunun oldukça basit olduğunu öğrendim - nereye bakacağınızı bildiğinizde.

AppDelegate'imde NSPersistentStoreCoordinator'ı kurdum - ve otomatik geçişi işlemesini söylemek için buna bazı seçenekler eklemeniz gerekiyor:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,

[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

NSError *error;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    // Handle error
    NSLog(@"Problem with PersistentStoreCoordinator: %@",error);
}

O zaman xCode'da küçük bir numara yapmanız gerekir:

  1. Xcdatamodel dosyanızı seçin
  2. En üstteki Tasarım Menüsünü seçin, ardından Veri Modeli'ni seçin ve ardından Model Sürümü Ekle'yi seçin
  3. Xcdatamodel dosyanız daha sonra xcdatamodel dosyanızla aynı ada sahip ancak xcdatamodeld uzantısına sahip yeni bir dizine taşınacaktır - bu dizinde adında 2 olan ikinci bir dosya olacaktır. Yeni dosyayı seçin ve ardından Tasarım-> Veri Modeli-> Mevcut Sürümü Ayarla ( Xcode 4'te bunu yaparsınız )
  4. Projenizin uyumsuz olmasına neden olan değişiklikleri zaten yaptıysanız - bu değişiklikleri orijinal xcdatamodel dosyasından çıkarın. Henüz değişiklikleri yapmadıysanız - o zaman 2.xcdatamodel dosyasını (az önce yaptığınız sürüm) düzenleyin.
  5. Şimdi bu sürümü eski modele sahip bir cihaza yüklediğinizde - bu modeli otomatik olarak yeni modele yükseltecektir.

Bu harika ve istediğim kadar basit görünüyor - ancak geliştirme sırasında bir modeli değiştirirken dikkatli olmanız gerektiğini düşünüyorum - aksi takdirde her değişiklik için yeni bir sürüm oluşturmanız gerekecektir.

Sanırım yapacağım şey, değiştirilen tüm dosyaları saklayacağım ve ardından güncellememi dağıtmaya hazırlandığımda aradaki tüm dosyaları silip en eski ve en son modellerle dağıtacağım.


GÜNCELLEME (15/07/2011):

@ Rockstarberlin'e Apple'da güncellenmiş belgeler olduğunu belirttiği için teşekkürler :

Xcode 4: Yönetilen Nesne Modelinin Mevcut Sürümünü Ayarlama

Güncelleme: 19.08.2013 daha iyi bağlantı:

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmModelFormat.html


Xcode belge görüntüleyicisinde ve developer.apple.com adresinde bulunan Temel Veri Taşıma ve Sürüm Oluşturma Kılavuzunu okumanızı öneririm.
Hunter

1
Buradaki cevabı basitçe bulamadım - bunu nasıl yapacağımı bulmak biraz zaman aldı.
Grouchal

NSInferMappingModelAutomaticallyOption iyi çalışır, ancak yalnızca bir özniteliğin adını değiştirmek gibi basit eşlemeler için. Daha karmaşık herhangi bir şey için (ilişkiler, varlık kaldırma veya ekleme) bir eşleme modeli eklemeniz gerekecektir. Xcode, NSInferMappingModelAutomaticallyOption'ın bildirilmediğinden şikayet ederse, #import <CoreData / CoreData.h> öğesini uygulama temsilcisi üstbilgi dosyanıza ekleyin.
Elise van Looij

Modelime bazı varlıklar ekledim ve kötü şöhretli "Mağazayı açmak için kullanılan model, mağazayı oluşturmak için kullanılan modelle uyumsuz" hatasını aldım. Çözümünüz onu düzeltti! Çok teşekkür ederim!
Karsten Silz

1
Bu talimatları izledikten sonra "modelleri iki farklı varlıkla birleştiremiyorum" hatası alıyorsanız aşağıdaki Santthosh'un yanıtına bakın.
benvolioT

14

Bu inanılmaz derecede yardımcı oldu. Apple belgeleri - her zamanki gibi - ne yazık ki eksikti. Bu değişiklikleri yaptıktan sonra ilk kez çalıştırdığımda "İki farklı varlığa sahip modelleri birleştiremiyorum xxx" hatasıyla karşılaştığım için temiz bir yapı yapmanızı öneririm. Temiz yapı onu düzeltti.


Temiz bir yapı sorunlarımı da çözdü.
jrainbow

6

Grouchal'ın cevabı mükemmel ... ancak yapıyı birkaç kez temizledikten sonra bile "Modelleri iki farklı varlıkla birleştiremiyorum xxx" varsa ... managedObjectModel'in nasıl yüklendiğiyle ilgili sorunlarınız olabilir .. .şuna bir bakın ... bu da düzeltmeme yardımcı oldu ..

temel veri taşıma sorunları


3

Ayrıca, benim yaptığım gibi bu gönderiye rastladıysanız, "Mağazayı açmak için kullanılan model, mağazayı oluşturmak için kullanılan modelle uyumsuz" hatasını aldıktan sonra ve yalnızca simülatörü kullanarak hata ayıklama yapıyorsunuz ve Eski model yüklüyse, Simülatör uygulamasını sıfırlayabilir veya uygulamanızı simülatörden silmek muhtemelen işe yarayacaktır.

Buradaki yazıları okuyana kadar bunu denemek aklıma gelmedi, bu noktada uygulamayı simülatöre yüklediğimi ve daha sonra modeli değiştirdiğimi fark ettim, bu da yukarıda bahsedilen çalışma zamanı hatasına neden oldu.


1

Santthosh'un cevabını takip etmek için, kod pasajını onun yerine buraya göndereceğimi düşündüm. ManagedObjectModel'inizi oluşturmanız gerekir initWithContentsOfURL:, mergedModelFromBundles:aksi takdirde hata alırsınız:

XXX ve XXX olmak üzere iki farklı varlıkla modeller birleştirilemez

Model dosyanız "Model" olarak adlandırılmışsa, managedObjectModel'i şu şekilde oluşturursunuz:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; 

Bu blog gönderisine kredi verin .



1

Yıllardır bu sorunu yaşadım ve tüm bu cevapları boşuna denedim. Bugün nihayet neyi yanlış yaptığımı anladım. Çok basit bir sorun, ama onu gözden kaçırdım. Veri modelinin daha yeni bir sürümünü oluştururken, sütun EKLİYORSANIZ, bunları İSTEĞE BAĞLI olarak işaretlediğinizden emin olun. Bunu yapmazsanız, yeni sütun değerleri doldurulmayacağı için basit geçiş çalışmayacaktır.

Yeni sütunlarımın "isteğe bağlı" işaretli olduğundan emin olur olmaz, taşımayı tekrar denedim ve işe yaradı.


1

Farklı bir sorun nedeniyle bu gönderiye rastladım, ancak hata " Mağazayı açmak için kullanılan model yapılandırması, mağazayı oluşturmak için kullanılan yapılandırmayla uyumsuz " idi.

İşte benim sorunum ve onun çözümü. Modelimde konfigürasyonları kullanıyordum . Varlıklardan bazıları bir dosyada ve diğerleri ikinci bir dosyada saklanıyordu. (Periyodik olarak indirilmesi gerekebilecek bazı varsayılanlarım var ve bunları bir bütün halinde birleştirmek inanılmaz bir acı olurdu). Her neyse, yeni bir varlık yaptım. Program iyi çalışıyor gibiydi, ancak ne zaman çıksam yukarıdaki hatayı aldım.

Çözüm, konfigürasyonlarıma bakmak, şu anda hiçbir konfigürasyonda olmayan bir varlığım olduğunu fark etmek ve onu birine eklemekti. Bir rüya gibi koşuyor.

Bu, OP'nin sorununu çözmez. Ama belki google üzerinden buraya inen bir kaç kişi benim bulunduğum teknede olacak :)


0

iOS 4.0+

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

0

@ Grouchal'ın Xcode sürüm 5 için yukarıdaki harika talimatlarında küçük bir düzenleme:

Eski: 2. En üstteki Tasarım Menüsünü seçin - ardından Veri Modeli - sonra Model Sürümü Ekle'yi seçin

Sürüm 5+: 2. Düzenleyici menüsünü seçin, ardından Model Sürümü Ekle… öğesini seçin, Sürüm adınızı yazın ve Modele göre (listeden orijinal modelinizi seçin)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.