2017-04-10 23 views
2

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

我有以下问题:

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

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

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

谢谢。

回答

0
  1. 使用evictUbiquitousItem(at url:)
  2. 见点#1。不过,我不确定你为什么想这样做。你不能停止访问本地副本第二个开关关闭?
  3. 我不认为它可以通过编程方式禁用。从积极的方面来看,如果你想利用可能性禁用iCloud的用户,它已经在那里。 iCloud的是应该通过设置被禁用应用程序,你真正需要做的是通过听NSUbiquityIdentityDidChangeNotification

UPDATE处理应用程序内的事实

阿明Negm - 阿瓦德指出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) 

我不认为远程文件最终会在设备上,除非startDownloadingUbiquitousItemAtUrl:被称为与拆迁户文件的URL。不过,不确定这种行为是否可以依赖。

+0

我认为'evictUbiquitousItemAtURL:error:'不会永久删除本地副本,而是强制重新加载。我认为在iCloud中仍然有版本的情况下,根本不可能删除本地副本。 –

+0

@Amin Negm-Awad查看我的更新回答 – crizzis

0

看完苹果的文档和其他建议后,这里是我的理解。我不是100%确定他们是否正确。注释和更正非常欢迎:加入或从无处不在容器中取出,将与iCloud的服务器进行同步

  1. 什么。该应用程序无法控制这一点。

  2. 一旦用户在“设置”应用程序中启用了iCloud文档存储,它就不能被应用程序禁用。该应用程序的责任是提供用户界面(假设UISwitch),让用户指出他们希望他们的文档与iCloud同步应用程序的位置。

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

+0

Hi Mark。你对此有何了解?今晚处理同样的事情。谢谢。 – SAHM

+0

从你的(还是非常好的)回答中,我不清楚的是 - 只要我们发现用户关闭了iCloud,我们是否可以从ubiquity容器中获取文件(在应用程序被终止的情况下,下一个用户打开应用程序的时间等),并将它们保存在本地?这样,保存在iCloud中的备份可以移动到本地存储,并且当用户在设置应用程序中关闭iCloud时仍然可以访问该应用程序。这是符合你的答案,还是我们不能抓住这些文件? – SAHM

相关问题