I have created a basic login function using the POST http method. The credentials are sent successfully and the server authentication successfully. The httpResponse.statusCode
is sent over and is printed into the console. I am trying to make an Alert httpResponse.statusCode
is 400 and load a new view if it is 200. This is the code I am using;
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)
The AlertView does not popup and the AreaView()
doesn't load either. The only command that works within the if statement is print. I've done a bunch of googling to try and find out the issue but SwiftUI is just too new. The console doesn't give me any error messages either. It's worth noting that the code I have was generated by PostMan. Any help is appreciated.
The basic thing you'll need here is to refactor your approach to accommodate SwiftUI's declarative nature, as opposed to UIKit's imperative nature.
If you look at the warnings you'll get in Xcode, you'll see things like "Result of 'Alert' initializer is unused
". This is because you're creating an instance of an Alert
, but it is immediately thrown away at the end of the current scope, as it has no connection to your view.
As a simplified example of what this might look like in 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()
}
}