I have this old application written in Objective C that uses CoreData, backed with ICloud Documents.
https://i.stack.imgur.com/Q7FUa.png
Here's the setup for the old app
@property (nonatomic, strong) PersistentStack* persistentStack;
...
- (NSManagedObjectContext *)managedObjectContext
{
if (!self.persistentStack) {
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
self.persistentStack = [[PersistentStack alloc] initWithStoreURL:self.storeURL modelURL:modelURL];
}
return self.persistentStack.managedObjectContext;
}
- (NSURL*)storeURL
{
NSURL* documentsDirectory = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL];
return [documentsDirectory URLByAppendingPathComponent:@"MyApp.sqlite"];
}
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
_managedObjectContext.persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
[option addEntriesFromDictionary:@{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" }];
[self.managedObjectContext.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:option error:&error];
This function fetches all the data. The entity defined in the .xcdatamodeld
is called Nota
+(NSMutableArray*)getNoteInContext:(NSManagedObjectContext*)context
{
if(context==nil) context = [AppDelegate mainManagedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Nota" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"timestamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSError *error;
NSArray *risposta = [context executeFetchRequest:fetchRequest error:&error];
return [NSMutableArray arrayWithArray:risposta];
}
Here's the "new" app, written in Swift (SwiftUI)
I defined a class to manage the core data stuff
final class CoreDataManager {
private(set) lazy var managedObjectContext: NSManagedObjectContext = {
let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return managedObjectContext
}()
private lazy var managedObjectModel: NSManagedObjectModel = {
guard let modelURL = Bundle.main.url(forResource: "MyApp", withExtension: "momd") else {
fatalError("Unable to Find Data Model")
}
guard let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL) else {
fatalError("Unable to Load Data Model")
}
return managedObjectModel
}()
private lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let fileManager = FileManager.default
let storeName = "MyApp.sqlite"
do {
let documentsDirectoryURL = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let persistentStoreURL = documentsDirectoryURL.appendingPathComponent(storeName)
try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: persistentStoreURL, options: nil)
} catch {
fatalError("Unable to Load Persistent Store")
}
return persistentStoreCoordinator
}()
}
and here is how is consumed
struct Home: View {
@State var notes: [Nota]?
var body: some View {
VStack {
Text("Entries: \(self.notes?.count.description ?? "No entries at all")")
.padding(.top)
}.onAppear {
let moc = CoreDataManager().managedObjectContext
let fetchRequest = NSFetchRequest<Nota>()
fetchRequest.returnsObjectsAsFaults = false
let entity = NSEntityDescription.entity(forEntityName: "Nota", in: moc)
fetchRequest.entity = entity
let sortDescriptor1 = NSSortDescriptor(key: "timestamp", ascending: false)
let sortDescriptors = [sortDescriptor1]
fetchRequest.sortDescriptors = sortDescriptors
do {
self.notes = try moc.fetch(fetchRequest)
} catch {
fatalError("Failed to fetch notes: \(error)")
}
}
}
}
In the new app, having the same CFBundleIdentifier, the same Developer account and the same Apple ID in either simulator or physical device, the data saved in the "Old" App is not available in the "New" one.
If I delete the old app and reinstall it, ICloud syncs correcly show me the data from the cloud. Even after a complete reset of the device (just in case...)
What is missing? Or what I've done wrong?
Thanks in advance!