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
Ambiguous Method Overload with Closures in Swift, But Only When Closure Returns a Value
Performing a Completion Handler Before App Launches
Nsmanagedobject Subclasses Duplicate Declaration
Label Showing Top of Screen Instead of Being on the Inputaccessoryview
Interrupted Purchase Not Calling Delegate After Accepting T&C
How to Change the Order of Functions Triggered
Cannot Read Property 'Keycode' 'Character' Assertion Failure When Detect Modifier Key + Numeric Key
Exc Bad Access After Coding Signing
How to Give Dynamic Height to Uitableview
Swiftui - Mapkit - Binding Mapkit and Show View on Annotation Callout Buttons
Downloading Firebase Storage Files Device Issue
Swift Format Text Field When User Is Typing
Core Data Update in Swift While Selecting Any Row in List Table View Not Working
Retrieve an Image from Firebase to an Uiimage Swift5
Why Does the Compiler Not See the Default Code in a Protocol
Why Can't I Use 'Type' as the Name of an Enum Embedded in a Struct
Swift: Can't Edit Properties of Custom Table Cell Programmatically