使用iCloud文档存储的最佳方法
我目前在我的iOS应用程序中使用本地存储。 用户数据存储在文档目录中,现在我计划使用iCloud Documents存储。
我打算这样做:
-
检查设备上是否有iCloud
-
如果是,则使用URLForUbiquityContainerIdentifier获取iCloud容器URL
-
将新的文件和文档保存到这个新的URL
为此,我使用此代码将返回文档文件夹的URL(iCloud或本地)
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不可用,我担心会出现问题,所以本地目录将被用来代替云容器,并且将是空的。 谢谢。
感谢上面的评论和进一步的阅读,我find了解决我的问题的方法。
这是我决定做的事情:
- iCloud将被默认激活(如果可能的话)
- 用户可以使用UISwitch在应用程序中禁用/启用iCloud
- 当用户禁用iCloud时,所有iCloud文件将在本地传输
- 当用户启用iCloud时,所有的本地文件将被传输到iCloud Ubiquity容器中
- 没有数据合并
像这样的数据不会丢失。
我想几乎每个人都会使用iCloud,一切都将是透明和无痛的。 无论如何,我同步的文件是非常小的,所以它应该工作得很好(到目前为止)。
我有5个简单的方法:
- 检查iCloud是否可用的方法
- 根据用户select(iCloud或Local)返回文档URL的方法
- 删除目录中的所有文件的方法(应用程序使用的文件)
- 将文件从本地目录移动到iCloud容器的方法
- 从iCloud容器移动fies到本地目录的方法
这是我的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)") } } } } }
检查这个链接: iCloud的基本知识和代码示例
如果您正在存储的信息很简单,最好使用NSUserDefaults。 你不想问iCloud的基本信息。
对于那些想要使用SWIFT 3的用户 :注意:不要移动数据,而只需复制。 但目标path在复制数据之前被清除。
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)") } } } } }