URLSession.uploadTask响应处理问题:字符串转Int16失败及异步值传递困惑
问题解决指南
1. 修复带换行符的字符串转Int16失败问题
返回的"7\n"因为包含换行符,直接转换会失败,你可以通过trimmingCharacters(in: .whitespacesAndNewlines)去除字符串首尾的空白和换行符,再执行类型转换:
if let mimeType = response.mimeType, let data = data, let dataString = String(data: data, encoding: .utf8) { print ("got data: \(dataString)") // 清理字符串中的空白与换行符 let cleanedString = dataString.trimmingCharacters(in: .whitespacesAndNewlines) self.globalUserID = Int16(cleanedString) ?? 0 // 此时globalUserID可正确获取到7 }
2. 异步任务返回值的规范处理方式
直接在闭包内修改全局变量globalUserID虽能运行,但会增加代码耦合度,且无法灵活通知调用者任务结果。更合理的做法是使用闭包回调:
// 重写函数,新增完成回调参数 func validateUser(user: User, completion: @escaping (Int16?) -> Void) { // (...) let url = URL(string: "exampleURL") var request = URLRequest(url: url!) request.httpMethod = "POST" request.setValue("text/html", forHTTPHeaderField: "Content-Type") let task = URLSession.shared.uploadTask(with: request, from: jsonData) { data, response, error in if let error = error { print ("error: \(error)") completion(nil) return } guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else { print ("server error") completion(nil) return } if let data = data, let dataString = String(data: data, encoding: .utf8) { let cleanedString = dataString.trimmingCharacters(in: .whitespacesAndNewlines) let userID = Int16(cleanedString) completion(userID) } else { completion(nil) } } task.resume() } // 调用示例 validateUser(user: yourUserInstance) { userID in if let id = userID { self.globalUserID = id // 若需更新UI,必须切回主线程 DispatchQueue.main.async { // 执行UI更新操作 } } else { // 处理请求失败逻辑 } }
注意:URLSession闭包默认在后台线程执行,所有UI相关操作必须通过DispatchQueue.main.async切换到主线程完成。
内容的提问来源于stack exchange,提问作者blendstylez
相关产品推荐
相关产品推荐

