2014-11-20 9 views
8

Ich möchte, dass meine App die Dokumente speichert, die auf iCloud Drive erstellt werden, aber es fällt mir schwer, dem zu folgen, was Apple geschrieben hat. Hier ist, was ich bisher habe, aber ich bin mir nicht sicher, wohin ich von hier aus gehen soll.Speichern von iOS 8-Dokumenten auf iCloud Drive

UPDATE2

ich folgend in meinem Code muss manuell ein Dokument zu iCloud-Laufwerk speichern:

- (void)initializeiCloudAccessWithCompletion:(void (^)(BOOL available)) completion { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     self.ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; 
     if (self.ubiquityURL != nil) { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       NSLog(@"iCloud available at: %@", self.ubiquityURL); 
       completion(TRUE); 
      }); 
     } 
     else { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       NSLog(@"iCloud not available"); 
       completion(FALSE); 
      }); 
     } 
    }); 
} 
if (buttonIndex == 4) { 



    [self initializeiCloudAccessWithCompletion:^(BOOL available) { 

     _iCloudAvailable = available; 

     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 

     NSString *documentsDirectory = [paths objectAtIndex:0]; 

     NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:selectedCountry]; 

     NSURL* url = [NSURL fileURLWithPath: pdfPath]; 


     [self.manager setUbiquitous:YES itemAtURL:url destinationURL:self.ubiquityURL error:nil]; 


    }]; 

     } 

Ich habe die für den App-ID gesetzt Ansprüche und in Xcode selbst. Ich klicke auf die Schaltfläche, um sie auf iCloud Drive zu speichern, und es werden keine Fehler angezeigt. Die App stürzt nicht ab, aber auf meinem Mac in iCloud Drive wird nichts angezeigt. Die App läuft auf meinem iPhone 6 Plus über Test Flight mit iOS 8.1.1.

Wenn ich es auf Simulator laufen (ich weiß, dass es nicht wegen iCloud-Laufwerk funktioniert nicht mit Simulator arbeiten), erhalte ich den Absturz Fehler: 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]'

+0

'setUbiquitous: itemAtURL: destinationURL: error:' kehrt ein BOOL, ob die Operation erfolgreich war oder nicht. Was ist der Rückgabewert? Stellen Sie auch einen Zeiger auf ein 'NSError'-Objekt für den Parameter 'error' bereit. Wenn die Methode NEIN zurückgibt, erhalten Sie wahrscheinlich weitere Hinweise. – fguchelaar

+0

@fbuchelaar Entschuldigung, ich habe nie viel mit NSFileManager vermasselt, also geht mir das etwas über den Kopf. – user717452

Antwort

29

Nun, du hast mich selbst in dieser Angelegenheit interessiert, und als Ergebnis habe ich viel zu viel Zeit auf diese Frage verbracht, aber jetzt, Ich habe es funktioniert Ich hoffe es hilft dir auch!

File on my Mac

Um zu sehen, was im Hintergrund tatsächlich geschieht, können Sie einen Blick auf ~/Library/Mobile Documents/ haben, da dies der Ordner, wo die Dateien schließlich nach oben zeigen. Ein weiteres sehr cooles Dienstprogramm ist brctl, um zu überwachen, was nach dem Speichern einer Datei in der iCloud auf Ihrem Mac passiert. Führen Sie in einem Terminalfenster brctl log --wait --shorten aus, um das Protokoll zu starten.

Als Erstes aktivieren Sie die iCloud-Funktion (mit ausgewählten iCloud-Dokumenten) und geben Informationen zur iCloud Drive-Unterstützung (Enabling iCloud Drive Support). Ich musste auch meine Bundle-Version bumsen, bevor ich die App erneut ausführte; nahm mir etwas Zeit, um das herauszufinden. Fügen Sie folgendes zu Ihrem info.plist:

<key>NSUbiquitousContainers</key> 
<dict> 
    <key>iCloud.YOUR_BUNDLE_IDENTIFIER</key> 
    <dict> 
     <key>NSUbiquitousContainerIsDocumentScopePublic</key> 
     <true/> 
     <key>NSUbiquitousContainerSupportedFolderLevels</key> 
     <string>Any</string> 
     <key>NSUbiquitousContainerName</key> 
     <string>iCloudDriveDemo</string> 
    </dict> 
</dict> 

Weiter oben, der Code:

- (IBAction)btnStoreTapped:(id)sender { 
    // Let's get the root directory for storing the file on iCloud Drive 
    [self rootDirectoryForICloud:^(NSURL *ubiquityURL) { 
     NSLog(@"1. ubiquityURL = %@", ubiquityURL); 
     if (ubiquityURL) { 

      // We also need the 'local' URL to the file we want to store 
      NSURL *localURL = [self localPathForResource:@"demo" ofType:@"pdf"]; 
      NSLog(@"2. localURL = %@", localURL); 

      // Now, append the local filename to the ubiquityURL 
      ubiquityURL = [ubiquityURL URLByAppendingPathComponent:localURL.lastPathComponent]; 
      NSLog(@"3. ubiquityURL = %@", ubiquityURL); 

      // And finish up the 'store' action 
      NSError *error; 
      if (![[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:ubiquityURL error:&error]) { 
       NSLog(@"Error occurred: %@", error); 
      } 
     } 
     else { 
      NSLog(@"Could not retrieve a ubiquityURL"); 
     } 
    }]; 
} 

- (void)rootDirectoryForICloud:(void (^)(NSURL *))completionHandler { 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"]; 

     if (rootDirectory) { 
      if (![[NSFileManager defaultManager] fileExistsAtPath:rootDirectory.path isDirectory:nil]) { 
       NSLog(@"Create directory"); 
       [[NSFileManager defaultManager] createDirectoryAtURL:rootDirectory withIntermediateDirectories:YES attributes:nil error:nil]; 
      } 
     } 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      completionHandler(rootDirectory); 
     }); 
    }); 
} 

