Как загрузить файл хранилища sqlite расширения iMessage на MacBook

Мы разрабатываем расширение iMessage. Он успешно использует Core Data. Нам нужно оценить файл store.sqlite, но мы не можем его найти.

Пробуем найти так:

  • В Xcode: Окно -> Устройства
  • В Installed Apps выбираем наше расширение
  • Download Container ...

Но контейнер пуст:


Обновлять:

Благодаря @Mundi answer мы узнали, как получить URL-адрес моделей:

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

Теперь пытаемся скопировать Модель в папку Documents, чтобы иметь возможность потом загрузить ее на наш MacBook через Xcode (см. выше).

К сожалению, путь к `Документам:

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

снова в /var/mobile/Containers/:

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

Как мы можем загрузить файл Model.sqlite из общего контейнера на наш MacBook?


person shallowThought    schedule 07.11.2016    source источник
comment
Возможно ли это сделать на симуляторе? Затем вы можете получить доступ к файлам непосредственно в файловой системе MacOS.   -  person Mundi    schedule 13.11.2016
comment
К сожалению, нам нужен файл с устройства.   -  person shallowThought    schedule 13.11.2016
comment
Разве копирование файла в каталог «Документы» и его совместное использование на Mac через airdrop не решает проблему здесь программно? Вы пробовали так делать?   -  person KrishnaCA    schedule 16.11.2016


Ответы (2)


Лучше всего для этого написать экспортер, используя действие общего доступа к почте. В одном из моих приложений я разрешаю пользователю экспортировать все данные, отправив по электронной почте копию файла 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, поэтому он не очень хорош, но работает. Я использовал его на днях в развернутой копии моего приложения для устранения проблемы, просто напишите себе и откройте с помощью средства просмотра Sqlite на вашем Mac.

person SimonBarker    schedule 03.12.2016
comment
Жестко, но здорово :-) - person shallowThought; 03.12.2016

Фактический файл 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

person Mundi    schedule 07.11.2016
comment
Как получить это от NSPersistentContainer? - person shallowThought; 07.11.2016
comment
Я обновил ответ, чтобы продемонстрировать, как перейти к URL-адресу. - person Mundi; 07.11.2016
comment
Спасибо за упоминание. Однако даже не голосовать за мой правильный ответ, а вместо этого просто изменить вопрос, не особенно мотивирует. - person Mundi; 12.11.2016
comment
Проголосовали и упомянули в обновлении вопроса. Обновление вопроса заключалось не в том, чтобы изменить его семантику, а в том, чтобы лучше описать мою настоящую озабоченность. - person shallowThought; 12.11.2016