Swift write/save/move 一个文档文件到 iCloud 驱动器
Swift write/save/move a document file to iCloud drive
两天多来我一直在尝试将文件写入 iCloud 驱动器。我试过直接在本地编写一个简单的文本文件,然后使用 UIDocumentMenuViewController 等移动它。我的代码没有收到任何错误并单步执行调试器,它看起来很成功,但是当我检查文件是否存在或至少 iCloud 目录,那里什么都没有。我在模拟器和我的 iPhone 上都试过了,触发 iCloud 同步,以及我能想到的一切。
我的主要目标是简单地向 iCloud 驱动器写入一个文本文件,稍后将是 "numbers" 文件
我已经设置了我的 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>
我还通过捆绑版本进行了升级,如下所述:Save iOS 8 Documents to 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 驱动器上看不到它。
我遇到了这个问题。我 followed the advice here 并且我发现我的 Info.plist
密钥不正确。一旦我将它更改为 iCloud.MY_BUNDLE_IDENTIFIER
(即从 Info.plist
中更高的 CFBundleIdentifier
键复制字符串),它就开始工作了。
从您的密钥中删除 .com 可能会解决您的问题。
FWIW:
我还发现包 ID 中的项目名称很重要。
我的项目包 ID 类似于以下内容:aaa-bbb-ccc-ddd
我无法让 iCloud 工作。
然后我改名为:aaa-bbb.ccc-ddd
它开始工作了。
我相信我已经找到了一种让所有内容恢复同步的方法,而无需经常 "bump" 我的捆绑包编号。我在键值 storage/iCloud Documents/CloudKit 的 "capabilities" 区域内进行更改时尝试了多次,似乎每次都有效。
- 在您的 Mac
上退出 iCloud
- 在模拟器上退出 iCloud
- 在您的 Mac
上重新登录 iCloud
- 在模拟器上重新登录 iCloud
- 从 XCode (Shift-Cmd-K)
进行干净构建
当您的 App 正在写入您的 iCloud 文档目录时,这似乎可以重置文件夹结构的同步 - 无需触摸您的捆绑包编号。完成它需要更长的时间,但我有点强迫症,有点喜欢我的初始应用程序启动以 1 开头!
可能容器名称有规定。
我尝试了以下名称。
○:iSheet
×:sheetFiles
×:com.myname.sheetFiles
两天多来我一直在尝试将文件写入 iCloud 驱动器。我试过直接在本地编写一个简单的文本文件,然后使用 UIDocumentMenuViewController 等移动它。我的代码没有收到任何错误并单步执行调试器,它看起来很成功,但是当我检查文件是否存在或至少 iCloud 目录,那里什么都没有。我在模拟器和我的 iPhone 上都试过了,触发 iCloud 同步,以及我能想到的一切。
我的主要目标是简单地向 iCloud 驱动器写入一个文本文件,稍后将是 "numbers" 文件
我已经设置了我的 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>
我还通过捆绑版本进行了升级,如下所述:Save iOS 8 Documents to 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 驱动器上看不到它。
我遇到了这个问题。我 followed the advice here 并且我发现我的 Info.plist
密钥不正确。一旦我将它更改为 iCloud.MY_BUNDLE_IDENTIFIER
(即从 Info.plist
中更高的 CFBundleIdentifier
键复制字符串),它就开始工作了。
从您的密钥中删除 .com 可能会解决您的问题。
FWIW:
我还发现包 ID 中的项目名称很重要。
我的项目包 ID 类似于以下内容:aaa-bbb-ccc-ddd
我无法让 iCloud 工作。
然后我改名为:aaa-bbb.ccc-ddd
它开始工作了。
我相信我已经找到了一种让所有内容恢复同步的方法,而无需经常 "bump" 我的捆绑包编号。我在键值 storage/iCloud Documents/CloudKit 的 "capabilities" 区域内进行更改时尝试了多次,似乎每次都有效。
- 在您的 Mac 上退出 iCloud
- 在模拟器上退出 iCloud
- 在您的 Mac 上重新登录 iCloud
- 在模拟器上重新登录 iCloud
- 从 XCode (Shift-Cmd-K) 进行干净构建
当您的 App 正在写入您的 iCloud 文档目录时,这似乎可以重置文件夹结构的同步 - 无需触摸您的捆绑包编号。完成它需要更长的时间,但我有点强迫症,有点喜欢我的初始应用程序启动以 1 开头!
可能容器名称有规定。
我尝试了以下名称。
○:iSheet
×:sheetFiles
×:com.myname.sheetFiles