Swift3中替换URL为NSURL后无法使用DataTask的解决方法求助
解决Swift 3中NSURL与URLSession DataTask的兼容问题
嘿,我太懂跟着旧指南踩坑的滋味了!Swift 3对Foundation的API做了不少简化调整,NSURL和URLSession的用法确实和老版本不一样。咱们直接动手改代码,搞定最后这个问题:
关键问题拆解
在Swift 3里,URLSession.dataTask(with:)已经不再直接接受NSURL类型参数,而是要求用原生URL类型。另外,NSURLSessionConfiguration的调用方式变了,还有一堆NS前缀的集合类型(比如NSArray、NSMutableArray)可以换成更Swift化的原生类型,代码会清爽很多。
修改后的完整可运行代码
import Foundation protocol HomeModelProtocol: class { func itemsDownloaded(items: [Any]) } class HomeModel: NSObject, URLSessionDataDelegate { // 属性定义 weak var delegate: HomeModelProtocol! let urlPath = "http://iosquiz.com/service.php" // 后续可替换为你的service.php实际路径 func downloadItems() { // 推荐用Swift原生URL替代NSURL guard let url = URL(string: urlPath) else { print("URL格式无效") return } // 获取默认Session配置并创建Session实例 let defaultSessionConfig = URLSessionConfiguration.default let session = URLSession(configuration: defaultSessionConfig, delegate: self, delegateQueue: nil) // 创建DataTask(现在接受URL类型参数) let task = session.dataTask(with: url) { [weak self] data, response, error in guard let self = self else { return } if let error = error { print("数据下载失败:\(error.localizedDescription)") return } guard let validData = data else { print("未获取到有效数据") return } print("数据下载成功") self.parseJSON(validData) } task.resume() } func parseJSON(_ data: Data) { var jsonResult: [Any] = [] do { // Swift 3简化了JSONSerialization写法 jsonResult = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [Any] } catch let error as NSError { print("JSON解析失败:\(error)") } // 用Swift原生数组替代NSMutableArray var locations: [LocationModel] = [] for element in jsonResult { guard let jsonElement = element as? [String: Any] else { continue } let location = LocationModel() // 简化可选绑定逻辑 location.name = jsonElement["Name"] as? String location.address = jsonElement["Address"] as? String location.latitude = jsonElement["Latitude"] as? String location.longitude = jsonElement["Longitude"] as? String locations.append(location) } // 通知代理数据处理完成 delegate?.itemsDownloaded(items: locations) } } // 补充LocationModel定义(如果之前没写的话) class LocationModel: NSObject { var name: String? var address: String? var latitude: String? var longitude: String? }
核心修改点说明
- 替换NSURL为URL:Swift 3推荐使用原生
URL类型,比NSURL更符合Swift语法;如果一定要保留NSURL,也可以通过nsUrl as URL转换后传给dataTask。 - Session配置创建:原来的
Foundation.NSURLSessionConfiguration要改成URLSessionConfiguration.default获取默认配置,再创建URLSession实例。 - 闭包弱引用self:添加
[weak self]避免循环引用,这是Swift里常见的内存优化写法。 - 原生集合替代NS前缀类型:把
NSArray换成[Any],NSMutableArray换成[LocationModel],NSDictionary换成[String: Any],addObject换成append,代码更简洁易读。 - 简化JSON解析写法:
NSJSONSerialization可以直接写成JSONSerialization,去除冗余前缀。
这样改完后,你的DataTask就能正常工作了,代码也更贴合Swift 3的规范~
内容的提问来源于stack exchange,提问作者SophieT
相关产品推荐
相关产品推荐

