Mac / iPhone-app - Synchronisierung wichtigsten Daten zu iCloud & - Geräte (mit core data)
Arbeite ich in einem iPhone-app und eine Mac app, Core Data.
Ich hätte gern diese 2 apps synchronisieren Ihre Datenbanken über den iCloud-Speicher.
Habe ich Anpassungen zu den Implementierungen der managedObjectContext
& persistentStoreCoordinator
& Hinzugefügt mergeiCloudChanges
- aus der aktualisierten Rezepte Beispiel-code:
#pragma mark -
#pragma mark Core Data stack
//this takes the NSPersistentStoreDidImportUbiquitousContentChangesNotification
//and transforms the userInfo dictionary into something that
//-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] can consume
//then it posts a custom notification to let detail views know they might want to refresh.
//The main list view doesn't need that custom notification because the NSFetchedResultsController is
//already listening directly to the NSManagedObjectContext
- (void)mergeiCloudChanges:(NSNotification*)note forContext:(NSManagedObjectContext*)moc {
NSLog(@"merging iCloud stuff");
[moc mergeChangesFromContextDidSaveNotification:note];
NSNotification* refreshNotification = [NSNotification notificationWithName:@"RefreshAllViews" object:self userInfo:[note userInfo]];
[[NSNotificationCenter defaultCenter] postNotification:refreshNotification];
}
/**
Returns the managed object context for the application.
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
*/
- (NSManagedObjectContext *)managedObjectContext
{
if (managedObjectContext != nil)
{
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"5.0")) {
NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc performBlockAndWait:^{
[moc setPersistentStoreCoordinator: coordinator];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(mergeChangesFrom_iCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator];
}];
managedObjectContext = moc;
} else {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:coordinator];
}
}
return managedObjectContext;
}
//NSNotifications are posted synchronously on the caller's thread
//make sure to vector this back to the thread we want, in this case
//the main thread for our views & controller
- (void)mergeChangesFrom_iCloud:(NSNotification *)notification {
NSManagedObjectContext* moc = [self managedObjectContext];
//this only works if you used NSMainQueueConcurrencyType
//otherwise use a dispatch_async back to the main thread yourself
[moc performBlock:^{
[self mergeiCloudChanges:notification forContext:moc];
}];
}
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
*/
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator__ != nil) {
return persistentStoreCoordinator__;
}
//assign the PSC to our app delegate ivar before adding the persistent store in the background
//this leverages a behavior in Core Data where you can create NSManagedObjectContext and fetch requests
//even if the PSC has no stores. Fetch requests return empty arrays until the persistent store is added
//so it's possible to bring up the UI and then fill in the results later
persistentStoreCoordinator__ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
//prep the store path and bundle stuff here since NSBundle isn't totally thread safe
NSPersistentStoreCoordinator* psc = persistentStoreCoordinator__;
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"MyApp.sqlite"];
//do this asynchronously since if this is the first time this particular device is syncing with preexisting
//iCloud content it may take a long long time to download
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
//this needs to match the entitlements and provisioning profile
NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:nil];
NSString* coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:@"MyApp"];
cloudURL = [NSURL fileURLWithPath:coreDataCloudContent];
NSLog(@"cloudURL: %@", cloudURL);
// The API to turn on Core Data iCloud support here.
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@"xxxxxxxx.com.me.MyApp",
@"MyApp",
cloudURL,
NSPersistentStoreUbiquitousContentURLKey,
[NSNumber numberWithBool:YES],
NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES],
NSInferMappingModelAutomaticallyOption,
nil];
NSError *error = nil;
[psc lock];
if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options 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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
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.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[psc unlock];
//tell the UI on the main thread we finally added the store and then
//post a custom notification to make your views do whatever they need to such as tell their
//NSFetchedResultsController to -performFetch again now there is a real store
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"asynchronously added persistent store!");
[[NSNotificationCenter defaultCenter] postNotificationName:@"RefetchAllDatabaseData" object:self userInfo:nil];
});
});
return persistentStoreCoordinator__;
}
Kann ich die Dateien erscheinen in meiner "/Users/ich/Library/Mobile Documents" - Verzeichnis, wenn ich build/run myapp.
Aber ich habe keine Ahnung, ob es die Synchronisation über die iCloud Speicher - und offensichtlich auch die Daten zwischen iphone und mac ist nicht synchronisiert.
Gibt es andere Methoden, die ich implementieren muss, um die Daten in die cloud verschieben?
Und gibt es irgendeine Möglichkeit für mich, zu sehen, was die Dokumente tatsächlich auf der iCloud-Speicher?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist eine kurze teilantwort.
Können Sie sehen, was die in iCloud gespeichert sind:
Auf dem Mac:
Systemeinstellungen.app -> iCloud -> klicken Sie auf 'Verwalten...' finden Sie dann eine Liste mit allen apps, die Dokumente gespeichert Mac OS X oder iOS.
Auf iOS:
Einstellungen -> iCloud -> Archiv & Backup -> option unter den verwendeten Speicherplatz Sie sehen dann eine Liste mit allen apps, die Dokumente gespeichert Mac OS X oder iOS.
Solange Sie mit
NSFileManager
'ssetUbiquitous: itemAtURL: destinationURL: error:
sollten die Dokumente immer in die iCloud gesendet, die für Sie und zeigt sich auch auf anderen Geräten.if ([[NSFileManager defaultManager] setUbiquitous:makeUbiquitous itemAtURL:fileURL destinationURL:destURL error:&err]) {
so halt ich die app über Xcode, und dann erscheint es in der Konsole app:librariand: client connection is invalid: Connection invalid
Irgendwelche Ideen?setUbiquitous:...
. Wenn ich Probleme habe ich HinzugefügtNSLog(@"container == %@", [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:container]);
zu einem der init-Methoden in der app zu sehen, wenn ich war auch immer ein URL. Sie sollten auch sicherstellen, dass Sie nicht versuchen, verschieben Sie das Dokument, bevor es auf den Datenträger geschrieben wurden woanders zuerst.Andere partielle Antwort. Werfen Sie einen Blick auf : http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1 wenn Sie noch nicht haben. Ich bin an der gleichen Sache arbeiten wie Sie, nämlich, Mac App und iOS
app-Daten zu teilen. Viel Glück. Daneben
Ich habe gelernt, über : http://mentalfaculty.tumblr.com/archive
Suchen Sie nach "Unter Der Bettdecke" CoreData und iCloud. Check it out!
OK mein code sieht anders aus, ich habe es in einer separaten Klasse wiederverwenden es für alle meine Projekte. Dennoch, wenn iCloud aktiviert ist (URLForUbiquityContainerIdentifier:null zurück, die nicht null) richte ich meine NSPersistentStoreCoordinator wie diese:
Vermisse ich, wo man das setup der NSPersistentStoreUbiquitousContentnamekey.
Zweiten ist klar, ich denke, das funktioniert nur auf dem Gerät, und Ihre App-ID muss iCloud aktiviert.