0

我需要向登录视图(SwiftUI)发布一个 https 请求,我的代码遵循我在 getres.swift 中的:所以我需要从响应中获取价值并将其放在文本中

      import Foundation
        import Combine

        struct result: Decodable {
           let res, ordercount, rate: String
        }

        class getres: ObservableObject {

          let objectWillChange = PassthroughSubject<getres, Never>()
        @Published var authenticated = ""
          @Published var todos = [result]() {
              didSet {
                   objectWillChange.send(self)
              }
           }

            func auth(username: String, password: String) {
            guard let url = URL(string: "http://company.com/auth.php") else { return }

            let body: [String: String] = ["username": username, "password": password]

            let finalBody = try! JSONSerialization.data(withJSONObject: body)

            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            request.httpBody = finalBody
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")

            URLSession.shared.dataTask(with: request) { (data, response, error) in


 guard let data=data else{return}


    let fineldata=try! JSONDecoder().decode(result.self, from: data)


        DispatchQueue.main.async {
            self.todos = [fineldata]
            self.authenticated=fineldata.res


        }


 print(fineldata)









    }.resume()
          }

        }

在登录页面中我尝试显示其他视图

在这段代码中,我将从函数中获取值作为 json 响应我将获取 ordercount 和 rate 我将它放在另一个视图中

 import SwiftUI

    struct ContentView: View {

    @State private var username: String = ""
    @State private var password: String = ""

    @ObservedObject   var manager = getres()


    var body: some View {

        VStack(alignment: .leading) {

            if manager.authenticated == "2"{
                                        userdetails()
                                    }else{


            Text("Username")
            TextField("placeholder", text: $username)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .border(Color.green)
                .autocapitalization(.none)

            Text("Password")
            SecureField("placeholder", text: $password)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .border(Color.green)

            Button(action: {

                self.manager.auth(username: self.username, password: self.password)

            }) {
                HStack{
                    Spacer()
                    Text("Login")
                    Spacer()
                }
                .accentColor(Color.white)
                .padding(.vertical, 10)
                .background(Color.red)
                .cornerRadius(5)
                .padding(.horizontal, 40)

            }

        }.padding()}

       }
      }

      struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
       }

在 userdetails 中,我需要从响应中获取值

struct userdetails: View {

  @State var controller = getres()
    var body : some View{
        ScrollView(Axis.Set.vertical, showsIndicators: true) {

            VStack(spacing: 20){
            Image("wlogo").renderingMode(.original);              HStack(spacing: 15){

                  Spacer()
                  VStack(alignment: .center, spacing: 10) {

                    Text(???).foregroundColor(Color.white).bold()
                        .font(.largeTitle)

                    Text("")
                    .foregroundColor(Color.white)
                        .font(.headline)                  }

                  Spacer()
              }}}}

如何从响应中获取 ordercount 并在视图 userdetails 中输入 text(???) 例如 controller.todos.ordercount 当我尝试 Text( controller.todos.ordercount) json 响应

{"res":"2","ordercount":"20","rate":"5"}
4

1 回答 1

1

更新的答案

1.) 如果您只复制一部分代码会很有帮助 - 这对我们所有人来说都更容易复制 2.) 在手动复制或更改代码中的某些内容之前,您应该自己尝试您的代码。发现以下错误很烦人:

如果 manager.authenticated == "2"{ userdetails() } else{

        Text("Username")
        TextField("placeholder", text: $username)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .border(Color.green)
            .autocapitalization(.none)

        Text("Password")
        SecureField("placeholder", text: $password)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .border(Color.green)

        Button(action: {

            self.manager.auth(username: self.username, password: self.password)

        }) {
            HStack{
                Spacer()
                Text("Login")
                Spacer()
            }
            .accentColor(Color.white)
            .padding(.vertical, 10)
            .background(Color.red)
            .cornerRadius(5)
            .padding(.horizontal, 40)

        }

    }.padding()}

}

您将 .padding() 添加到 if 语句的位置....

