Вопрос

Я знаю, что у iOS есть API для интеграции iCloud для приложений. Могу ли я интегрировать iCloud в приложения Mac? Будет ли реализация отличаться для приложений Mac для интеграции iCloud? Если да, есть ли учебные пособия и т. Д. или Справочные сайты?

Это было полезно?

Решение

Да. iCloud доступен на Mac.
Но документация Apple по этой теме все еще не очень полна. Единственные официальные ресурсы, которые я мог найти, где WWDC 2011 Сессия 107 Видео И некоторые заметки в "Что нового в Mac OS X"

Когда Lion & Icloud все еще были под NDA, я опубликовал свои выводы в DevForums Apple.
Это отредактированная версия эта почта:

Я использую модифицированную версию кода WWDC 2011 Session 107. (Переписано из видео) Мне пришлось удалить ручную экземпляр NSFileCoordinator, чтобы заставить образец работы (говорящий упоминает, что координатор «может не понадобиться в будущем»):::

- (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];
     }
}

Вышеуказанная апонтизация подключена к nsmenuitem, который проверяет, находится ли документ в iCloud или если его нужно загрузить:

- (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;
}

Контрольный список для неверных задач, которые необходимы для работы с хранением документов iCloud:

  • Проверьте, активируется ли поддержка ICLOUD в утилите сертификата разработчика
  • Создайте идентификатор контейнера в Abiquity в утилите сертификата разработчика
  • Идентификатор контейнера в повсеместном распространении начинается с идентификатора/индивидуального идентификатора вашей команды (см. Вкладку учетной записи в Центре членов)
  • Включить права в XCODE
  • Добавьте свой идентификатор контейнера в повсеместном распространении в файл Valiements (как описано здесь «Запрашивая права на хранение iCloud».)
  • Мой идентификатор пакета PLIST должен был соответствовать идентификатору контейнера повсеместного использования (за исключением идентификатора команды)
  • Я не смог добавить суффиксы (например, "app.example.osx", "app.example.ipad", ... как предложено в DOC выше)
  • Создать профиль подготовки
  • Убедитесь, что профиль установлен на вашем Dev Machine и отображается в XCode & System Preferences
  • Включите подписание кода в настройках сборки приложений

Другие советы

Есть документ Apple, который подробно описан во всех аспектах http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/icloud/icloud.html

Одна важная проблема с кодом, размещенным здесь, заключается в том, что в нем нет команды в идентификаторе, предоставленной UrlForubiquityContainerIdentifier, даже если он упоминается в контрольном списке, оставляя его вообще, чтобы быть автоматически заполненным из прав, кажется лучшим потуханием.

Лично единственные изменения, которые мне пришлось внести, чтобы Icloud пошел в мое приложение, были:

  1. Проверьте кнопку «Использовать iCloud» на веб -сайте разработчика для идентификатора моего приложения
  2. Загрузите регенерированное положение для этого идентификатора приложения
  3. Проверьте «Включить право» в кратком изложении XCODE

Это было все, вот, надеюсь, более четкий пример кода (должен работать как для iOS, так и для OSX):

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]);               
    }      
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top