Hi all:
I am working on a POC IOS app that needs to authtenticate to a SA+QL Server Azure database. I wrote a web service in .NET, also osted on Azure, and found some examples that let me write the code below in my IOS app. So when the user taps the login button, the function calls the submitPost code, and the line print("response: ", utf8Representation) prints the response to the console. The web service will return "Success" if the authentication creentials are valid, and I need to return this value back to the login button function so I can take action based on the result, but I've been struggling trying to figure out how. Can anyone offer a suggestion? Note this is just a POC so if this isn't the best way to do this I am not worried about it right now, just need this to work! Thanks for any and all input!
Code in Login Function>>>
let myPost = User(username: "User1", password: "PW")
submitPost(post: myPost) { (error) in
if let error = error {
fatalError(error.localizedDescription)
}
}
Submit function>>>
func submitPost(post: User, completion:((Error?) -> Void)?)
{
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "mysite1.azurewebsites.net"
urlComponents.path = "/Authenticate"
guard let url = urlComponents.url else { fatalError("Could not create URL from components") }
var request = URLRequest(url: url)
request.httpMethod = "POST"
var headers = request.allHTTPHeaderFields ?? [:]
headers["Content-Type"] = "application/json"
request.allHTTPHeaderFields = headers
let encoder = JSONEncoder()
do {
let jsonData = try encoder.encode(post)
request.httpBody = jsonData
print("jsonData: ", String(data: request.httpBody!, encoding: .utf8) ?? "no body data")
} catch {
completion?(error)
}
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: request) { (responseData, response, responseError) in
guard responseError == nil else {
completion?(responseError!)
return
}
if let data = responseData, let utf8Representation = String(data: data, encoding: .utf8)
{
print("response: ", utf8Representation)
} else {
print("no readable data received in response")
}
}
task.resume()
}
Currently, one of the most popular ways is using `Result` type as an argument to the completion handler:
func submitPost(post: User, completion:((Result<String, Error>) -> Void)?) {
//...
let encoder = JSONEncoder()
do {
let jsonData = try encoder.encode(post)
request.httpBody = jsonData
print("jsonData: ", String(data: request.httpBody!, encoding: .utf8) ?? "no body data")
} catch {
completion?(.failure(error)) //<-
}
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: request) { (responseData, response, responseError) in
guard responseError == nil else {
completion?(.failure(responseError!)) //<-
return
}
if
let data = responseData,
let utf8Representation = String(data: data, encoding: .utf8)
{
print("response: ", utf8Representation)
completion?(.success(utf8Representation)) //<-
} else {
print("no readable data received in response")
completion?(.success("no readable data received in response")) //or you may want to pass .failure with your own error
}
}
task.resume()
}
You can use it like this:
submitPost(post: myPost) { (result) in
switch result {
case .success(let value):
print(value)
//...use value here
case .failure(let error):
print(error)
fatalError(error.localizedDescription)
}
}