Reputation: 647
Summary
I'm querying an API for a user with the user's login username and password in an asynchronous task. I found one method of doing this by:
API File
class API {
var delegate: APIDelegate?
required init(providedDelegate: APIDelegate){
delegate = providedDelegate
}
func getPOSTData(){
API.request(URL, method: .post).responseJSON
{ response in
if response.result.value != nil {
//print("JSON: \(JSON)")
self.delegate?.onSuccess(jsonData: JSON as! [String : Any])
} else {
self.delegate?.onFailure(error: "No JSON Data")
}
}
}
}
View Controller File
protocol APIDelegate{
func onSuccess(jsonData: [String:Any])
func onFailure(error: Any)
}
UIViewControllerName : UIViewController, APIDelegate{
var delegate: APIDelegate?
func testAPICall(sender: UIButton){
let client = API(providedDelegate: delegate!)
client.getPOSTData()
}
func onSuccess(jsonData: [String:Any]) {
print("JSON: \(jsonData)")
}
func onFailure(error: Any) {
print(error)
}
}
Question
Is this going to cause problems in the long run? Is there a better way to share data between an asynchronous task from another class back up to the calling UIViewController?
Upvotes: 2
Views: 1261
Reputation: 285059
Basically your code is supposed to work, however I highly recommend to use a callback closure rather than protocol / delegate.
The code uses an enum to be able to return a single value and a switch
statement to handle the cases on the caller side:
enum APIResult {
case success([String:Any])
case failure(Any)
}
class UIViewControllerName : UIViewController {
func testAPICall(sender: UIButton) {
let client = API()
client.getPOSTData() { result in
switch result {
case .success(let jsonData) : print("JSON: \(jsonData)")
case .failure(let error) : print("JSON: \(error)")
}
}
}
}
class API {
func getPOSTData(completion: (APIResult)->() ) {
API.request(URL, method: .post).responseJSON
{ response in
if response.result.value != nil {
//print("JSON: \(JSON)")
completion(.success(JSON as! [String : Any]))
} else {
completion(.failure("No JSON Data"))
}
}
}
}
Upvotes: 2
Reputation: 8322
You can pass data through closure
Declare block
typealias responseHandler = (_ responseObject: [String : Any]) -> Void
func getPOSTData(with callback : responseHandler){
API.request(URL, method: .post).responseJSON
{ response in
if response.result.value != nil {
//print("JSON: \(JSON)")
self.delegate?.onSuccess(jsonData: JSON as! [String : Any])
callback(JSON as! [String : Any])
} else {
callback([:] as! [String : Any] )
}
}
}
Invoke as below
client.getPOSTData { (responseData) in
print(responseData)
// here your data
}
Upvotes: 1