Загрузить данные из файла sqlite Swift 4.2

Загрузить данные из файла sqlite Swift 4.2I имеет большую базу данных в файле sqlite поэтому я пытаюсь получить к нему доступ непосредственно из моего файла data.sqlite но я не могу получить к нему доступ. Я выполнил эту задачу в прошлом, используя цель C

Предпринятые шаги:

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

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

Вывод: path=== /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
    }

Покажи, как ты поставил pathToDatabase. И вы подтвердили, что ваш data.sqlite действительно копируется в пакет приложения, когда приложение создается?

rmaddy 29.05.2019 20:14

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

zkn 29.05.2019 20:15

Это должно быть в вашем вопросе, а не в комментарии.

rmaddy 29.05.2019 20:16

Пожалуйста, объясните, как я могу подтвердить, что файл data.sqlite действительно копируется в пакет приложений?

zkn 29.05.2019 20:16

См. stackoverflow.com/a/51054075/1226963, чтобы узнать, как проверить целевое членство файла.

rmaddy 29.05.2019 20:20

@maddy Целевое членство в файле data.sqlite выглядит нормально. Я добавил фото, посмотрите

zkn 29.05.2019 20:30

Выглядит неплохо. Но обратите внимание, что файл находится в комплекте приложения, а не в папке «Документы».

rmaddy 29.05.2019 20:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
776
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Я не использовал 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")

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

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

Копирование может быть или не быть подходящим в зависимости от его варианта использования. База данных с неизменяющимися данными будет занимать место впустую, особенно если она большая, если она используется в режиме только для чтения.

ekscrypto 29.05.2019 20:49

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

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)

Другие вопросы по теме