gpt4 book ai didi

ios - SwiftUI SQLite ForEach 列表数据

转载 作者:行者123 更新时间:2023-11-28 05:36:44 27 4
gpt4 key购买 nike

我正在尝试集成 SQLite 数据库 (with SQLite.swift)进入我的项目(因为我未恢复的 CoreData 引用的明显限制 here

我有一个帮助程序文件,其中包含一个我实例化的类,用于执行与 SQLite 查询相关的所有繁重工作。

我不知道如何获取这些数据,比如将数据库内容的简单列表,放入 SwiftUI 中的 ForEach 语句中。

我试图从运行查询的函数中设置一个返回值,但它的返回类型是 AnySequence<Row> ,我不确定该怎么做。当我在获取数据后尝试返回它时,我收到关于不返回失败的错误(可以理解)。不知道如何返回空白 AnySequence<Row>在这种情况下。请参阅下面的代码。

有什么想法吗?

来自辅助类的代码(按照 Kilo Loco's YouTube video 中的一些说明构建):


import Foundation
import SQLite



class DataModel {

var database: Connection!
let usersTable = Table("users")
let id = Expression<Int>("id")
let name = Expression<String>("name")
let email = Expression<String>("email")
var dataDict = [Dictionary<String, String>()]

init() {

do {

let documentDirectory = try FileManager.default.url(for: .applicationSupportDirectory, in: .allDomainsMask, appropriateFor: nil, create: true)
let fileUrl = documentDirectory.appendingPathComponent("users").appendingPathExtension("sqlite3")
let database = try Connection(fileUrl.path)
self.database = database
print("Database initialized at path \(fileUrl)")
} catch {
print(error)
}

}


func createTable() {

print("Create Tapped")

let createTable = self.usersTable.create { (table) in
table.column(self.id, primaryKey: true)
table.column(self.name)
table.column(self.email, unique: true)
}

do {

try self.database.run(createTable)
print("Table Created")

} catch {
print(error)
}

}


func insertRecord(name: String, email: String) {

let insertRecord = self.usersTable.insert(self.name <- name, self.email <- email)

do {

try self.database.run(insertRecord)
print("record added")
} catch {
print(error)
}

}

func listUsers() {

print("Listed Users")

do {

let users = try self.database.prepare(self.usersTable)

for user in users {
print("User ID: \(user[self.id]), UserName: \(user[self.name]), Email: \(user[self.email])")

}

} catch {
print(error)
}
}
}

和简单的 SwiftUI 内容 View


import SwiftUI

let myData = DataModel()

struct ContentView: View {

@State var name: String = ""
@State var email: String = ""

var body: some View {


VStack {

TextField("Enter Name", text: self.$name)
TextField("Enter email", text: self.$email)

Button(action: {
myData.insertRecord(name: self.$name.wrappedValue, email: self.$email.wrappedValue)
}) {
Text("Insert Record")
}

Button(action: {
myData.createTable()
}) {
Text("Create Table")
}


Button(action: {
myData.listUsers()
}) {
Text("List users")
}
}
}
}

理论上,我希望能够在我的 VStack 中做一些事情:

ForEach (myData.listUsers, id: \.self) { record in 
Text("UserName \(record.userName)")
}

我试图让 listUsers 函数返回它的结果,这样它就可以像这样使用,但效果并不好..

更新 #1

尝试让函数返回数据,然后我可以在 SwiftUI View 中迭代它。我正在尝试这个:

    func listUsers() -> (Int, String, String) {
print("Listed Users")
do {
let users = try self.database.prepare(self.usersTable)
for user in users {
print("User ID: \(user[self.id]), UserName: \(user[self.name]), Email: \(user[self.email])")
return (user[self.id], user[self.name], user[self.email])
}
} catch {
print(error)
}
return (0, "No Name", "No Email")
}

然后在我试图调用的 View 中:

                let response = myData.listUsers()
for resp in response {
Text(resp.name)
}

但是我得到了错误:

Type '(Int, String, String)' does not conform to protocol 'Sequence'

更新 #2

神圣的 C*&@ - 多么痛苦..

我能够让函数返回一些我可以使用的东西,但这绝对不是最有效的方法。知道我怎样才能做得更好:

我现在的功能是:

    func listUsers() ->  [Dictionary<String,Any>]  {
print("Listed Users")
do {
let users = try self.database.prepare(self.usersTable)
for user in users {
print("User ID: \(user[self.id]), UserName: \(user[self.name]), Email: \(user[self.email])")
dataDictArray.append(["id":user[self.id], "name":user[self.name], "email":user[self.email]])
}
} catch {
print(error)
}
return dataDictArray
}


}

它返回一个 String:Any 字典数组(因为我在我的数据库中混合了 String 和 Int。然后我的函数看起来像:

                let response = myData.listUsers()
print(response)
for dicts in response {
for record in dicts {
if (record.key.datatypeValue == "name") {
print("Record Key: \(record.key)")
print("Record Value: \(record.value)")
}
}
}
}) {
Text("List users")
}

所以它所做的,这是荒谬的,是循环遍历数组,然后循环遍历字典以获取键值对..

只是感觉很麻烦而且过于复杂。

  • 仍然无法弄清楚如何将其放入实际 View 中。我可以将输出打印到日志中,但不能打印在 Text() 标记中。

最佳答案

我发现了如何做到这一点:

在我的 SQLite 工作文件中,我需要创建一个结构来表示数据模型:

struct TestDataModel: Hashable {
let id: Int
let name: String
let email: String
}

然后在我的帮助程序类中,我的函数将数据加载到 TestDataModel 对象数组中。该函数然后像这样返回数组:

    func listUsers2() ->  [TestDataModel]  {
print("Listed Users")
var theseVars = [TestDataModel]()
do {
let users = try self.database.prepare(self.usersTable)
for user in users {
print("User ID: \(user[self.id]), UserName: \(user[self.name]), Email: \(user[self.email])")
theseVars.append(TestDataModel(id: user[self.id], name: user[self.name], email: user[self.email]))
}
} catch {
print(error)
}
return theseVars
}

然后,在我的 SwiftUI View 中,我可以像平常一样使用 TestDataModel 对象数组:

            ForEach (myData.listUsers2(), id: \.self) { record in
Text(record.email)

}

这可行,不确定它是否是最优雅的方法,但结果很好..

关于ios - SwiftUI SQLite ForEach 列表数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58420241/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com