- (NSURL *)localPathForResource:(NSString *)resource ofType:(NSString *)type { 
    NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 
    NSString *resourcePath = [[documentsDirectory stringByAppendingPathComponent:resource] stringByAppendingPathExtension:type]; 
    return [NSURL fileURLWithPath:resourcePath]; 
} 

Ich habe eine Datei demo.pdf gespeichert im Ordner Dokumente genannt, die ich 'Hochladen' sein.

Ich werde ein paar Teile hervorheben:

URLForUbiquityContainerIdentifier: das Root-Verzeichnis zum Speichern von Dateien bieten, wenn Sie sie in Ihrem Mac in de icloud-Laufwerk zu zeigen, dann müssen Sie sie im Ordner Dokumente speichern, , so dass hier fügen wir diesen Ordner an die Wurzel:

NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"]; 

Sie müssen auch die Dateinamen in die URL hinzuzufügen, hier habe ich die Dateinamen aus der localURL kopieren (was demo.pdf):

// Now, append the local filename to the ubiquityURL 
ubiquityURL = [ubiquityURL URLByAppendingPathComponent:localURL.lastPathComponent]; 

Und das ist im Grunde ist es ...

Als Bonus zu überprüfen, wie Sie ein NSError Zeiger liefern können mögliche Fehlerinformationen zu erhalten:

// And finish up the 'store' action 
NSError *error; 
if (![[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:ubiquityURL error:&error]) { 
    NSLog(@"Error occurred: %@", error); 
} 
+0

Es sieht so aus, als würde ich meine Datei senden (Ich erhalte einen Fehler: Datei existiert bereits, wenn ich versuche, dieselbe Datei mehrmals zu schreiben), und ich sehe Sachen in 'brutal log' auf meinem Mac, aber ich weiß nicht ' t Siehe den Ordner auf iCloud.com oder auf meinem Mac. Irgendwelche Gedanken, warum das der Fall sein könnte? –

+2

EDIT: Muss 'CFBundleVersion' erhöhen. Wahnsinnig! http://StackOverflow.com/a/25328864/1148702 –

+0

Ich weiß, Wahnsinn .. Ich werde das Bit hervorheben es meine Antwort ein wenig mehr, Sie scheinen es übersehen zu haben :) – fguchelaar

1

Wenn Sie mit UIDocument und iCloud zu arbeiten beabsichtigen dieser Leitfaden von Apple, ist ziemlich gut: https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/Introduction/Introduction.html

EDITED: nicht jeder besseren Führer der Hand wissen Sie, so dass dies helfen kann:

Sie das ubiquityURL mit t holen müssen er URLForUbuiquityContainerIdentifier Funktion auf NSFileManager (die asynchron durchgeführt werden sollte). Sobald das erledigt ist, können Sie Code wie dem folgenden verwenden, um Ihr Dokument zu erstellen.

NSString* fileName = @"sampledoc"; 
NSURL* fileURL = [[self.ubiquityURL URLByAppendingPathComponent:@"Documents" isDirectory:YES] URLByAppendingPathComponent:fileName isDirectory:NO]; 

UIManagedDocument* document = [[UIManagedDocument alloc] initWithFileURL:fileURL]; 

document.persistentStoreOptions = @{ 
        NSMigratePersistentStoresAutomaticallyOption : @(YES), 
        NSInferMappingModelAutomaticallyOption: @(YES), 
        NSPersistentStoreUbiquitousContentNameKey: fileName, 
        NSPersistentStoreUbiquitousContentURLKey: [self.ubiquityURL URLByAppendingPathComponent:@"TransactionLogs" isDirectory:YES] 
}; 

[document saveToURL:fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { 

}]; 

Sie wollen auch prüfen, NSMetadataQuery mit Dokumenten von anderen Geräten hochgeladen zu erkennen und möglicherweise für Download-Warteschlange, und Beobachten der NSPersistentStoreDidImportUbiquitousContentChangesNotification über Änderungen via iCloud gemacht zu finden, unter anderem.

** Edit 2 **

Sieht aus wie Sie versuchen, eine PDF-Datei zu speichern, die nicht ganz ist, was Apple ein „Dokument“ in Bezug auf die iCloud Synchronisation hält. Sie müssen UIManagedDocument nicht verwenden. Entfernen Sie die letzten 3 Zeilen Ihres Beendigungshandlers und verwenden Sie stattdessen einfach die Funktion setUbiquitous:itemAtURL:destinationURL:error: von NSFileManager. Die erste URL sollte ein lokaler Pfad zur PDF sein. Die zweite URL sollte der Pfad innerhalb des Ubiquiuty-Containers sein, um als zu speichern.

Sie müssen vielleicht auch in NSFileCoordinator suchen. Ich denke, diese Anleitung von Apple die relevant sein können: https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/iCloud/iCloud.html

+1

Das ist etwas hilfreich, ich folge nur nicht, wie Apple all ihre Sachen schreibt. Ich suche gerade nach etwas, das sagt, wenn Sie Ihr Dokument erstellen, tun Sie das und speichern es in iCloud, damit es in iCloud Drive angezeigt wird. – user717452

+0

Überprüfen Sie das Update auf meine ursprüngliche Frage, bitte, um zu sehen, ob ich etwas vermasselt habe. – user717452

+0

Ich habe jetzt die Datei Metadata.plist in iCloud Drive gespeichert, aber nicht die PDF selbst. Was ist durcheinander? – user717452

Verwandte Themen