问题
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