3.)您应该以人们可以理解该类的用途并以大写字母开头的方式命名类名,就像Apple对所有类名所做的那样

4.)您还应该开始查看大写的名称(就像Apple一样)5.)因为我必须访问您的页面并且您没有提供示例数据和/或密码我不知道那里有什么数据......

到目前为止,这是我的解决方案代码:

我添加了一些伪造的数据,因为我无法访问您的数据....所以您可以查看详细信息。

struct ToDo: Decodable, Identifiable {

    var id = UUID().uuidString

    let res, ordercount, rate: String
}

class ToDoGetter: ObservableObject {

    let objectWillChange = PassthroughSubject<ToDoGetter, Never>()
    @Published var authenticated = ""
    @Published var todos = [ToDo]() {
        didSet {
            objectWillChange.send(self)
        }
    }

    let someFakingTodos = [
        ToDo(res: "a", ordercount: "5", rate: "75%"),
        ToDo(res: "b", ordercount: "52", rate: "5%"),
        ToDo(res: "c", ordercount: "566", rate: "7%"),
        ToDo(res: "d", ordercount: "53", rate: "33%"),
        ToDo(res: "e", ordercount: "15", rate: "44%"),
        ToDo(res: "f", ordercount: "345", rate: "10%")

    ]

    func auth(username: String, password: String) {
        guard let url = URL(string: "http://company.com/auth.php") else { return }

        let body: [String: String] = ["username": username, "password": password]

        let finalBody = try! JSONSerialization.data(withJSONObject: body)

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.httpBody = finalBody
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        URLSession.shared.dataTask(with: request) { (data, response, error) in


            guard let data=data else{return}

            let fineldata=try! JSONDecoder().decode(ToDo.self, from: data)

            DispatchQueue.main.async {
                self.todos = [fineldata]
                self.authenticated=fineldata.res
            }
            print(fineldata)
        }.resume()
    }
}

struct ContentView: View {

    @EnvironmentObject var todoGetter : ToDoGetter

    @State private var username: String = ""
    @State private var password: String = ""


    @State var navigateToDetail : Bool = false

    var body: some View {
        NavigationView {
            VStack(alignment: .leading) {

                if todoGetter.authenticated == "2"{
                    Userdetails().environmentObject(todoGetter)
                } else{

                    Text("Username")
                    TextField("placeholder", text: $username)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .border(Color.green)
                        .autocapitalization(.none)

                    Text("Password")
                    SecureField("placeholder", text: $password)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .border(Color.green)

                    NavigationLink(destination: Userdetails(), isActive: self.$navigateToDetail) {
                        EmptyView() }
                        .hidden()
                        .padding()

                    Button(action: {

                        self.todoGetter.auth(username: self.username, password: self.password)
                        self.navigateToDetail.toggle()
                    }) {
                        HStack{
                            Spacer()
                            Text("Login")
                            Spacer()
                        }
                        .accentColor(Color.white)
                        .padding(.vertical, 10)
                        .background(Color.red)
                        .cornerRadius(5)
                        .padding(.horizontal, 40)
                    }
                }
            }
        }
    }
}

struct Userdetails: View {

    @EnvironmentObject var todoGetter : ToDoGetter

    var body : some View{

        VStack(spacing: 20) {
            Image("wlogo").renderingMode(.original);              HStack(spacing: 15){

                Spacer()

                List(todoGetter.someFakingTodos) { todo in

                    VStack(alignment: .center, spacing: 10) {
                        HStack {
                            Text(todo.res).foregroundColor(Color.white).bold()
                                .font(.largeTitle)

                            Text(todo.ordercount)
                                .foregroundColor(Color.white)
                                .font(.headline)
                            Text(todo.rate)
                                .foregroundColor(Color.white)
                                .font(.headline)
                        }
                    }.background(Color.black)

                    Spacer()
                }
            }
        }
    }
}

旧答案

你打电话给getres 2次。您只需调用一次,然后将值赋给详细视图。

每个应用程序只能创建一次模型。

于 2020-03-28T13:51:33.937 回答