2014-11-20 3 views
8

Я хочу, чтобы мое приложение сохраняло документы, которые он создает для iCloud Drive, но мне нелегко следить за тем, что написало Apple. Вот что я до сих пор, но я не уверен, куда идти отсюда.Сохраните документы iOS 8 на iCloud Drive

UPDATE2

У меня есть следующий в моем коде вручную сохранить документ в ICloud Drive:

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


    }]; 

     } 

У меня есть пособия, установленные для App ID и в самой Xcode. Я нажимаю кнопку для сохранения на iCloud Drive, и никаких ошибок не появляется, приложение не падает, но на моем Mac в iCloud Drive ничего не отображается. Приложение работает на моем iPhone 6 Plus через тестовый рейс при использовании iOS 8.1.1.

Если я запустить его на Simulator (я знаю, что это не будет работать из-за ICloud Drive не работает с тренажером), я получаю ошибку аварии: 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]'

+0

'setUbiquitous: itemAtURL: DestinationUrl: ошибка:' возвращает BOOL ли операция была успешной или нет. Что такое возвращаемое значение? Также укажите указатель на объект 'NSError' для параметра' error'. Если метод возвращает NO, это, вероятно, даст вам еще несколько рекомендаций. – fguchelaar

+0

@fguchelaar жаль, что я никогда не много перепутал с NSFileManager, поэтому некоторые из них проходят над моей головой. – user717452

ответ

29

Ну, ты меня интересует в этом вопросе я и в результате я провел так много времени, по этому вопросу, но теперь, У меня есть работа, я надеюсь, что это поможет вам!

File on my Mac

Чтобы увидеть, что на самом деле происходит в фоновом режиме, вы можете посмотреть на ~/Library/Mobile Documents/, так как это папка, в которой файлы в конечном итоге будет отображаться. Еще одна очень полезная утилита - brctl, чтобы отслеживать, что происходит на вашем Mac после сохранения файла в iCloud. Запустите brctl log --wait --shorten из окна терминала, чтобы запустить журнал.

Первое, что нужно сделать после включения способности iCloud (с выбранными документами iCloud), предоставить информацию для поддержки iCloud Drive (Enabling iCloud Drive Support). Мне также пришлось ударить версию своего пакета, прежде чем запускать приложение; Мне потребовалось некоторое время, чтобы понять это. Добавьте следующие строки в 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> 

Далее, код:

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

У меня есть файл с именем demo.pdf хранятся в папке Documents, которую Я буду «загрузка».

Я выделю несколько частей:

URLForUbiquityContainerIdentifier: обеспечивает корневой каталог для хранения файлов, если вы хотите им показать в де ICloud Диска на Mac, то вам нужно хранить их в папке Документы , поэтому здесь мы добавим эту папку в корневом каталоге:

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

Кроме того, необходимо добавить имя файла в URL, здесь я копирую имя файла из localURL (который demo.pdf):

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

И это в основном это ...

В качестве бонуса, проверьте, как вы можете предоставить NSError указатель, чтобы получить потенциальную информацию об ошибке:

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

Похоже, что я отправляю свой файл (я получаю сообщение об ошибке: файл уже существует, когда я пытаюсь написать один и тот же файл много раз), и я вижу материал в «жестоком журнале» на моем Mac, но я не знаю, t увидеть папку на iCloud.com или на моем Mac. Любые мысли, почему это может быть так? –

+2

EDIT: Придется увеличивать 'CFBundleVersion'. Maddening! http://stackoverflow.com/a/25328864/1148702 –

+0

Я знаю, безумие. Я выделим, что немного его отвечу, вы, кажется, упустили это :) – fguchelaar

1

Если вы намерены работать с UIDocument и ICloud , это руководство от компании Apple довольно хорошо: https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/Introduction/Introduction.html

EDITED: не знаю ни одного лучшего гида руки, так что это может помочь:

Вам нужно будет принести ubiquityURL с помощью т он URLForUbuiquityContainerIdentifier функция на NSFileManager (что должно выполняться асинхронно). Как только это будет сделано, для создания документа вы можете использовать следующий код.

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) { 

}]; 

Вы также хотите, чтобы посмотреть в использовании NSMetadataQuery обнаружить документы, загруженные с других устройств и потенциально их в очередь для загрузки, и наблюдая за NSPersistentStoreDidImportUbiquitousContentChangesNotification, чтобы найти информацию об изменениях, внесенных через ICloud, между прочим.

** Edit 2 **

Похоже, вы пытаетесь сохранить PDF-файл, который не совсем то, что компания Apple рассматривает «документ» с точки зрения ICloud синхронизации. Не нужно использовать UIManagedDocument. Удалите последние 3 строки вашего обработчика завершения и вместо этого просто используйте функцию NSFileManager setUbiquitous:itemAtURL:destinationURL:error:. Первым URL-адресом должен быть локальный путь к PDF-файлу. Второй URL-адрес должен быть указан в контейнере ubiquiuty, чтобы сохранить его.

Возможно, вам также понадобится посмотреть в NSFileCoordinator. Я думаю, что это руководство от Apple, может быть наиболее актуальны: https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/iCloud/iCloud.html

+1

Это несколько полезно, я просто не понимаю, как Apple выписывает все свои вещи. Я просто ищу что-то, что говорит, когда вы делаете свой документ, вы делаете это, и это, чтобы сохранить его в iCloud, чтобы он появился в iCloud Drive. – user717452

+0

Проверьте обновление до моего оригинального вопроса, пожалуйста, чтобы узнать, не запутался ли я что-то. – user717452

+0

Теперь я сохранил файл Metadata.plist в iCloud Drive, но не сам PDF. Что перепуталось? – user717452

Смежные вопросы