costar97
costar97

Reputation: 31

SwiftUI Share variable Between Struct

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

Answers (1)

Asperi
Asperi

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

Related Questions