I am creating a simple login app with custom error message display in an alert for API response failure. Below is my code
@State private var username = ""
@State private var password = ""
@State private var isPresentederror = false
var body: some View {
NavigationView{
ZStack{
VStack{
TextField("Username", text : $username)
.autocapitalization(.none)
.padding()
.frame(width:300,height: 50)
SecureField("Password", text : $password)
.padding()
.frame(width:300,height: 50)
Button("Login"){
authenticateUser(username: username, password: password)
}
.foregroundColor(.white)
.frame(width: 300, height: 50)
.background(Color.blue)
.cornerRadius(10)
.alert("Error", isPresented: $isPresentederror, actions: {
}, message: {
Text("Something went wrong! Please try again")
})
}
}
.navigationBarHidden(true)
}
}
on Click of LOGIN button I am calling a function authenticateUser by passing username and password as a parameter Below is my authenticateUser function code
func authenticateUser(username: String, password: String){
let method = "POST"
let urlString = "http://myapi_to verify_username_password"
var urlHeader=//header part goes here
let json: [String: Any] = ["password": password,
"username": username]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
urlHeader.httpBody = jsonData
URLSession.shared.dataTask(with: urlHeader) { (data, response , error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8) ?? "Invalid JSON")
do {
//success code working fine
} catch {
print("Error:\(error.localizedDescription)")
print(error)
isPresentederror = true
}
}.resume()
}
success is working fine for me, but on error I am showing an alert with manual text "Something went wrong! Please try again". I want to show an error message coming from API. the line
print(String(data: data, encoding: .utf8) ?? "Invalid JSON")
in above function gives an object as below
{"timestamp":"2022-09-30T10:03:29.142 00:00","status":501,"error":"Please verify the data you have sent Found","path":"path_to_url"}
I want to show the error inside alert which is "Please verify the data you have sent Found" coming from API. I tried decoding it and UTF method but it always gives me an error. so please help me to achieve this
CodePudding user response:
You could try this approach, to ...pass response error coming from API
, using a @State var errorMessage
and
testing the httpResponse.statusCode
, such as in this example code:
struct LoginView: View {
@State private var username = ""
@State private var password = ""
@State private var isPresentederror = false
// -- here
@State var errorMessage = "Something went wrong! Please try again"
var body: some View {
NavigationView{
ZStack{
VStack{
TextField("Username", text : $username)
.autocapitalization(.none)
.padding()
.frame(width:300,height: 50)
SecureField("Password", text : $password)
.padding()
.frame(width:300,height: 50)
Button("Login"){
authenticateUser(username: username, password: password)
}
.foregroundColor(.white)
.frame(width: 300, height: 50)
.background(Color.blue)
.cornerRadius(10)
.alert("Error", isPresented: $isPresentederror, actions: {
}, message: {
Text(errorMessage) // <-- here
})
}
}
.navigationBarHidden(true)
}
}
func authenticateUser(username: String, password: String){
let urlString = "https://myapi_to verify_username_password"
var request = URLRequest(url: URL(string: urlString)!)
request.httpMethod = "POST"
let json: [String: Any] = ["password": password, "username": username]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
request.httpBody = jsonData
URLSession.shared.dataTask(with: request) { (data, response , error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8) ?? "Invalid JSON")
// when the response describing the error, is returned as json
do {
let decoded = try JSONDecoder().decode(ApiError.self, from: data)
errorMessage = decoded.error
isPresentederror = true
return
} catch { }
// -- here
guard let httpResponse = response as? HTTPURLResponse else {
errorMessage = "Unknown error"
isPresentederror = true
return
}
if (httpResponse.statusCode == 401) {
errorMessage = "Unauthorized"
isPresentederror = true
return
}
if (405..<500 ~= httpResponse.statusCode) {
errorMessage = "Client error"
isPresentederror = true
return
}
if (500..<600 ~= httpResponse.statusCode) {
errorMessage = "Server error"
isPresentederror = true
return
}
// ...etc...
do {
//success code working fine
try JSONDecoder().decode([String].self, from: data)
//....
} catch {
print("Error:\(error.localizedDescription)")
// -- here
errorMessage = error.localizedDescription
isPresentederror = true
}
}.resume()
}
}
// consult the server docs
struct ApiError: Codable {
var timestamp: String
var status: Int
var error: String
var path: String
}