如何在 Swift 3 中将 NSData 转换为数据?

Posted

技术标签:

【中文标题】如何在 Swift 3 中将 NSData 转换为数据?【英文标题】:How to convert NSData to Data in Swift 3? 【发布时间】:2017-01-16 18:45:53 【问题描述】:

我正在尝试创建一个简单的天气应用程序,该应用程序可以获取用户的位置并使用 Google Maps api 显示简单的天气数据。一切正常,除了我获取 JSON 并获取地址的部分。

func getAddressForLatLng(latitude: String, longitude: String) 
    let url = NSURL(string: "\(baseUrl)latlng=\(latitude),\(longitude)&key=\(apikey)")
    let data = NSData(contentsOf: url! as URL)
    let json = try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! Dictionary
    if let result = json["results"] as? Dictionary 
        if let address = result[0]["address_components"] as? Array 
            let number = address[0]["short_name"] as! String
            let street = address[1]["short_name"] as! String
            let city = address[2]["short_name"] as! String
            let state = address[4]["short_name"] as! String
            let zip = address[6]["short_name"] as! String
            weatherDisplay.text = "\(city),\(state)"
        
    

上线:

let json = try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! Dictionary 

我收到此错误:

Cannot invoke 'jsonObject' with an argument list of type '(with: NSData?, options: JSONSerialization.ReadingOptions)'

我做错了什么?

【问题讨论】:

这里根本不需要使用 NSData(或 NSURL)。 let url = URL(string: ...), let data = Data(contentsOf: ...) 问题是你将一个可选项传递给JSONSerialization。您可以强制解包数据,例如JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! Dictionary 请注意,使用 NSData(contentsOf: url! as URL)(或 Swift 3 中的 Data(contentsOf:))是个坏主意。这是一个同步调用,将冻结 UI 直到它完成。你真的应该重写它来使用 NSURLSession。 我很难理解为什么这被否决了。在集合和相关标签的范围内似乎是一个合法的问题。 @LukeVanIn 你为什么要使用allowFragments?你知道如果下载失败,强制解包会崩溃吗? 【参考方案1】:
let nsdata = NSData()    
let data = Data(referencing: nsdata)

https://developer.apple.com/documentation/foundation/data/3126627-init

【讨论】:

【参考方案2】:

您需要更改一些内容。首先,您使用的是NSData。您应该使用 Swift 类型 Data。要将NSData? 转换为Data?,只需将as Data? 添加到变量声明的末尾即可。

另外,你的类型是可选的,但你不能传入可选类型,所以你需要解开它(在这个例子中使用if let data = data /* stuff here */):

func getAddressForLatLng(latitude: String, longitude: String) 
    let url = NSURL(string: "\(baseUrl)latlng=\(latitude),\(longitude)&key=\(apikey)")
    let data = NSData(contentsOf: url! as URL) as Data? // <==== Added 'as Data?'
    if let data = data  // <====== Added 'if let'
        let json = try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! Dictionary
        if let result = json["results"] as? Dictionary 
            if let address = result[0]["address_components"] as? Array 
                let number = address[0]["short_name"] as! String
                let street = address[1]["short_name"] as! String
                let city = address[2]["short_name"] as! String
                let state = address[4]["short_name"] as! String
                let zip = address[6]["short_name"] as! String
                weatherDisplay.text = "\(city),\(state)"
            
        
    

更新:

你需要改变的另一件事是:

let json = try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! Dictionary

当您转换为Dictionary 类型时,编译器不知道您在说什么,因为Dictionary 是generic type。所以你需要转换为Dictionary&lt;String, AnyObject&gt;[String: AnyObject] (它们是相同的)。

【讨论】:

感谢您的快速回复!现在它说(在 let = json 行上)“通用参数 'key' 无法推断为 'Dictionary<_>” @EricPhillips 更新了我的答案! 现在,在if let address = result[0]["address_components"] as? Array 行上,它显示“对成员'下标'的模糊引用”。还有什么我应该添加/更改的吗? @EricPhillips 不确定。我知道Array 类型就像Dictionary 类型。您需要添加数组的类型,即Array&lt;String&gt;。如果您还有更多问题,我建议您使用 Google 搜索,然后在 SO (Stack Overflow) 上提出一个新问题。【参考方案3】:

刚投:let newData = nsData as Data

【讨论】:

这不是let data = NSData(contentsOf: url! as URL) as Data? // &lt;==== Added 'as Data?' 在the accepted answer 中所做的吗?

以上是关于如何在 Swift 3 中将 NSData 转换为数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 3 中将字典表示为 NSValue?

将 UIImage 转换为 NSData 并在 Swift 中转换回 UIImage?

在 Swift 中将 UIView 保存和检索为 NSData

如何在 iPhone 中将 NSData 转换为字节数组?

如何在 iOS 中将 NSData 变量转换为 NSInteger 变量

在 Swift 3 中将 JSON 对象解析为 NSArray