如何将 iMessage 扩展的 sqlite 存储文件下载到 MacBook

How to download sqlite store file of iMessage extension to MacBook

我们正在开发 iMessage 扩展。它成功地使用了核心数据。我们需要评估 store.sqlite 文件,但找不到它。

我们尝试这样查找:

但是容器是空的:


更新:

感谢 我们找到了如何获取模型 URL:

file:///var/mobile/Containers/Data/PluginKitPlugin/9C15B67C-8917-4A24-9FB0-BD119C43B3C4/Library/Application%20Support/Model.sqlite

现在我们正在尝试将模型复制到 Documents 文件夹,以便稍后能够通过 Xcode(见上文)将其下载到我们的 MacBook。

不幸的是,`Documents 的路径:

NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]

又在/var/mobile/Containers/:

file:///var/mobile/Containers/Data/PluginKitPlugin/D0BBD375-A8B7-43DD-8486-1909965CAEB0/Documents

我们如何将 Model.sqlite 文件从共享容器下载到我们的 MacBook?

实际的 sqlite 文件很可能位于共享容器中。

对我有用的是记录商店 URL 并使用它来定位它:

print(container.persistentStoreCoordinator.persistentStores.first!.url!)

产生类似

的结果

file:///Users/developer/Library/Developer/CoreSimulator/Devices/2EAE0CD4-7899-45A3-8E83-E7D79DEEA08F/data/Containers/Data/Application/37F48A5E-7DAB-4E30-A752-F5B62826A15A/Library/Application%20Support/Events.sqlite

最好的办法是编写一个使用邮件共享操作的导出器。在我的一个应用程序中,我允许用户通过电子邮件发送 sqlite 文件的副本来导出所有数据。

func exportAllDataSqlite() {
    let documentsUrl =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

    var newFilePath: URL!
    var mutablePathComponents = [String]()
    var sqliteFileCopied = false

    do {
        let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: FileManager.DirectoryEnumerationOptions())
        for f in directoryContents {
            let pathComponents = f.pathComponents
            if pathComponents.last == "XXXXWhatever your file is called when created by the persisten store.sqliteXXXXX" {
                //create a copy of the file with a dated file name
                mutablePathComponents = pathComponents

                let dateComponents = (Calendar.current as NSCalendar).components([.day, .month, .year], from: Date())
                let dateString = "\(dateComponents.day)-\(dateComponents.month)-\(dateComponents.year)"

                mutablePathComponents[mutablePathComponents.count-1] = "Events App \(dateString).sqlite"


                newFilePath = NSURL.fileURL(withPathComponents: mutablePathComponents)
                do {
                    try FileManager.default.copyItem(at: f, to: newFilePath!)
                    sqliteFileCopied = true
                    print("Copied sqlite file")
                } catch let error as NSError {
                    print(error.localizedDescription)
                }

            }
        }
    } catch let error as NSError {
        print(error.localizedDescription)
    }

    if sqliteFileCopied == true {
        //sharing
        let activityItem:URL = newFilePath!

        let objectsToShare = [activityItem]
        let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)

        activityVC.completionWithItemsHandler = { activity, success, items, error in
            do {
                try FileManager.default.removeItem(at: newFilePath!)
                print("Deleted file: \(newFilePath!)")
            } catch let error as NSError {
                print(error.localizedDescription)
            }
        }

        let excludeActivities = [UIActivityType.airDrop,
                                 UIActivityType.print,
                                 UIActivityType.assignToContact,
                                 UIActivityType.saveToCameraRoll,
                                 UIActivityType.addToReadingList,
                                 UIActivityType.postToFlickr,
                                 UIActivityType.postToVimeo]
        activityVC.excludedActivityTypes = excludeActivities

        self.present(activityVC, animated: true, completion: nil)
    } else {
        print("file not copied so can't be shared")
    }
}

这是我最早的一些 Swift,虽然不是很好,但很管用。我前几天在我的应用程序的部署副本中使用它来调试问题,只需给自己发送电子邮件并在 mac.

上使用 Sqlite 查看器打开