How to download sqlite store file of iMessage extension to MacBook

谁说胖子不能爱 提交于 2019-12-10 18:42:44

问题


We are developing an iMessage extension. It uses Core Data successfully. We need to evaluate the store.sqlite file, but can not find it.

We try to find it like this:

  • In Xcode: Window -> Devices
  • In Installed Apps, select our extension
  • Download Container ...

But the container is empty:


Update:

Thanks to @Mundi's answer we found out how to get the models URL:

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

Now we are trying to copy the Model to the Documents folder, to be able to download it later to our MacBook via Xcode (see above).

Unfortunately the path to `Documents:

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

is again in /var/mobile/Containers/:

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

How can we download the Model.sqlite file from a shared container to our MacBook?


回答1:


Your best bet with this is to write an exporter using the mail share action. In one of my apps I allow the user to export all of the data by emailing a copy of the sqlite file.

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")
    }
}

It's some of my earliest Swift so not great but it works. I used it the other day in a deployed copy of my app to debug an issue, just email to yourself and open with an Sqlite viewer on your mac.




回答2:


The actual sqlite file is likely to be in a shared container.

What works for me is to log the store URL and use that to locate it:

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

Yields something like

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



来源:https://stackoverflow.com/questions/40463923/how-to-download-sqlite-store-file-of-imessage-extension-to-macbook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!