Быстрая запись / сохранение / перемещение файла документа на диск iCloud
Более двух дней я пытался записать файл на диск iCloud. Я пытался написать простой текстовый файл напрямую, локально, затем переместить его, используя UIDocumentMenuViewController и т. Д. Я не получаю никаких ошибок с моим кодом и пошагово через отладчик, он выглядит успешно, но когда я проверяю, существует ли файл или по крайней мере, каталог iCloud, там ничего нет. Я попробовал и симулятор, и мой iPhone, запустив синхронизацию iCloud и все остальное, о чем я могу подумать.
Моя главная цель - просто записать текстовый файл на диск iCloud, который позже будет файлом "цифр"
Я настроил файл plist и мои права:
<key>NSUbiquitousContainers</key>
<dict>
<key>iCloud.com.paul.c.$(PRODUCT_NAME:rfc1034identifier)</key>
<dict>
<key>NSUbiquitousContainerIsDocumentScopePublic</key>
<true/>
<key>NSUbiquitousContainerName</key>
<string>myCloudTest</string>
<key>NSUbiquitousContainerSupportedFolderLevels</key>
<string>Any</string>
</dict>
</dict>
Я также столкнулся с версией пакета, как указано на: Сохранить документы iOS 8 на iCloud Drive
Я попробовал десятки учебных пособий без удачи. Мой последний код основан на этом примере: https://medium.com/ios-os-x-development/icloud-drive-documents-1a46b5706fe1
Вот мой код:
@IBAction func ExportFile(sender: AnyObject) {
var error:NSError?
let iCloudDocumentsURL = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier(nil)?.URLByAppendingPathComponent("myCloudTest")
//is iCloud working?
if iCloudDocumentsURL != nil {
//Create the Directory if it doesn't exist
if (!NSFileManager.defaultManager().fileExistsAtPath(iCloudDocumentsURL!.path!, isDirectory: nil)) {
//This gets skipped after initial run saying directory exists, but still don't see it on iCloud
NSFileManager.defaultManager().createDirectoryAtURL(iCloudDocumentsURL!, withIntermediateDirectories: true, attributes: nil, error: nil)
}
} else {
println("iCloud is NOT working!")
// return
}
if ((error) != nil) {
println("Error creating iCloud DIR")
}
//Set up directorys
let localDocumentsURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: .UserDomainMask).last as! NSURL
//Add txt file to my local folder
let myTextString = NSString(string: "HELLO WORLD")
let myLocalFile = localDocumentsURL.URLByAppendingPathComponent("myTextFile.txt")
let written = myTextString.writeToURL(myLocalFile, atomically: true, encoding: NSUTF8StringEncoding, error: &error)
if ((error) != nil){
println("Error saving to local DIR")
}
//If file exists on iCloud remove it
var isDir:ObjCBool = false
if (NSFileManager.defaultManager().fileExistsAtPath(iCloudDocumentsURL!.path!, isDirectory: &isDir)) {
NSFileManager.defaultManager().removeItemAtURL(iCloudDocumentsURL!, error: &error)
}
//copy from my local to iCloud
if (error == nil && !NSFileManager.defaultManager().copyItemAtURL(localDocumentsURL, toURL: iCloudDocumentsURL!, error: &error)) {
println(error?.localizedDescription);
}
Спасибо, что нашли время для этого.
Ура, Пол
Я запустил код на своем iphone после кода выше:
var error:NSError?
let iCloudDocumentsURL = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier(nil) //?.URLByAppendingPathComponent("myCloudTest")
var fileManager: NSFileManager = NSFileManager()
var fileList: NSArray = fileManager.contentsOfDirectoryAtURL(iCloudDocumentsURL!, includingPropertiesForKeys: nil, options: nil, error: &error)!
var filesStr: NSMutableString = NSMutableString(string: "Files in iCloud folder \n")
for s in fileList {
println(s)
}
и он печатает путь к моему текстовому файлу: file:///private/var/mobile/Library/Mobile%20Documents/iCloud~com~paul~c~myApp/MyTextFile.txt
Мой файл там, я просто не вижу его на диске iCloud.
5 ответов
У меня была эта проблема. Я последовал совету здесь и обнаружил, что мой Info.plist
Ключ был неверным. Однажды я изменил это на iCloud.MY_BUNDLE_IDENTIFIER
(т.е. скопировать строку из CFBundleIdentifier
ключ выше в Info.plist
) все заработало.
Удаление.com из вашего ключа может решить вашу проблему.
FWIW:
Я также узнал, что имя проекта в идентификаторе пакета важно.
Мой идентификатор пакета проекта был примерно таким: aaa-bbb-ccc-ddd
Я не мог заставить работать iCloud.
Затем я переименовал его в: aaa-bbb.ccc-ddd
Это начало работать.
Вам нужно сделать 2 вещи
- Сделайте то, что сказал @rick Andrews: «Однажды я изменил его на iCloud.MY_BUNDLE_IDENTIFIER (т.е. скопировал строку из ключа CFBundleIdentifier выше в Info.plist)»
- Храните ваши файлы в подпапке контейнеров Documents
struct iCloudStore {
public var containerUrl: URL! {
return fileManager.url(forUbiquityContainerIdentifier: nil)!
}
public var documents: URL! {
return containerUrl.appendingPathComponent("Documents", isDirectory: true)
}
private let fileManager: FileManager = FileManager.default
func store(url: URL) {
// move ulr into the documents folder as a file
let fileID = "\(UUID().uuidString).<#extension#>"
let icloudFile = documents.appendingPathComponent(fileID, isDirectory: false)
try fileManager.copyItem(at: url, to: icloudFile)
}
}
Я полагаю, что нашел способ вернуть все в синхронизацию, не прибегая к постоянному увеличению моего номера пакета. Я пытался сделать это несколько раз, внося изменения в области "возможностей" хранилища значений ключей /iCloud Documents/CloudKit, и, похоже, это работает каждый раз.
- Выйдите из iCloud на своем Mac
- Выйдите из iCloud на своем симуляторе
- Войдите в iCloud на своем Mac
- Войдите в iCloud на своем симуляторе
- Сделайте чистую сборку из XCode (Shift-Cmd-K)
Похоже, это сбрасывает синхронизацию структур папок, когда приложение пишет в каталог документов iCloud - без необходимости касаться номера вашего пакета. Это займет немного больше времени, но я немного ОКР и предпочитаю, чтобы мой первый запуск приложения начинался с 1!
Может быть, есть правило для названия контейнера.
Я пробовал следующие имена.
○: iSheet
×: sheetFiles
×:com.myname.sheetFiles