文件存在于 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 读取文件内容

iCloud:获取云中存在的文件数组

在 iCloud 中使用预先存在的 NSFileManager 代码

iCloud:在 OS X 上获取云中存在的一系列 txt 文件

验证 iCloud 容器上的文档是不是存在

iphone怎么查询照片是不是存在ic上