You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI注册应用多视图间数据传递问题求助

注册应用视图间数据传递问题

我正在开发一款注册应用,分为三个视图:

  • 第一个视图包含基础信息输入字段
  • 第二个视图包含从GET API获取数据的选择器组件
  • 第三个视图设有调用POST API的提交按钮

目前无法将前两个视图的数据传递到第三个视图完成提交,相关代码如下:

第一个视图(基础信息输入)

struct test3: View {
   
    @State var VM = PersonInfoViewModel()
    
    var body: some View {
        VStack {
            NavigationView {
                Form {
                    Section() {
                        TextField("Number", text: $VM.mobileNumber)
                        TextField("Email", text: $VM.email)
                    }
                    Section() {
                        TextField("Name", text: $VM.name)
                        TextField("Gender", text: $VM.gender)
                        TextField("Address", text: $VM.address)
                    }
                    Section() {
                        DatePicker("Birthday", selection: $VM.dateofBirth, displayedComponents: .date)
                    }
                    Section() {
                        
                        NavigationLink {
                            test2()
                        } label: {
                            Text("Next")
                                .fontWeight(.bold)
                                .multilineTextAlignment(.center)
                        }
                    }
                }
            }
        }
    }
}

第二个视图(地区选择器)

struct test2: View {
    @State var stateId: States? = nil
    @State var districtId: Districts? = nil
    @State var constituencyId: Constituency? = nil
    
    @StateObject var getStates = StateViewModel()
    @StateObject var getDistricts = DistrictsViewModel()
    @StateObject var getConstituency = ConstituencyViewModel()
    var body: some View {
        NavigationView {
            Form{
                Section() {
                    Picker("States*", selection: $stateId) {
                        Text("Select a State").tag(nil as States?)
                        ForEach(getStates.states, id: \.id) {
                            states in Text(states.value).tag(states as States?)
                        }
                    }
                    .task {
                        do {
                            try await getStates.fetchStates()
                        } catch {
                            //should display error.localizedDescription to user.
                            print(error)
                        }
                    }
                    Picker("District*", selection: $districtId) {
                        Text("Select a District").tag(nil as Districts?)
                        ForEach(getDistricts.districts, id: \.id) {
                            districts in
                            Text(districts.value).tag(districts as Districts?)
                        }
                    }
                    .task(id: stateId, { //This will run when the selected continent changes
                        districtId = nil
                        getDistricts.districts = []
                        //Since a new continent was selected makes the selected country nil and empty the list
                        guard let stateId else { //Proceed if the continent isn't nil
                            return
                        }
                        //Get the new countries list
                        do {
                            try await getDistricts.fetchDistricts(stateId: stateId.id)
                        } catch {
                            //should display error.localizedDescription to user.
                            print(error)
                        }
                    })
                    Picker("Constituency*", selection: $constituencyId) {
                        Text("Select a Constituency").tag(nil as Constituency?)
                        ForEach(getConstituency.constituency, id: \.id) {
                            constituency in
                            Text(constituency.value).tag(constituency as Constituency?)
                        }
                    }
                    .task(id: districtId, { //This will run when the selected continent changes
                        constituencyId = nil
                        getConstituency.constituency = []
                        //Since a new continent was selected makes the selected country nil and empty the list
                        guard let districtId else { //Proceed if the continent isn't nil
                            return
                        }
                        //Get the new countries list
                        do {
                            try await getConstituency.fetchConstituency(districtId: districtId.id)
                        } catch {
                            //should display error.localizedDescription to user.
                            print(error)
                        }
                    })
                    NavigationLink {
                        test4()
                    } label: {
                        Text("Next")
                            .fontWeight(.bold)
                            .multilineTextAlignment(.center)
                    }
                    
                }
            }
        }
    }
}

第三个视图(提交按钮)

struct test4: View {
    @StateObject var VM = PersonInfoViewModel()
    @StateObject var VM1 = NewVoterViewModel()
    var body: some View {
        VStack{
            Form {
                Section {
                    Button {
                        VM1.makePostAPI(id: VM.id, name: VM.name, address: VM.address, aadharNumber: VM.aadharNumber, email: VM.email, dateofBirth: VM.birthdayString, mobileNumber: VM.mobileNumber, stateId: stateId?.id ?? 0, districtId: districtId?.id ?? 0 , constituencyId: constituencyId?.id ?? 0)
                    } label: {
                        Text("Submit")
                }
                }
            }

        }
    }
}

POST API 实现

POST API 需要必填参数countryId、stateId、districtId和constituencyId,但当前无法将前两个视图的结构体数据传递到提交视图。

class NewVoterViewModel: ObservableObject{
    
    
    //****--POST API CALL--****//
    func makePostAPI(id: Int, name: String, address: String, aadharNumber: String, email: String, dateofBirth: String, mobileNumber: String, stateId: Int, districtId: Int, constituencyId: Int, countryId: Int = 1) {
        
        guard let url = URL(string: "https://janasenanriconnectwebapi.azurewebsites.net/api/Voter/CreateVoter") else {
            return
        }
        
        print("Making api call..")
        
        var request = URLRequest(url: url)
        
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        let body: [String: AnyHashable] = [
              "name": name,
              "gender": "male",
              "dateofBirth": dateofBirth,
              "mobileNumber": mobileNumber,
              "aadharNumber": aadharNumber,
              "email": email,
              "address": address,
              "countryId": countryId,
              "stateId": stateId,
              "districtId": districtId,
              "constituencyId": constituencyId,

        ]
        request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
        
        let task = URLSession.shared.dataTask(with: request) { data, _, error in
            guard let data = data, error == nil  else {
                return
            }
            
            do {
                let response = try JSONDecoder().decode(NewVoter.self, from: data)
                print("SUCCESS: \(response)")
            }
            catch {
                print(error)
            }
        }
        task.resume()
    }
}

GET API 实现

struct States: Hashable, Codable{
    let id: Int
    let value: String
}

@MainActor class StateViewModel: ObservableObject {
    @Published var states: [States] = []
    func fetchStates() async throws {
        let url = "https://janasenanriconnectwebapi.azurewebsites.net/api/MasterData/getStates"
        self.states = try await URLSession.shared.decoded(url: url)
    }
}

struct Districts: Hashable, Codable { 
    let id: Int
    let value: String
}
@MainActor class DistrictsViewModel: ObservableObject {
    
    @Published var districts: [Districts] = []
    
    func fetchDistricts(stateId: Int) async throws {
        let url = "https://janasenanriconnectwebapi.azurewebsites.net/api/MasterData/getDistrict?stateId=\(stateId)"
        
        self.districts = try await URLSession.shared.decoded(url: url)
    }
}

struct Constituency: Hashable, Codable { //Rename to something that represents the object, this isnt a list it is a single object.
    let id: Int
    let value: String
}
@MainActor class ConstituencyViewModel: ObservableObject {
    
    @Published var constituency: [Constituency] = []
    
    func fetchConstituency(districtId: Int) async throws {
        let url = "https://janasenanriconnectwebapi.azurewebsites.net/api/MasterData/getConstituency?districtId=\(districtId)"
        
        self.constituency = try await URLSession.shared.decoded(url: url)
    }
}

我是新手开发者,此前发布过类似问题但表述不够清晰,希望得到问题指正与解决协助,实现将前两个视图(包含结构体数组与GET API返回结构体类型)的数据传递到第三个视图的需求。


内容的提问来源于stack exchange,提问作者CodeBee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 23:19:53