About retrieving data from the API using URLSessionTask on Swift4.

Asked 2 years ago, Updated 2 years ago, 95 views

[What I want to do]
I want to store data from the GetDataFromAPI class getDataFromAPI function in the ViewController class variable data.

つまStumbling points br
I don't know how to return the variables in the closure and it's not working.

We have not been able to implement this part for about a week, and the development has stopped.
Thank you for your cooperation

ViewController.swift

import UIKit

classViewController:UIViewController {
    vardata: String=""

    override func viewDidLoad(){
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from anib.
        letgetDataObject=GetDataFromAPI()
        let returnData=getDataObject.getDataFromAPI()
        data=returnData
        print("data:\(data)")

    }


}

GetData.swift

import Foundation

structure JsonData:Codable {
    // The JSON returned this time is {"key":"value"}
    let key —String
}

classGetDataFromAPI {
    var formattedData: String=""

    funcgetDataFromAPI()->String{
        let url : URL = URL (string: "http://127.0.0.1:5000/study")!
        let dispatchGroup = DispatchGroup()

        dispatchGroup.enter()
        let task: URLSessionTask = URLSession.shared.dataTask(with:url, completionHandler: {data, response, error in)
            letdecoder: JSONDecoder= JSONDecoder()
            do{
                let data: JsonData=try decoder.decode(JsonData.self, from:data!) // Contains retrieved data

                print("Data Retrieved")
                self.formattedData=data.key
                print(self.formattedData)

            } catch{
                print("error:", error.localizedDescription)
            }
        })
        task.resume()// Run
        return self.formattedData
    }

}

swift ios swift4

2022-09-30 19:49

1 Answers

URLSessionTask The trick to master the asynchronous API is to abandon the idea of returning a value (as a return value).The important thing for your app is to make sure you take advantage of the values you get from the server, and the purpose of the development should not be to "force a variable coding that returns asynchronously as a return value".

In today's Swift, which does not have a standard toolset for asynchronous support, it is common to adopt a completion handler pattern in such cases.

class GetDataFromAPI{

    func getDataFromAPI(completion:@escaping(String)->Void) {//<- add your own completion handler argument
        let url : URL = URL (string: "http://127.0.0.1:5000/study")!

        let task: URLSessionTask = URLSession.shared.dataTask(with:url, completionHandler: {data, response, error in)
            letdecoder: JSONDecoder= JSONDecoder()
            do{
                let data: JsonData=try decoder.decode(JsonData.self, from:data!) // Contains retrieved data

                print("Data Retrieved")
                print(data.key)
                Call your own completion handler in completion(data.key)//<-`URLSession.dataTask(with:completionHandler:)` completion handler

            } catch{
                print("error:", error.localizedDescription)
                completion("")//<- Same as above (think about the error)
            }
        })
        task.resume()// Run
        // ↑ If you call `task.resume(), don't do anything else.
    }

}

(formattedData is a problem when multiple requests are sent at the same time, so I deleted it.)

This is what the caller looks like.

let getDataObject=GetDataFromAPI()
    getDataObject.getDataFromAPI {returnDatain
        self.data=returnData//<- Avoid naming variables of type `String` as `data` in actual code
        print("data:\(self.data)")
    }

Similar questions have been asked many times in the past on this Japanese stack overflow and online blogs and bulletin boards, some of which may include "force asynchronous values back as return values" but all have disadvantages such as "coding complexity only works in certain cases."

Get used to the right way as soon as possible.


2022-09-30 19:49

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.