I am fairly new to SwiftUI.
In this example I am running a network request through an API that has a completion handler in order to alter the app state, i.e., show a different view based on a tokens (JWT) validity. I am trying to figure out how to use the completion in the .onAppear of my view to do this, any help would be appreciated:
View code
struct LaunchView: View {
let keychainManager = KeychainManager()
let keychainRecords = KeychainRecords()
let tokenManager = TokenManager()
var validSession: Bool
var body: some View {
ZStack {
if validSession {
HomeView()
} else {
LoginView()
}
}
.onAppear(){
do {
let token = try keychainManager.getToken(identifier: keychainRecords.identifier, service: keychainRecords.service)
let tokenValidationResponse = try tokenManager.validateToken(token: token){ completion in
if Result<TokenValidationResponse, NetworkError> {
guard let message = tokenValidationResponse.Message else { return }
if (message == "Success") {
validSession = true
} else {
validSession = false
}
} else {
// Show an error message
print("Network request failed")
}
}
} catch {
print(error)
}
}
}
Validation code
func validateToken(token: String, completion: @escaping (Result<TokenValidationResponse, NetworkError>) -> Void) {
guard let url = URL(string: BASE_URL + TOKEN) else {
completion(.failure(.invalidURL))
return
}
let body = TokenRequestBody(token: token)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = try? JSONEncoder().encode(body)
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else {
completion(.failure(.noData))
return
}
guard let tokenValidationResponse = try? JSONDecoder().decode(TokenValidationResponse.self, from: data) else {
completion(.failure(.decodingError))
return
}
print(tokenValidationResponse)
completion(.success(tokenValidationResponse))
}.resume()
}
Thank you (PS I am getting a valid response from the request when printed)
Mark your variable with @State.