文件存在于 iCloud 中,但 query.resultCount = 0
Posted
技术标签:
【中文标题】文件存在于 iCloud 中,但 query.resultCount = 0【英文标题】:File exists in iCloud, but query.resultCount = 0 【发布时间】:2018-08-15 07:53:05 【问题描述】:应用程序使用 iCloud 存储符合 Codable 协议的对象。
如果重新安装应用程序或在新设备上安装应用程序,我会尝试使用 NSMetadataQuery 从 iCloud 的现有文件中获取数据 - 但 query.resultCount = 0。
我认为我的问题是关于以正确的方式设置 NSMetadataQuery 谓词。
请就这个问题给我建议
class ViewController: UIViewController
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var weightLabel: UILabel!
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var weightTextField: UITextField!
let fileManager = FileManager.default
var iCloudContainer: URL?
return FileManager().url(forUbiquityContainerIdentifier: nil)
func getFilePath(container: URL, fileName: String) -> String
let filePath = container.appendingPathComponent(fileName).path
return filePath
lazy var metadataQuery : NSMetadataQuery =
let query = NSMetadataQuery()
query.searchScopes = [NSMetadataQueryUbiquitousDocumentsScope]
var pred = NSPredicate(format: "NOT %K.pathExtension = '.'", NSMetadataItemFSNameKey)
query.predicate = pred
return query
()
override func viewDidLoad()
super.viewDidLoad()
self.metadataQuery.start()
NotificationCenter.default.addObserver(self, selector: #selector(refreshFileList), name: NSNotification.Name.NSMetadataQueryDidUpdate, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(refreshFileList), name: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: nil)
deinit
NotificationCenter.default.removeObserver(self)
@objc func refreshFileList()
print(metadataQuery.resultCount)
metadataQuery.enumerateResults (item: Any, index: Int, stop: UnsafeMutablePointer<ObjCBool>) in
let metadataItem = item as! NSMetadataItem
if isMetadataItemDownloaded(item: metadataItem) == false
let url = metadataItem.value(forAttribute: NSMetadataItemURLKey) as! URL
try? FileManager.default.startDownloadingUbiquitousItem(at: url)
let container = self.iCloudContainer
let filePath = getFilePath(container: container!, fileName: "Person")
if let jsonData = NSKeyedUnarchiver.unarchiveObject(withFile: filePath) as? Data
if let person = try? JSONDecoder().decode(Person.self, from: jsonData)
nameLabel.text = person.name
weightLabel.text = String(person.weight)
else
nameLabel.text = "NOT decoded"
weightLabel.text = "NOT decoded"
else
nameLabel.text = "NOT unarchived"
weightLabel.text = "NOT unarchived"
func isMetadataItemDownloaded(item : NSMetadataItem) -> Bool
if item.value(forAttribute: NSMetadataUbiquitousItemDownloadingStatusKey) as? String == NSMetadataUbiquitousItemDownloadingStatusCurrent
return true
else
return false
@IBAction func saveButtonPressed(_ sender: UIButton)
let container = self.iCloudContainer
let filePathe = getFilePath(container: container!, fileName: "Person")
let person = Person(name: nameTextField.text!, weight: Double(weightTextField.text!)!)
let jsonData = try? JSONEncoder().encode(person)
NSKeyedArchiver.archiveRootObject(jsonData!, toFile: filePathe)
【问题讨论】:
【参考方案1】:首先谓词的格式应该是
query.predicate = NSPredicate(format: "%K == %@", NSMetadataItemFSNameKey, "Person")
其次,你可以像这样在容器中显示保存文件
let filePath = container.appendingPathComponent("Documents").appendingPathComponent(fileName).path
文件路径必须是/Documents/File
没有Documents目录,查询找不到文件
【讨论】:
以上是关于文件存在于 iCloud 中,但 query.resultCount = 0的主要内容,如果未能解决你的问题,请参考以下文章
在 iCloud 中使用预先存在的 NSFileManager 代码