JobsView.swift:
import SwiftUI
импортировать объединение
struct JobsView: View {
@EnvironmentObject var appState: AppState
Код: Выделить всё
@StateObject private var webSocketManager = WebSocketManager.shared
@EnvironmentObject private var databaseManager: DatabaseManager
@State private var selectedJobs: Set = [] //Tracks selected Jobs
@State private var navigateToPODView: Bool = false //Controls navigation to POD view
var body: some View {
NavigationStack {
VStack {
// List with selection from local db
List(databaseManager.jobs, id: \.id, selection: $selectedJobs) { job in
HStack {
if selectedJobs.contains(job) {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(Color.green) //Shows a checkmark for selected jobs
}
VStack(alignment: .leading) {
Text("\(job.CustomerName)")
.font(.headline)
Text("\(job.Address1), \(job.Suburb), \(job.State)")
.font(.subheadline)
Text("Invoice: \(job.InvoiceNo)")
.font(.footnote)
}
.contentShape(Rectangle()) //Makes the entire row tappable
.onTapGesture {
toggleSelection(for: job)
}
}
}
.listStyle(.inset)
.navigationTitle("Jobs")
// Action button to proceed to POD view
Button(action: {
navigateToPODView = true
}) {
Text("Sign POD (\(selectedJobs.count) selected)")
.bold()
.frame(maxWidth: .infinity, minHeight: 44)
.background(selectedJobs.isEmpty ? Color.gray : Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
.padding()
}
.disabled(selectedJobs.isEmpty) // Disable button if no jobs are selected
}
//.onAppear {
// databaseManager.fetchJobs()
//}
.navigationDestination(isPresented: $navigateToPODView) {
PODView(selectedJobs: Array(selectedJobs))
}
}
}
private func toggleSelection(for job: Job) {
if selectedJobs.contains(job) {
selectedJobs.remove(job)
} else {
selectedJobs.insert(job)
}
}
DatabaseManager.swift:
импортировать GRDB
импортировать Foundation
импортировать
класс DatabaseManager : ObservableObject {
Код: Выделить всё
// The database file URL
private var dbQueue: DatabaseQueue!
//Publisher for jobs updates
@Published var jobs: [Job] = []
private var cancellables = Set()
init() {
do {
// Specify the SQLite database file location (it will create the file if it does not exist)
let fileManager = FileManager.default
let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
let dbPath = documentDirectory.appendingPathComponent("job.sqlite")
dbQueue = try DatabaseQueue(path: dbPath.path)
// Create the jobs table if it doesn't already exist
try createJobsTable()
//Observe database changes
observeJobs()
} catch {
print("Error initializing database: \(error)")
}
}
// Create jobs table
private func createJobsTable() throws {
try dbQueue.write { db in
try db.create(table: "job", ifNotExists: true) { t in
t.autoIncrementedPrimaryKey("id")
t.column("JobId", .integer)
t.column("PickTicketId", .integer)
t.column("DriverId", .integer)
t.column("InvoiceNo", .text)
t.column("CustomerName", .text)
t.column("Address1", .text)
t.column("Address2", .text)
t.column("Address3", .text)
t.column("Suburb", .text)
t.column("State", .text)
t.column("Pcode", .text)
t.column("Cartons", .integer)
t.column("Created", .text)
}
}
}
//Observe jobs table for changes and update the @Published property
private func observeJobs() {
let observation = ValueObservation.tracking() { db in
try Job.fetchAll(db) //Fetch all jobs whenever there is a change
}
observation
.publisher(in: dbQueue)
.catch { error -> Just in
print("Database observation error: \(error)")
return Just([]) // Return an empty array if there's an error
}
.receive(on: DispatchQueue.main)
.sink { [weak self] jobs in
self?.jobs = jobs
}
.store(in: &cancellables)
}
func insertJob(job: Job) {
do {
try dbQueue.write { db in
try job.insert(db) // Use GRDB's insert method
}
} catch {
print("Error inserting job: \(error)")
}
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... os-swiftui
Мобильная версия