Ios 如何将数据从API调用传递到ViewController?
我构建了一个Ios 如何将数据从API调用传递到ViewController?,ios,swift,networking,Ios,Swift,Networking,我构建了一个apimager类,该类具有对我的API进行API调用的函数,该API工作正常。然后,我使用一个类APIClient来存储我需要在API上执行的每个调用,这些调用带有特定参数,例如url查询或POST数据 问题是这些函数是空函数,不返回任何内容。我想知道如何修改它以返回可以存储在我的ViewController变量中的数据 以下是我在apimager中使用的函数: func makeRequest(toURL url: URL, withHt
apimager
类,该类具有对我的API进行API调用的函数,该API工作正常。然后,我使用一个类APIClient
来存储我需要在API上执行的每个调用,这些调用带有特定参数,例如url查询或POST数据
问题是这些函数是空函数,不返回任何内容。我想知道如何修改它以返回可以存储在我的ViewController
变量中的数据
以下是我在apimager中使用的函数:
func makeRequest(toURL url: URL,
withHttpMethod httpMethod: HttpMethod,
completion: @escaping (_ result: Results) -> Void) {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
let targetURL = self?.addURLQueryParameters(toURL: url)
let httpBody = self?.getHttpBody()
guard let request = self?.prepareRequest(withURL: targetURL, httpBody: httpBody, httpMethod: httpMethod) else
{
completion(Results(withError: CustomError.failedToCreateRequest))
return
}
let sessionConfiguration = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfiguration)
let task = session.dataTask(with: request) { (data, response, error) in
completion(Results(withData: data,
response: Response(fromURLResponse: response),
error: error))
}
task.resume()
}
}
然后在我的ViewController中定义我的APIClient
,并在点击按钮时调用一个函数:
let apiClient = APIClient()
@IBAction func testTapped(_ sender: Any) {
apiClient.getData()
}
然后我的APIClient
处理调用:
func getData() {
var decodedResponse: Any?
guard let url = URL(string: "https://XX.API.XX/XX//XXX/XXX/XXX") else { return }
apiManager.makeRequest(toURL: url, withHttpMethod: .get) { (results) in
guard let response = results.response else { return }
if response.httpStatusCode == 200 {
guard let data = results.data else { return }
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(Data.self, from: data) else { return }
}
}
}
有人知道我可以用什么方法修改这些文件,以便从
APIClient
返回decodedData
并将其存储在我的ViewController
中吗?如果需要在视图控制器中获得结果,实现这一点的方法之一是通过回调将其传回,就像你将结果从你的经理传递给APIClient一样
func getData(completion handler: @escaping (Data?, Error?) -> Void) {
var decodedResponse: Any?
guard let url = URL(string: "https://XX.API.XX/XX//XXX/XXX/XXX") else { return }
apiManager.makeRequest(toURL: url, withHttpMethod: .get) { (results) in
guard let response = results.response else { return }
if response.httpStatusCode == 200 {
guard let data = results.data else { return }
let decoder = JSONDecoder()
guard let decodedData = try? decoder.decode(Data.self, from: data) else {
handler(NSError(code: 1, ...)) /// <===
return
}
handler(decodedData) /// <===
} else {
handler(results.error) /// <===
}
}
}
虽然这可以回答这个问题,但发布“仅代码”答案并不是一个好主意。如果你能解释一下你的代码在做什么,那会更有帮助。我会尝试一下,谢谢。如果你能解释一下你做了些什么,这确实会有帮助,因为我不完全理解你添加的每一个步骤,以及为什么这是解决我问题的好方法。感谢您查看已编辑的应答改进:您不应该为每个请求创建URLSession对象。这是非常非常。。次优;)将其移动到APIManager类,并确保只创建一次。此外,似乎没有必要向全局队列发送消息。如果,那么当APIManager需要同步时,它应该是APIManager创建的专用调度队列。
@IBAction func testTapped(_ sender: Any) {
apiClient.getData { data, error in
if let data = data {
//do anything with the data
} else if let error = error {
//show the error message
}
}
}