Swift技术问题:在URLSessionTask流程中设置ViewController标签文本
解决方案:通过CompletionHandler更新ViewController标签文本
我帮你梳理并完善了整个实现流程,确保你能顺利把解析后的JSON字符串设置到ViewController的标签上:
第一步:完善TransportServices的网络请求与解析逻辑
首先要让getLyftData方法正确处理网络请求、JSON解析,并通过completion handler返回你需要的特定字符串。这里我写了完整的实现示例,你可以根据实际API返回的JSON结构调整解析部分:
import Foundation class TransportServices { // 定义completion handler类型,让代码更清晰 typealias LyftDataCompletion = (String?, Error?) -> Void func getLyftData(origin: String, destination: String, completion: @escaping LyftDataCompletion) { // 替换成你的实际Lyft API请求地址 guard let requestUrl = URL(string: "https://your-lyft-api-endpoint.com?origin=\(origin)&destination=\(destination)") else { completion(nil, NSError(domain: "InvalidURL", code: 0, userInfo: [NSLocalizedDescriptionKey: "请求地址无效"])) return } var request = URLRequest(url: requestUrl) request.httpMethod = "GET" // 如果API需要授权,在这里添加请求头,比如: // request.setValue("Bearer your_api_token_here", forHTTPHeaderField: "Authorization") // 发起后台网络请求 let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in // 先处理网络层面的错误 if let requestError = error { completion(nil, requestError) return } // 确保返回了有效数据 guard let responseData = data else { completion(nil, NSError(domain: "NoData", code: 1, userInfo: [NSLocalizedDescriptionKey: "未获取到返回数据"])) return } do { // 解析JSON,这里假设你的API返回包含目标字段的字典结构 if let jsonDict = try JSONSerialization.jsonObject(with: responseData) as? [String: Any] { // 提取你需要的特定字符串,比如"estimated_price"或"arrival_time",替换成你的实际字段 if let targetString = jsonDict["estimated_price"] as? String { completion(targetString, nil) } else { completion(nil, NSError(domain: "ParseError", code: 2, userInfo: [NSLocalizedDescriptionKey: "未找到目标字段"])) } } else { completion(nil, NSError(domain: "ParseError", code: 3, userInfo: [NSLocalizedDescriptionKey: "JSON结构不匹配"])) } } catch { completion(nil, error) } } dataTask.resume() } }
第二步:在SecondViewController中调用并更新标签
注意!网络请求的completion handler是在后台线程执行的,必须回到主线程更新UI,否则会导致崩溃。另外用[weak self]避免内存泄漏:
import UIKit class SecondViewController: UIViewController { // 假设你已经通过Storyboard/XIB创建了这个标签的IBOutlet @IBOutlet weak var lyftInfoLabel: UILabel! let transportService = TransportServices() override func viewDidLoad() { super.viewDidLoad() // 替换成你的实际起点和终点参数 let origin = "37.7749,-122.4194" // 示例坐标:旧金山 let destination = "37.3352,-121.8811" // 示例坐标:圣何塞 // 调用数据获取方法 transportService.getLyftData(origin: origin, destination: destination) { [weak self] targetString, error in // 回到主线程更新UI DispatchQueue.main.async { if let fetchError = error { // 显示错误提示 self?.lyftInfoLabel.text = "获取数据失败:\(fetchError.localizedDescription)" } else if let resultString = targetString { // 设置标签文本为解析后的特定字符串 self?.lyftInfoLabel.text = resultString } else { self?.lyftInfoLabel.text = "暂无数据" } } } } }
几个关键提醒
- 主线程更新UI:这是iOS开发的基本规则,所有UI操作必须在主线程执行,所以一定要用
DispatchQueue.main.async包裹标签设置代码。 - 弱引用避免泄漏:闭包中捕获
self时用[weak self],防止ViewController因为闭包的强引用无法被释放。 - 适配实际JSON结构:上面的解析逻辑是示例,你需要根据Lyft API实际返回的JSON结构调整字段提取的代码,比如如果是嵌套的JSON对象,要逐层解析。
- 错误处理:不要忽略错误情况,给用户显示友好的提示,也方便你调试问题。
内容的提问来源于stack exchange,提问作者Andreas P.
相关产品推荐
相关产品推荐

