Reputation: 31
import SwiftUI
struct ReserveView: View {
@State var searchT = ""
@State var isSearching = false
@State private var showCheckAlert = false
@Binding var roomnum:Int
@StateObject private var vm = ReserveViewModel(
service: ReserveService()
)
var body: some View {
VStack{
HStack{
TextField("Search", text:$searchT)
.padding(.leading, 30)
}
.padding()
.background(Color.gray.opacity(0.2))
.cornerRadius(6)
.padding(.horizontal)
.onTapGesture(perform: {
isSearching = true
})
.overlay(
HStack {
Image(systemName: "magnifyingglass")
Spacer()
}.padding(.horizontal,32)
.foregroundColor(.white)
)
if isSearching {
Button(action:{
isSearching = false
searchT = ""
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for:nil)
}, label: {
Text("Cancle")
.padding(.trailing)
.padding(.leading,0)
})
.transition(.move(edge: .trailing))
}
switch vm.state{
case .success(let data):
List{
ForEach((data).filter({"\($0)".contains(searchT)||searchT.isEmpty}),
id: \.roomnum){ item in
HStack{
Text("\(item.when) \(item.time) \(item.username)").foregroundColor(Color.black)
}
}
}
.padding(.bottom,15)
//.padding(.top,20)
case .loading:
ProgressView()
default:
EmptyView()
}
}
.task {
await vm.getReserves()
}
}
}
struct ReserveView_Previews: PreviewProvider {
static var previews: some View {
ReserveView(roomnum:.constant(""))
}
}
import Foundation
import SwiftUI
struct ReserveService {
enum ReserveListError: Error {
case failed
case failedToDecode
case invalidStatusCode
}
func fetchReserves() async throws -> [Reserve] {
let url = URL(string: "https://f6d3-119-203-102/roomreserveview?roomnum=\(here i want use variable)")!
let configuration = URLSessionConfiguration.ephemeral
print(url)
let (data, response) = try await URLSession(configuration: configuration).data(from: url)
guard let response = response as? HTTPURLResponse,
response.statusCode == 200 else{
throw ReserveListError.invalidStatusCode
}
let decodedData = try JSONDecoder().decode(ReserveServiceResult.self, from: data)
return decodedData.reserveInfo
}
}
import SwiftUI
import Foundation
@MainActor
class ReserveViewModel: ObservableObject {
enum State {
case na
case loading
case success(data: [Reserve])
case failed(error: Error)
}
@Published private(set) var state: State = .na
@Published var hasError: Bool = false
private let service: ReserveService
init(service: ReserveService) {
self.service = service
}
func getReserves() async {
self.state = .loading
self.hasError = false
do {
let reserves = try await service.fetchReserves()
self.state = .success(data: reserves)
}catch {
self.state = .failed(error: error)
self.hasError = true
print(String(describing: error))
}
}
}
hello! I'd like to ask you a SwiftUI question.
Based on the ReserveService file, I am implementing the part that lists and displays the desired data in ReserveView.
I want to complete the url in the 'fetchReserves' function by receiving the variable 'roomnum' from the ReserveView model to the ReserveService. However, Binding does not seem to work because ReserveService is not a view model. Is there any way I can get this variable from the viewmodel? If you don't understand my explanation, please ask the question again.
This is my first time asking a question. Please forgive me if there is something missing in my question
Upvotes: 3
Views: 209
Reputation: 257719
It is possible to inject it as function argument, like
func fetchReserves(_ roomnum: Int) async throws -> [Reserve] {
let url = URL(string:
"https://f6d3-119-203-102/roomreserveview?roomnum=\(roomnum)")!
Upvotes: 1