使用 iCloud 文档存储的最佳方式
Best way to use iCloud Documents Storage
我目前在 iOS 应用程序中使用本地存储。用户数据存储在文档目录中,现在我打算改用 iCloud 文档存储。
我打算这样做:
正在检查 iCloud 在设备上是否可用
如果是,使用URLForUbiquityContainerIdentifier获取iCloud容器URL
将新文件和文档保存到这个新 URL
为此,我正在使用此代码 return 文档文件夹(iCloud 或本地)的 URL
class CloudDataManager {
class func getDocumentDiretoryURL() -> NSURL {
let localDocumentsURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: .UserDomainMask).last! as NSURL
let iCloudDocumentsURL = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier(nil)?.URLByAppendingPathComponent("Documents")
if userDefault.boolForKey("useCloud") && iCloudDocumentsURL != nil {
return iCloudDocumentsURL!
} else {
return localDocumentsURL
}
}
}
这是最佳做法吗?
我担心如果有一天 iCloud 不可用时会出现问题,因此将使用本地目录而不是云容器并且将是空的。
谢谢。
检查此 link:iCloud basics and code sample
如果你存储的信息很简单,最好使用NSUserDefaults。您不想向 iCloud 询问基本信息。
感谢上面的评论和进一步的阅读,我找到了解决问题的方法。
我是这样决定的:
- iCloud 将默认激活(如果可能)
- 用户可以在应用程序中使用 UISwitch disable/enable iCloud
- 当用户禁用 iCloud 时,所有 iCloud 文件都将传输到本地
- 当用户启用 iCloud 时,所有本地文件将传输到 iCloud Ubiquity 容器中
- 没有数据合并
点赞此数据不会丢失
我想几乎每个人都会使用iCloud,一切都会透明无痛。无论如何,我同步的文件非常小,所以它应该可以正常工作(到目前为止它可以)。
我有5个简单方法:
- 检查 iCloud 是否可用的方法
- 方法return 文档URL 根据用户选择(iCloud 或本地)
- 删除目录中所有文件的方法(应用程序使用的文件)
- 将文件从本地目录移动到 iCloud 容器的方法
- 将文件从 iCloud 容器移动到本地目录的方法
这是我的 class 处理问题
class CloudDataManager {
static let sharedInstance = CloudDataManager() // Singleton
struct DocumentsDirectory {
static let localDocumentsURL: NSURL? = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: .UserDomainMask).last! as NSURL
static let iCloudDocumentsURL: NSURL? = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier(nil)?.URLByAppendingPathComponent("Documents")
}
// Return the Document directory (Cloud OR Local)
// To do in a background thread
func getDocumentDiretoryURL() -> NSURL {
print(DocumentsDirectory.iCloudDocumentsURL)
print(DocumentsDirectory.localDocumentsURL)
if userDefault.boolForKey("useCloud") && isCloudEnabled() {
return DocumentsDirectory.iCloudDocumentsURL!
} else {
return DocumentsDirectory.localDocumentsURL!
}
}
// Return true if iCloud is enabled
func isCloudEnabled() -> Bool {
if DocumentsDirectory.iCloudDocumentsURL != nil { return true }
else { return false }
}
// Delete All files at URL
func deleteFilesInDirectory(url: NSURL?) {
let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtPath(url!.path!)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.removeItemAtURL(url!.URLByAppendingPathComponent(file))
print("Files deleted")
} catch let error as NSError {
print("Failed deleting files : \(error)")
}
}
}
// Move local files to iCloud
// iCloud will be cleared before any operation
// No data merging
func moveFileToCloud() {
if isCloudEnabled() {
deleteFilesInDirectory(DocumentsDirectory.iCloudDocumentsURL!) // Clear destination
let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtPath(DocumentsDirectory.localDocumentsURL!.path!)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.setUbiquitous(true,
itemAtURL: DocumentsDirectory.localDocumentsURL!.URLByAppendingPathComponent(file),
destinationURL: DocumentsDirectory.iCloudDocumentsURL!.URLByAppendingPathComponent(file))
print("Moved to iCloud")
} catch let error as NSError {
print("Failed to move file to Cloud : \(error)")
}
}
}
}
// Move iCloud files to local directory
// Local dir will be cleared
// No data merging
func moveFileToLocal() {
if isCloudEnabled() {
deleteFilesInDirectory(DocumentsDirectory.localDocumentsURL!)
let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtPath(DocumentsDirectory.iCloudDocumentsURL!.path!)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.setUbiquitous(false,
itemAtURL: DocumentsDirectory.iCloudDocumentsURL!.URLByAppendingPathComponent(file),
destinationURL: DocumentsDirectory.localDocumentsURL!.URLByAppendingPathComponent(file))
print("Moved to local dir")
} catch let error as NSError {
print("Failed to move file to local dir : \(error)")
}
}
}
}
}
对于那些想要使用 SWIFT 3 的人:
注意:我只是复制而不是移动数据。但是目标路径在复制数据之前被清除了..
class CloudDataManager {
static let sharedInstance = CloudDataManager() // Singleton
struct DocumentsDirectory {
static let localDocumentsURL = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: .userDomainMask).last!
static let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
}
// Return the Document directory (Cloud OR Local)
// To do in a background thread
func getDocumentDiretoryURL() -> URL {
if isCloudEnabled() {
return DocumentsDirectory.iCloudDocumentsURL!
} else {
return DocumentsDirectory.localDocumentsURL
}
}
// Return true if iCloud is enabled
func isCloudEnabled() -> Bool {
if DocumentsDirectory.iCloudDocumentsURL != nil { return true }
else { return false }
}
// Delete All files at URL
func deleteFilesInDirectory(url: URL?) {
let fileManager = FileManager.default
let enumerator = fileManager.enumerator(atPath: url!.path)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.removeItem(at: url!.appendingPathComponent(file))
print("Files deleted")
} catch let error as NSError {
print("Failed deleting files : \(error)")
}
}
}
// Copy local files to iCloud
// iCloud will be cleared before any operation
// No data merging
func copyFileToCloud() {
if isCloudEnabled() {
deleteFilesInDirectory(url: DocumentsDirectory.iCloudDocumentsURL!) // Clear all files in iCloud Doc Dir
let fileManager = FileManager.default
let enumerator = fileManager.enumerator(atPath: DocumentsDirectory.localDocumentsURL.path)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.copyItem(at: DocumentsDirectory.localDocumentsURL.appendingPathComponent(file), to: DocumentsDirectory.iCloudDocumentsURL!.appendingPathComponent(file))
print("Copied to iCloud")
} catch let error as NSError {
print("Failed to move file to Cloud : \(error)")
}
}
}
}
// Copy iCloud files to local directory
// Local dir will be cleared
// No data merging
func copyFileToLocal() {
if isCloudEnabled() {
deleteFilesInDirectory(url: DocumentsDirectory.localDocumentsURL)
let fileManager = FileManager.default
let enumerator = fileManager.enumerator(atPath: DocumentsDirectory.iCloudDocumentsURL!.path)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.copyItem(at: DocumentsDirectory.iCloudDocumentsURL!.appendingPathComponent(file), to: DocumentsDirectory.localDocumentsURL.appendingPathComponent(file))
print("Moved to local dir")
} catch let error as NSError {
print("Failed to move file to local dir : \(error)")
}
}
}
}
}
我目前在 iOS 应用程序中使用本地存储。用户数据存储在文档目录中,现在我打算改用 iCloud 文档存储。
我打算这样做:
正在检查 iCloud 在设备上是否可用
如果是,使用URLForUbiquityContainerIdentifier获取iCloud容器URL
将新文件和文档保存到这个新 URL
为此,我正在使用此代码 return 文档文件夹(iCloud 或本地)的 URL
class CloudDataManager {
class func getDocumentDiretoryURL() -> NSURL {
let localDocumentsURL = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: .UserDomainMask).last! as NSURL
let iCloudDocumentsURL = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier(nil)?.URLByAppendingPathComponent("Documents")
if userDefault.boolForKey("useCloud") && iCloudDocumentsURL != nil {
return iCloudDocumentsURL!
} else {
return localDocumentsURL
}
}
}
这是最佳做法吗? 我担心如果有一天 iCloud 不可用时会出现问题,因此将使用本地目录而不是云容器并且将是空的。 谢谢。
检查此 link:iCloud basics and code sample
如果你存储的信息很简单,最好使用NSUserDefaults。您不想向 iCloud 询问基本信息。
感谢上面的评论和进一步的阅读,我找到了解决问题的方法。
我是这样决定的:
- iCloud 将默认激活(如果可能)
- 用户可以在应用程序中使用 UISwitch disable/enable iCloud
- 当用户禁用 iCloud 时,所有 iCloud 文件都将传输到本地
- 当用户启用 iCloud 时,所有本地文件将传输到 iCloud Ubiquity 容器中
- 没有数据合并
点赞此数据不会丢失
我想几乎每个人都会使用iCloud,一切都会透明无痛。无论如何,我同步的文件非常小,所以它应该可以正常工作(到目前为止它可以)。
我有5个简单方法:
- 检查 iCloud 是否可用的方法
- 方法return 文档URL 根据用户选择(iCloud 或本地)
- 删除目录中所有文件的方法(应用程序使用的文件)
- 将文件从本地目录移动到 iCloud 容器的方法
- 将文件从 iCloud 容器移动到本地目录的方法
这是我的 class 处理问题
class CloudDataManager {
static let sharedInstance = CloudDataManager() // Singleton
struct DocumentsDirectory {
static let localDocumentsURL: NSURL? = NSFileManager.defaultManager().URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: .UserDomainMask).last! as NSURL
static let iCloudDocumentsURL: NSURL? = NSFileManager.defaultManager().URLForUbiquityContainerIdentifier(nil)?.URLByAppendingPathComponent("Documents")
}
// Return the Document directory (Cloud OR Local)
// To do in a background thread
func getDocumentDiretoryURL() -> NSURL {
print(DocumentsDirectory.iCloudDocumentsURL)
print(DocumentsDirectory.localDocumentsURL)
if userDefault.boolForKey("useCloud") && isCloudEnabled() {
return DocumentsDirectory.iCloudDocumentsURL!
} else {
return DocumentsDirectory.localDocumentsURL!
}
}
// Return true if iCloud is enabled
func isCloudEnabled() -> Bool {
if DocumentsDirectory.iCloudDocumentsURL != nil { return true }
else { return false }
}
// Delete All files at URL
func deleteFilesInDirectory(url: NSURL?) {
let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtPath(url!.path!)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.removeItemAtURL(url!.URLByAppendingPathComponent(file))
print("Files deleted")
} catch let error as NSError {
print("Failed deleting files : \(error)")
}
}
}
// Move local files to iCloud
// iCloud will be cleared before any operation
// No data merging
func moveFileToCloud() {
if isCloudEnabled() {
deleteFilesInDirectory(DocumentsDirectory.iCloudDocumentsURL!) // Clear destination
let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtPath(DocumentsDirectory.localDocumentsURL!.path!)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.setUbiquitous(true,
itemAtURL: DocumentsDirectory.localDocumentsURL!.URLByAppendingPathComponent(file),
destinationURL: DocumentsDirectory.iCloudDocumentsURL!.URLByAppendingPathComponent(file))
print("Moved to iCloud")
} catch let error as NSError {
print("Failed to move file to Cloud : \(error)")
}
}
}
}
// Move iCloud files to local directory
// Local dir will be cleared
// No data merging
func moveFileToLocal() {
if isCloudEnabled() {
deleteFilesInDirectory(DocumentsDirectory.localDocumentsURL!)
let fileManager = NSFileManager.defaultManager()
let enumerator = fileManager.enumeratorAtPath(DocumentsDirectory.iCloudDocumentsURL!.path!)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.setUbiquitous(false,
itemAtURL: DocumentsDirectory.iCloudDocumentsURL!.URLByAppendingPathComponent(file),
destinationURL: DocumentsDirectory.localDocumentsURL!.URLByAppendingPathComponent(file))
print("Moved to local dir")
} catch let error as NSError {
print("Failed to move file to local dir : \(error)")
}
}
}
}
}
对于那些想要使用 SWIFT 3 的人: 注意:我只是复制而不是移动数据。但是目标路径在复制数据之前被清除了..
class CloudDataManager {
static let sharedInstance = CloudDataManager() // Singleton
struct DocumentsDirectory {
static let localDocumentsURL = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: .userDomainMask).last!
static let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
}
// Return the Document directory (Cloud OR Local)
// To do in a background thread
func getDocumentDiretoryURL() -> URL {
if isCloudEnabled() {
return DocumentsDirectory.iCloudDocumentsURL!
} else {
return DocumentsDirectory.localDocumentsURL
}
}
// Return true if iCloud is enabled
func isCloudEnabled() -> Bool {
if DocumentsDirectory.iCloudDocumentsURL != nil { return true }
else { return false }
}
// Delete All files at URL
func deleteFilesInDirectory(url: URL?) {
let fileManager = FileManager.default
let enumerator = fileManager.enumerator(atPath: url!.path)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.removeItem(at: url!.appendingPathComponent(file))
print("Files deleted")
} catch let error as NSError {
print("Failed deleting files : \(error)")
}
}
}
// Copy local files to iCloud
// iCloud will be cleared before any operation
// No data merging
func copyFileToCloud() {
if isCloudEnabled() {
deleteFilesInDirectory(url: DocumentsDirectory.iCloudDocumentsURL!) // Clear all files in iCloud Doc Dir
let fileManager = FileManager.default
let enumerator = fileManager.enumerator(atPath: DocumentsDirectory.localDocumentsURL.path)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.copyItem(at: DocumentsDirectory.localDocumentsURL.appendingPathComponent(file), to: DocumentsDirectory.iCloudDocumentsURL!.appendingPathComponent(file))
print("Copied to iCloud")
} catch let error as NSError {
print("Failed to move file to Cloud : \(error)")
}
}
}
}
// Copy iCloud files to local directory
// Local dir will be cleared
// No data merging
func copyFileToLocal() {
if isCloudEnabled() {
deleteFilesInDirectory(url: DocumentsDirectory.localDocumentsURL)
let fileManager = FileManager.default
let enumerator = fileManager.enumerator(atPath: DocumentsDirectory.iCloudDocumentsURL!.path)
while let file = enumerator?.nextObject() as? String {
do {
try fileManager.copyItem(at: DocumentsDirectory.iCloudDocumentsURL!.appendingPathComponent(file), to: DocumentsDirectory.localDocumentsURL.appendingPathComponent(file))
print("Moved to local dir")
} catch let error as NSError {
print("Failed to move file to local dir : \(error)")
}
}
}
}
}