Frage

Mir ist bewusst, dass iOS APIs hat, um iCloud für die Apps zu integrieren. Kann ich iCloud auch in Mac -Apps integrieren? Wird die Implementierung für Mac -Apps unterschiedlich sein, iCloud zu integrieren? Wenn ja, gibt es Tutorials usw. oder Referenzwebsites?

War es hilfreich?

Lösung

Ja. iCloud ist auf dem Mac erhältlich.
Die Dokumentation von Apple für dieses Thema ist jedoch immer noch nicht sehr vollständig. Die einzigen offiziellen Ressourcen, die ich finden konnte, wo der WWDC 2011 Sitzung 107 Video und einige Notizen in "Was ist neu in Mac OS X"

Als Lion & iCloud noch unter NDA standen, habe ich meine Ergebnisse in Apples DevForums veröffentlicht.
Dies ist eine bearbeitete Version von dieser Beitrag:

Ich verwende eine modifizierte Version des WWDC 2011 Session 107 Code. (transkribiert aus dem Video) Ich musste die manuelle Instanziierung von NSFilecoordinator entfernen, um das Beispiel zum Laufen zu bringen (der Sprecher erwähnt, dass der Koordinator "in Zukunft möglicherweise nicht benötigt wird"):

- (IBAction)moveToOrFromCloud:(id)sender
{
     NSFileManager* fm = [NSFileManager defaultManager];
     NSURL* fileURL = [[self document] fileURL];
     BOOL shouldMakeUbiquitous = [sender tag] == 1;
     NSURL* destinationURL;
     if(shouldMakeUbiquitous)
     {
          NSURL* rootURL = [fm URLForUbiquityContainerIdentifier:@"app.example"];
          NSURL* directoryURL = [rootURL URLByAppendingPathComponent:@"Documents"];
          [fm createDirectoryAtURL:directoryURL withIntermediateDirectories:NO attributes:nil error:NULL];
          destinationURL = [directoryURL URLByAppendingPathComponent:[fileURL lastPathComponent]];
     }
     else
     {
          destinationURL = [[[fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0] URLByAppendingPathComponent:[fileURL lastPathComponent]];
     }
     NSError* error;
     if(![fm setUbiquitous:shouldMakeUbiquitous itemAtURL:fileURL destinationURL:destinationURL error:&error])
     {
          [[self document] presentError:error modalForWindow:[[self document] windowForSheet] delegate:nil didPresentSelector:NULL contextInfo:NULL];
     }
     else
     {
          [[self document] setFileURL:destinationURL];
          [[self document] setFileModificationDate:nil];
     }
}

Die obige Ibaktion ist mit einem NSMenuitem verbunden, das überprüft, ob sich das Dokument bereits in iCloud befindet oder ob es hochgeladen werden muss:

- (BOOL)validateMenuItem:(NSMenuItem*)item 
{
     SEL action = [item action];
     if (action == @selector(moveToOrFromCloud:))
     {
          BOOL isUbiquitous = [[NSFileManager defaultManager] isUbiquitousItemAtURL:[[self document] fileURL]];
          [item setTitle:isUbiquitous ? @"Remove from Cloud": "Move to Cloud"];
          [item setTag:isUbiquitous?0:1];
          return [self.document fileURL] != nil;
     }    
     return YES;
}

Checkliste für Nicht-Code-Aufgaben, die erforderlich sind, um den iCloud-Dokumentenspeicher funktionieren zu können:

  • Überprüfen Sie, ob der iCloud -Support im Dienstprogramm für Entwicklerzertifikat aktiviert wird
  • Erstellen Sie eine Ubiquity -Container -ID im Entwicklerzertifikat -Dienstprogramm
  • Die Ubiquity -Container -ID beginnt mit Ihrer Team -ID/individuellen ID (siehe Registerkarte Konto im Mitgliedszentrum)
  • Berechtigungen in Xcode ermöglichen
  • Fügen Sie Ihre Ubiquity -Container -ID der Berichterstattungsdatei hinzu (wie hier beschrieben „Anfordern von Berechtigungen für den iCloud -Speicher.“).
  • Meine Plist -Bundle -ID musste mit der Ubiquity -Container -ID übereinstimmen (mit Ausnahme der Team -ID)
  • Ich konnte Suffixe nicht hinzufügen (z. B. "app.example.osx", "app.example.ipad", ... wie im obigen Dokument vorgeschlagen)
  • Erstellen Sie ein Bereitstellungsprofil
  • Stellen Sie sicher, dass das Profil auf Ihrem Entwicklungsgerät installiert ist und in Xcode- und Systemeinstellungen angezeigt wird
  • Aktivieren Sie die Code -Signierung in Ihren Apps Build -Einstellungen

Andere Tipps

Es gibt ein Dokument von Apple, das in allen Aspekten detailliert ist http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneoprogrammingguide/icloud/icloud.html

Ein wesentliches Problem mit dem hier veröffentlichten Code ist, dass das Team in der Kennung, die an UrlForubiquityContainerIdentifier gegeben wurde, nicht enthält, selbst wenn es in der Checkliste erwähnt wird, sodass es sich nicht um den besten Acloach befindet.

Persönlich waren die einzigen Änderungen, die ich vornehmen musste, um iCloud in meine App in Gang zu bringen:

  1. Überprüfen Sie die Schaltfläche "iCloud" auf der Entwickler -Website für meine App -ID
  2. Laden Sie die regenerierte Bestimmung für diese App -ID herunter
  3. Überprüfen Sie in der Xcode -Zusammenfassung "Berechtigungen“ in Xcode

Das war alles, hier ist ein hoffentlich klarerer Beispielcode (sollte sowohl für iOS als auch für OSX funktionieren):

NSURL *url = [self getiCloudURLFor:@"foo.bar" containerID:nil]; //leaving nil so it is auto filled from entitlements
if (url) {
    NSError *error;
    if (![[NSFileManager defaultManager] startDownloadingUbiquitousItemAtURL:url error:&error]) {
        NSLog(@"Error downloading/syncing %@ (%@)",[url path],[error description]);                
    }else{
        NSLog(@"Started downloading/syncing %@",[url path]);              
    }         
}

NSArray *conflicts = [NSFileVersion unresolvedConflictVersionsOfItemAtURL:url];
for (NSFileVersion *conflict in conflicts) {
    NSLog(@"Conflicting %@ at %@ by %@ from %@",[url path],[conflict URL],[conflict localizedNameOfSavingComputer],[conflict modificationDate]);   
}

- (NSURL*)getiCloudURLFor:(NSString*)fileName containerID:(NSString*)containerID
{   
    NSFileManager *fm = [NSFileManager defaultManager];  

    NSURL *rootURL = [fm URLForUbiquityContainerIdentifier:containerID];
    if (rootURL) {
        NSURL *directoryURL = [rootURL URLByAppendingPathComponent:@"Documents"];
        if (![fm fileExistsAtPath:[directoryURL path]]) [fm createDirectoryAtURL:directoryURL withIntermediateDirectories:NO attributes:nil error:NULL];
        NSURL *cloudURL = [directoryURL URLByAppendingPathComponent:fileName];
        if (![fm isUbiquitousItemAtURL:cloudURL]) [self makeUbiquitousItemAtURL:cloudURL];//this only runs once per filename when it is first added to iCloud
        return cloudURL;
    }else{
        return [[[fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0] URLByAppendingPathComponent:fileName]; //no cloud
    }     
    return nil;
}

- (void)makeUbiquitousItemAtURL:(NSURL*)cloudURL
{
    NSFileManager *fm = [NSFileManager defaultManager];

    NSURL *localURL = [[[fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0] URLByAppendingPathComponent:[cloudURL lastPathComponent]]; 
    if (![fm fileExistsAtPath:[localURL path]]) [fm createFileAtPath:[localURL path] contents:nil attributes:nil];
    NSError *error;            
    if(![fm setUbiquitous:YES itemAtURL:localURL destinationURL:cloudURL error:&error])  {
        NSLog(@"Error making %@ ubiquituous at %@ (%@)",[localURL path],[cloudURL path],[error description]);
    }else{
        NSLog(@"Made %@ ubiquituous at %@",[localURL lastPathComponent],[cloudURL path]);               
    }      
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top