ios – How does the swiftUI programming language in xcode get data from sqlite files?


struct ContentView: View {
    @State private var searchTerm: String = ""
    @State private var meanings: [String] = []

    @ObservedObject private var dbManager = DatabaseManager()
    @ObservedObject private var wordsManager = WordsManager(databaseManager: DatabaseManager())
    
    init() {
        let databaseManager = DatabaseManager()
        self.wordsManager = WordsManager(databaseManager: databaseManager)
        dbManager.copyDatabaseIfNeeded()
        wordsManager.fetchWords()
        print("Loaded words: \(wordsManager.words)")
    }
......
    var body: some View {
        NavigationView {
            VStack {
                HStack {
                    TextField("输入单词", text: $searchTerm, onEditingChanged: { _ in
                        updateList()
                    })
                    .autocapitalization(.none)
                    .padding()
                    .frame(height: 40)
                    .textFieldStyle(RoundedBorderTextFieldStyle())

                    Button("查找") {
                        findMeanings(for: searchTerm)
                    }
                    .padding()
                    .frame(height: 40)
                    .foregroundColor(.white)
                    .background(Color.blue)
                    .cornerRadius(10)
                }
                .padding()
                .navigationTitle("词典")

                Divider()

                List(wordsManager.words.filter { $0.lowercased().contains(searchTerm.lowercased()) || searchTerm.isEmpty }, id: \.self) { word in
                    NavigationLink(destination: DetailView(word: word, meaning: meanings.first ?? "未找到含义")) {
                        Text(word)
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .contentShape(Rectangle())
                    }
                }
                .listStyle(PlainListStyle())
                .background(Color.gray.opacity(0.1))

                Spacer()
            }
            .padding()
            .navigationTitle("词典")
        }
    }
......

Copy the current relative path of the db file (structure and data) to the local, and then get the data in sqlite displayed in the list

I’m afraid the code isn’t detailed enough to confuse you. I’m new to XCode

class DatabaseManager: ObservableObject {
    var db: OpaquePointer?

    init() {
         if let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
             let sandboxDBPath = documentsPath.appendingPathComponent("english_grammar_today.db").path
             print("沙盒中的数据库路径:\(sandboxDBPath)")

             // 打开数据库
             if sqlite3_open(sandboxDBPath, &db) == SQLITE_OK {
                 // 在这里执行你的操作
                 print("成功打开数据库")
             } else {
                 let errorMessage = String(cString: sqlite3_errmsg(db))
                 print("无法打开数据库,错误消息:\(errorMessage)")
             }
             
             // 创建表
             if sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS dictionary (id INTEGER PRIMARY KEY AUTOINCREMENT, entry TEXT, paraphrase TEXT);", nil, nil, nil) != SQLITE_OK {
                 fatalError("无法创建数据库表")
             }
         } else {
             print("找不到应用沙盒的文档目录")
         }
     }

    
    func copyDatabaseIfNeeded() {
        if let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
            let bundleDBPath = Bundle.main.path(forResource: "english_grammar_today", ofType: "db")
            let sandboxDBPath = documentsPath.appendingPathComponent("english_grammar_today.db").path
            if !FileManager.default.fileExists(atPath: sandboxDBPath) {
                do {
                    try FileManager.default.copyItem(atPath: bundleDBPath!, toPath: sandboxDBPath)
                    print("成功拷贝数据库文件到应用沙盒 copy successed")
                    
                    // close
                    if sqlite3_close(db) != SQLITE_OK {
                        print("无法关闭SQLite数据库连接 can't close")
                    }
                    
                    // retry
                    if sqlite3_open(sandboxDBPath, &db) == SQLITE_OK {
                        print("成功重新打开数据库")
                    } else {
                        let errorMessage = String(cString: sqlite3_errmsg(db))
                        print("无法重新打开数据库,错误消息:\(errorMessage)")
                    }
                } catch {
                    print("copy failed:\(error)")
                }
            } else {
                print("database file already exists")
            }
        } else {
            print("not found")
        }
    }


    deinit {
        // 关闭数据库连接
        if sqlite3_close(db) != SQLITE_OK {
            print("无法关闭SQLite数据库连接  failed")
        }
    }
}

Obtain the document directory of the application sandbox, build the path of the database file in the sandbox, output the database path in the sandbox, and open the database.

Actually, I don’t understand. What is a sandbox

But I don’t know if the WordsManager problem is a problem or the DatabaseManager problem

class WordsManager: ObservableObject {
    @Published var words: [String] = []

    var databaseManager: DatabaseManager

    init(databaseManager: DatabaseManager) {
        self.databaseManager = databaseManager
        // 调用 fetchWords 方法以获取单词列表
        fetchWords()
    }

    func fetchWords() {
        var statement: OpaquePointer?

        let query = "SELECT entry FROM dictionary"

        if sqlite3_prepare_v2(databaseManager.db, query, -1, &statement, nil) == SQLITE_OK {
            var fetchedWords: [String] = []

            while sqlite3_step(statement) == SQLITE_ROW {
                if let result = sqlite3_column_text(statement, 0) {
                    let word = String(cString: result)
                    fetchedWords.append(word)
                }
            }

            sqlite3_finalize(statement)

            if fetchedWords.isEmpty {
                print("未找到单词")
            } else {
                print("找到的单词:\(fetchedWords)")
            }

            DispatchQueue.main.async {
                self.words = fetchedWords
            }

        } else {
            let errorMessage = String(cString: sqlite3_errmsg(databaseManager.db))
            print("SQLite查询错误: \(errorMessage)")
        }
    }
}

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img