You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:39:56