Swift Accessing Response from Function

Return response as object in swift

First of all don't use NSDictionary in Swift, use native [String:Any] and declare the type as optional to return nil if an error occurs.

And never use .mutableContainers in Swift, the option is useless.

func getResponse(accessCode:String, UDID:String, completion: @escaping ([String:Any]?) -> Void)) {
let urlPath = "https://apihosthere.com/api/validate?accessCode=" + accessCode + "&UDID=" + UDID
guard let url = URL(string: urlPath) else { return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error else {
print(error)
completion(nil)
return
}
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!) as? [String:Any] {
print(jsonResult)
completion(jsonResult)
} else {
completion(nil)
}
} catch {
print(error)
completion(nil)
}
}
task.resume()
}

Your mistake is that you don't consider the closure, you have to execute the entire code inside the completion handler

@IBAction func StartWizard(_ sender: UIButton) {
//Store entered access code
let accessCode = AccessCodeField.text!
//Call API to validate Access Code
getResponse(accessCode:accessCode, UDID:myDeviceUDID) { [weak self] result in
if let accessCodeFound = result?["Found"] as? Bool {
print("Value of Found during function:")
//If access code is valid, go to License view
print(accessCodeFound)

if accessCodeFound {
//Load License View
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let licenseController = storyboard.instantiateViewController(identifier: "LicenseViewPanel")
self?.show(licenseController, sender: self)
}
}
}
}
}

Method to return value retrieved from HTTP request

You need a completion as request is asynchronous

func myFunction(zipCode: String,completion:@escaping(_ str:String?) -> () ) {

let siteLink = "http://example.com/zip/" + zipCode
let url = URL(string: siteLink)

let task = URLSession.shared.dataTask(with: url!) { data, response, error in
guard error == nil else {
print(error!)
completion(nil)
return
}
guard let data = data else {
print("Data is empty")
completion(nil)
return
}
let json = try! JSONSerialization.jsonObject(with: data, options: [])
guard let jsonArray = json as? [[String: String]] else {
completion(nil)
return
}
let myData = jsonArray[0]["MyPropertyName"]!
completion(myData)
}
task.resume()
}

Call

myFunction(zipCode: "52484") { (str) in 
if let st = str {
print(st)
}
}

how to use server response and data in other functions in swift 3

You need to declare the variables you want to share between functions on the class level so they can be accessed by each function in the class. token is an instance property of the class with this implementation, so each class instance has its own variable called token that can be accessed anywhere inside the class.

class MyViewController: UIViewController {
var token = ""

@IBAction func Login(_ sender: UIButton) {
guard let url = URL(string: "url was here..lol") else {return}
var request = URLRequest(url: url)
request.httpMethod = "POST"
let postString = "data to be posted"
print(postString)
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let response = response {
print(response)
}
if let data = data {
guard let json = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any] else {return}
guard let receivedToken = json["access_token"] as? String else {return}
self.token = receivedToken
otherFunction()
}
}
task.resume()
}

func otherFunction(){
print(token)
}
}

How to write alamofire request function that returns the response?

You can pass a closure as a parameter to the function like this

func callAPI(params: Dictionary<String, Any>, url: String, completion:@escaping (((Dictionary<String,Any>?) -> Void))) -> Void {
let hud = MBProgressHUD.showAdded(to: self.view, animated: true)
hud.contentColor = UIColor.red
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding(options: []), headers: nil).responseJSON { response in
hud.hide(animated: true)
switch response.result{
case .success:
if let resultJson = response.result.value as? Dictionary<String,Any>{
print(resultJson)
completion(resultJson)
// Success
}
case .failure(let error):
print(error)
completion(nil)
//Failed
}
}
}

Call the function with the closure

callAPI(params: [:], url: "") { resultJson in
guard let resultJson = resultJson else {
return
}
print(resultJson)
}

swift calling async function without a return value

What you're describing is a Task. For example:

Task { await `do`() }
stuff()

This will run do() concurrently with stuff(). If you need to keep track of when do() completes, you can await the task's value:

let task = Task { await `do`() }
stuff()
await task.value // Doesn't actually return anything, but will block

This kind of Task runs in the context of the current Actor, which is usually what you want. If you want something independent of the current Actor, you can use Task.detached() instead.

If you've previously used DispatchQueues, in many of the places you would have written queue.async { ... }, you can now write Task { ... }. The new system is much more powerful, but it maps fairly nicely to the old system if you want it to.



Related Topics



Leave a reply



Submit