关闭iCloud并从无处不在的容器中删除项目

时间:2017-04-10 14:13:50

标签: ios objective-c icloud

我的应用中有一个UISwitch,用户可以打开/关闭 iCloud 。我想实现以下目标:当用户关闭iCloud时,无处不在的容器中的所有内容都将被删除并作为备份复制到本地目录。但是,只要文件从无处不在的容器中删除, iCloud 服务器上的副本也会被删除。这基本上清除了 iCloud 上的所有内容。

我有以下问题:

  1. 如何删除无处不在的容器上的文件而不影响iCloud服务器上的副本?

  2. 在停用 iCloud 之前,从无处不在的容器中删除文件的最佳或标准做法是什么?

  3. iCloud初始化/启用后是否可以完全禁用?

  4. 谢谢。

2 个答案:

答案 0 :(得分:0)

  1. 使用evictUbiquitousItem(at url:)
  2. 见第1点。不过,我不确定你为什么要那样做。你能不能在第二个交换机关闭时停止访问本地副本?
  3. 我认为不能以编程方式禁用它。从积极的方面来说,如果你想利用有可能禁用iCloud的用户,它已经存在。 iCloud应该通过设置应用程序禁用,您真正需要做的就是通过收听NSUbiquityIdentityDidChangeNotification
  4. 来处理应用程序中的这一事实

    更新

    Amin Negm-Awad建议evictUbiquitousItem(at url:)强制重新加载,因此不会永久删除本地副本。但是,出于好奇,我做了一点测试,并没有发现情况。以下测试:

    func runTest(ubiURL: URL) {
        self.query.searchScopes = [NSMetadataQueryUbiquitousDocumentsScope]
        self.query.predicate = NSPredicate(format: "%K like '*'", NSMetadataItemFSNameKey)
        NotificationCenter.default.addObserver(self, selector: #selector(self.metadataQueryDidUpdate(_:)), name: NSNotification.Name.NSMetadataQueryDidUpdate, object: self.query)
        self.query.start()
        self.query.enableUpdates()
        let fileURL = ubiURL.appendingPathComponent("Documents/file.txt")
        FileManager.default.createFile(atPath: fileURL.path, contents: "Hello".data(using: .utf8))
        do {
            try FileManager.default.startDownloadingUbiquitousItem(at: fileURL)
        } catch {
            print("startDownloadingUbiquitousItem: \(error.localizedDescription)")
        }
    }
    
    var updateCount = 0
    
    func metadataQueryDidUpdate(_ notification: Notification) {
        print("######################")
        print("update #\(updateCount)")
    
        for file in query.results as! [NSMetadataItem] {
            guard let fileURL = file.value(forAttribute: NSMetadataItemURLKey) as? URL, let fileStatus = file.value(forAttribute: NSMetadataUbiquitousItemDownloadingStatusKey) as? String else {
                print("Invalid item!")
                return
            }
            if fileStatus == NSMetadataUbiquitousItemDownloadingStatusCurrent {
                print("URL to evict: \(fileURL)")
                do {
                    try FileManager.default.evictUbiquitousItem(at: fileURL)
                    print("Eviction result: successful")
                } catch {
                    print("evictUbiquitousItem: \(error.localizedDescription)")
                }
            }
            print("File exists at URL: \(FileManager.default.fileExists(atPath: fileURL.path))")
        }
    
        updateCount = updateCount + 1
    
    }
    

    屈服:

    ubiURL is file:///private/var/mobile/Library/Mobile%20Documents/iCloud~com~example~blabla3/
    ######################
    update #0
    URL to evict: file:///private/var/mobile/Library/Mobile%20Documents/iCloud~com~example~blabla3/Documents/file.txt
    evictUbiquitousItem: The file “file.txt” couldn’t be saved in the folder “blabla”.
    File exists at URL: true
    ######################
    ...
    update #3
    URL to evict: file:///private/var/mobile/Library/Mobile%20Documents/iCloud~com~example~blabla3/Documents/file.txt
    Eviction result: successful
    File exists at URL: true
    ######################
    update #4
    File exists at URL: false
    (no further updates followed)
    

    除非使用被驱逐文件的URL调用startDownloadingUbiquitousItemAtUrl:,否则我认为远程文件不会在设备上结束。但是不确定是否可以依赖这种行为。

答案 1 :(得分:0)

在阅读Apple的文档和其他建议后,我的理解是这样的。我不是100%肯定他们是否正确。欢迎提出意见和更正:

  1. 在ubiquity容器中添加或删除的任何内容都将与iCloud服务器同步。该应用程序无法控制此。

  2. 一旦用户在“设置”应用中启用了iCloud文档存储,该应用就无法禁用它。该应用程序的职责是提供UI(假设UISwitch),以便用户指示他们希望他们的文档与应用程序的iCloud同步。

  3. 如果用户通过关闭应用中的UISwitch关闭iCloud(不在设置中),应用应该做的是停止查询元数据,停止收听NSMetadataQueryDidUpdateNotification,并停止访问普遍容器中的文件(如上面的crizzis所述)。如果稍后用户再次打开iCloud,则ubiquity容器中已有的文件将自动与iCloud同步,除非发生未解决的冲突,否则不需要手动合并。