Загрузить данные из файла sqlite Swift 4.2 - PullRequest
0 голосов
/ 29 мая 2019

enter image description here У меня большая база данных в файле sqlite, поэтому я пытаюсь получить к ней доступ напрямую из файла data.sqlite, но не могу получить к ней доступ.Я выполнил эту задачу в прошлом, используя цель C

Выполненные шаги:

1: Перетащите файл data.sqlite в проект

2: Попытка получить к нему доступ через fmdb

Вывод: путь === /var/mobile/Containers/Data/Application/557B2961-52D8-4B14-BABC-BF4829852127/Documents/data.sqlite

let documentsDirectory = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString) as String 
pathToDatabase = documentsDirectory.appending("/(databaseFileName)")

func openDatabase() -> Bool {
 print("path=== \(pathToDatabase ?? "empty")")
      if database == nil {
           if FileManager.default.fileExists(atPath: pathToDatabase) {
                database = FMDatabase(path: pathToDatabase) 
//code is not entering in that if , it should be there becasuse I already included my sqlitefile    
 } 
        if database != nil {
            if database.open() {
                return true
            }
        }
        return false
    }

Ответы [ 3 ]

0 голосов
/ 29 мая 2019

Попробуйте скопировать файл локальной базы данных в библиотеку документов приложения, если его там нет.

import FMDB

class DBService {
    // MARK: Properties
    static let shared = DBService()
    var database: FMDatabase!

    private let fileManager = FileManager.default
    private var documentsDBPath: String
    private var resourcesDBPath: String

    private let databaseFileName = "data"
    private let databaseFileName = "sqlite"

    // MARK: Initializers
    private init() {
        documentsDBPath = try! fileManager
            .url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
            .appendingPathComponent(databaseFileName)
            .appendingPathExtension(databaseFileExtension)
            .path

        resourcesDBPath = Bundle.main.path(forResource: databaseFileName,
                                           ofType: databaseFileExtension)!
    }

    // MARK: - Setup
    func isDatabaseOpen() -> Bool {
        if database == nil {
            initDatabase()
        }

        return database.open()
    }

    private func initDatabase() {
        if isFirstLaunch() {
            copyDatabase(from: resourcesDBPath, to: documentsDBPath)  
        }

        database = FMDatabase(path: documentsDBPath)
    }

    private func isFirstLaunch() -> Bool {
        return !fileManager.fileExists(atPath: documentsDBPath)
    }

    private func copyDatabase(from source: String, to destination: String) {
        do {
            try fileManager.copyItem(atPath: source, toPath: destination)
        } catch {
            debugPrint(error)
        }
    }
}
0 голосов
/ 29 мая 2019

Ваш файл явно не находится в каталоге документов, вы должны получить к нему доступ в основном комплекте

let dbUrl = Bundle.main.url(forResource: "data", withExtension: "sqlite")

Если вам нужно скопировать базу данных в каталог документов, используйте вместо нее

let fileManager = FileManager.default
let dbUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask).last!.appendingPathComponent("data.sqlite")
if !fileManager.fileExists(atPath: dbUrl.path) {
    let url = Bundle.main.url(forResource: "data", withExtension: "sqlite")!
    try? fileManager.copyItem(at: url, to: dbUrl)
}

Использование

let database = FMDatabase(url: dbUrl)
0 голосов
/ 29 мая 2019

Я не использовал fmdb, но я успешно использовал GRDB (https://github.com/groue/GRDB.swift) в недавнем проекте. Обычно эти библиотеки позволяют вам получать код ошибки или вывод журнала в случае возникновения ошибки, и это может доказать действительно полезно для решения вашей проблемы.

А пока вот функция Swift, которую я использую для преобразования имени файла в полный путь пользователя для документов:

    private static func path(for filename: String) -> String {
        let fm = FileManager.default
        let documentsDirectory = fm.urls(for: .documentDirectory, in: .userDomainMask).first
        return documentsDirectory?.appendingPathComponent(filename).absoluteString ?? filename
    }

Обратите внимание, что файлы, включенные в состав сборки, обычно не будут находиться в ваших Документах, они будут частью ресурсов комплекта. В этом случае этот фрагмент кода может быть более полезным:

    let path = Bundle.main.path(forResource: "mydatabase", ofType: "sqlite")
...