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