Let me describe view controller (page design) first. I have added one button and one label. And a function is created by me for the button. Here is the ViewController.swift
file:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var btnHitWebService: UIButton!
@IBOutlet weak var lblResult: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func btnHitWebServiceClick(_ sender: Any) {
if (getTokenWithPostMethod() == true)
{
lblResult.text = "yes, we get token: " + g_token
}
else
{
lblResult.text = "there is an error, please try again later"
}
}
func getTokenWithPostMethod() -> Bool{
var funcResult = false
var request = URLRequest(url: URL(string: "https://apiABCDEFG.com/token")!)
request.httpMethod = "POST"
let postString = "grant_type=password&username=ABCDEF&password=ABCDEF"
request.httpBody = postString.data(using: .utf8)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request)
{
data, response, error in
guard let data = data, error == nil else
{
// check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200
{
// check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
do
{
if let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject]
{
g_token = (jsonObject["access_token"] as? String)!
print(g_token)
g_token_type = (jsonObject["token_type"] as? String)!
print("\n")
print(g_token_type)
funcResult = true ;
}
}
catch let error as NSError
{
print(error)
}
}
task.resume()
return funcResult
}
}
Here is my problem: When I click button, it gives me a token in output screen in Xcode (print) but getTokenWithPostMethod()
method returns false. Why does it return false? During the debug process, it jumps from let task =
to task.resume()
. Thanks! (by the way I can't share correct link, username and password. I hope these 3 are not necessary to fix this problem)
You are making an API call. It takes time to return the value. Here return statement will not wait for response. you should use either closure or delegate. You can try the given code:
func getTokenWithPostMethod(handler: @escaping (_ funcResult: Bool) -> Void){
var request = URLRequest(url: URL(string: "https://apiABCDEFG.com/token")!)
request.httpMethod = "POST"
let postString = "grant_type=password&username=ABCDEF&password=ABCDEF"
request.httpBody = postString.data(using: .utf8)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request)
{
data, response, error in
var funcResult = false
if error == nil, let data = data {
do
{
if let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject]
{
g_token = (jsonObject["access_token"] as? String)!
print(g_token)
g_token_type = (jsonObject["token_type"] as? String)!
print("\n")
print(g_token_type)
funcResult = true
}
}
catch let error as NSError
{
print(error)
}
}
// edited
DispatchQueue.main.async {
handler(funcResult)
}
}
task.resume()
}
This will return after the response comes. Replace the calling of that method with :
@IBAction func btnHitWebServiceClick(_ sender: Any) {
getTokenWithPostMethod { (flag) in
if flag {
lblResult.text = "yes, we get token: " + g_token
} else {
lblResult.text = "there is an error, please try again later"
}
}
}
For more details please visit