SwiftUI читает код ответа http и может распечатать его в консоли, но не будет запускать любой другой код в операторе if - PullRequest
0 голосов
/ 02 ноября 2019

Я создал базовую функцию входа в систему, используя HTTP-метод POST. Учетные данные успешно отправлены и проверка подлинности сервера успешно. httpResponse.statusCode передается и печатается в консоли. Я пытаюсь сделать Alert 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. Любая помощь приветствуется.

1 Ответ

0 голосов
/ 02 ноября 2019

Основная вещь, которая вам здесь понадобится, - это рефакторинг вашего подхода, чтобы приспособить декларативную природу SwiftUI, в отличие от императивной природы UIKit.

  • В UIKit вы должны описать шаги, чтобы ваш интерфейс выглядел определенным образом (например, когда происходит это событие, отобразите это предупреждение).
  • В SwiftUI вы описываете, как должен выглядеть пользовательский интерфейс для любогосостояние приложения, и позволяет фреймворку добраться до вас (например, когда приложение находится в этом состоянии, отображается предупреждение)

Если вы посмотрите на предупреждения, которые вы получите в Xcode, вы 'увидим такие вещи, как "Result of 'Alert' initializer is unused". Это потому, что вы создаете экземпляр Alert, но он сразу же отбрасывается в конце текущей области, так как он не связан с вашим представлением.

В качестве упрощенного примера того, чтоэто может выглядеть как в SwiftUI:

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()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...