3
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

1
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a minimal reproducible example. Commented Aug 1, 2022 at 13:23

1 Answer 1

1

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)")!
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you so much Could you take a look at the code I updated? Since 'roomnum' is a value received from user input data, it cannot be used as a function parameter unless it is retrieved from ReserveView. Can't I call the desired variable from ReserveView? Since 'roomnum' is not a variable that can be directly assigned, only the binding value must be used.
I don't see where do you want to call it, roomnum is used only as id in ForEach
I'm so sorry. Could you take a look at my code again? The roomnum will be loaded from another view I haven't attached and I'll bind it to ReserveView. And I want to share the bound roomnum to ReserveService again. Is this possible?
In simple terms, I want to use the variables bound in the view model at 'non-view model'.
Do same in task, like await vm.service.fetchReserves(roomnum) (removing private from service property, or make it only private(set)).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.