SwiftUI 读取 http 响应代码并可以在控制台中打印它,但不会 运行 if 语句中的任何其他代码

SwiftUI reads http response code and can print it in the console but won't run any other code within the if statement

我使用 POST http 方法创建了一个基本的登录功能。凭据发送成功,服务器身份验证成功。 httpResponse.statusCode 被发送并打印到控制台中。我正在尝试发出警报 httpResponse.statusCode 是 400,如果它是 200,则加载一个新视图。这是我正在使用的代码;

Button(action: {
    let login = self.username
    let passwordstring = self.password
    guard let url = URL(string: "http://localhost:8000/account/auth/") else {return}

    let headers = [
        "Content-Type": "application/x-www-form-urlencoded",
        "cache-control": "no-cache",
        "Postman-Token": "89a81b3d-d5f3-4f82-8b7f-47edc39bb201"
    ]

    let postData = NSMutableData(data: "username=\(login)".data(using: String.Encoding.utf8)!)
    postData.append("&password=\(passwordstring)".data(using: String.Encoding.utf8)!)

    let request = NSMutableURLRequest(url: NSURL(string: "http://localhost:8000/account/auth/")! as URL,
                                      cachePolicy:.useProtocolCachePolicy, timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data

    let session = URLSession.shared
    let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) in
        if let httpResponse = response as? HTTPURLResponse {
            guard let data = data else {return}
            print(data)
            if httpResponse.statusCode == 200{
                DispatchQueue.main.async {
                    //Segue to new view goes here
                    print(httpResponse.statusCode)

                    AreaView().animation(.easeIn)
                }
            }else{
                if httpResponse.statusCode == 400{
                    DispatchQueue.main.async {
                        Alert(title: Text("Oops"), message: Text("Username or Password Incorrect"), dismissButton: .default(Text("Got it!")))
                        print(httpResponse.statusCode)

                    }
                }else{
                    DispatchQueue.main.async {
                        Alert(title: Text("Well Damn"), message: Text("Ay chief we have no idea what just happened but it didn't work"), dismissButton: .default(Text("Got it!")))

                    }
                }
            }
            do{

                let JSONFromServer = try JSONSerialization.jsonObject(with: data, options: [])
                let decoder = JSONDecoder()
                decoder.keyDecodingStrategy = .convertFromSnakeCase
                let tokenArray = try decoder.decode(token.self, from: data)
                print(tokenArray.token)
                UserDefaults.standard.set(tokenArray.token, forKey: "savedToken")
                let savedToken = UserDefaults.standard.object(forKey: "savedToken")
                print(savedToken)
            }catch{
                if httpResponse.statusCode == 400{
                    Alert(title: Text("Oops"), message: Text("Username or Password Incorrect"), dismissButton: .default(Text("Got it!")))

                }
                print(error)
                print(httpResponse.statusCode)
            }
        } else if let error = error {

            Alert(title: Text("Well Damn"), message: Text("Ay chief we have no idea what just happened but it didn't work"), dismissButton: .default(Text("Got it!")))

            print(error)
        }
    })
    dataTask.resume()

})//end of login function
{
    Image("StartNow 3").resizable()
        .scaledToFit()
        .padding()
}
    .padding(.horizontal, 15).offset(y: -50)

AlertView 不会弹出,AreaView() 也不会加载。在 if 语句中唯一有效的命令是 print。我进行了大量谷歌搜索以尝试找出问题所在,但 SwiftUI 太新了。控制台也不给我任何错误消息。值得注意的是,我的代码是由 PostMan 生成的。感谢任何帮助。

这里您需要做的基本事情是重构您的方法以适应 SwiftUI 的 声明性 性质,而不是 UIKit 的性质命令自然

  • 在 UIKit 中,您必须描述让您的 UI 以某种方式显示的步骤(例如,当此事件发生时,显示此警报)。
  • 在 SwiftUI 中,您描述 UI 对于任何应用程序状态应该是什么样子,然后让框架将您带到那里(例如,当应用程序处于此状态时,会发出警报正在显示)

如果您查看 Xcode 中的警告,您会看到类似“Result of 'Alert' initializer is unused”的内容。这是因为您正在创建 Alert 的实例,但它会在当前范围的末尾立即被丢弃,因为它与您的视图没有任何联系。

作为 Swift 中的简化示例UI:

struct ContentView: View {
    @State private var showingAreaView = false
    @State private var showingAlert = false
    @State private var alertTitle = ""
    @State private var alertMessage = ""

    var body: some View {
        VStack {
            Button("Login") {
                self.login()
            }

            // only show the AreaView when showingAreaView == true
            // this will be set in the completion handler
            if showingAreaView {
                AreaView()
                    .animation(.easeIn)
            }
        }
        // only present an Alert when showingAlert == true
        // this will be set in the completion handler
        .alert(isPresented: $showingAlert) { () -> Alert in
            Alert(title: Text(alertTitle),
                  message: Text(alertMessage),
                  dismissButton: .default(Text("Got it!")))
        }
    }

    func login() {

        // setting up request, session, dataTask, etc.
        ...

            if httpResponse.statusCode == 200 {
                // if request is successful, show AreaView
                DispatchQueue.main.async {     
                    // do something with data here               
                    self.showingAreaView = true
                }
            } else if httpResponse.statusCode == 400 {
                // if request is unsuccessful, show Alert
                DispatchQueue.main.async {
                    self.alertTitle = "Oops"
                    self.alertMessage = "Username or Password Incorrect"
                    self.showingAlert = true
                }
            }

        ...

        dataTask.resume()
    }
}