【问题标题】:Parsing json and convert Double to String (Could not cast value of type 'NSTaggedPointerString' (0x1098a1b90) to 'NSNumber')解析 json 并将 Double 转换为字符串(无法将类型“NSTaggedPointerString”(0x1098a1b90)的值转换为“NSNumber”)
【发布时间】:2017-10-23 23:16:07
【问题描述】:

我有一个这样的 Swift 结构。

func parseData() {

    fetchedProduct = []
    let url = "http://www.koulourades.gr/api/products/get/?category=proionta"

    var request = URLRequest(url: URL(string: url)!)
    request.httpMethod = "GET"

    let configuration = URLSessionConfiguration.default
    let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)

    let task =  session.dataTask(with: request) { (data, response, error) in
        if  (error != nil) {
            print("Error")
        }
        else{
            do {
                let fetchedData = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! NSArray

                for eachFetchedProduct in fetchedData {
                    let eachProduct = eachFetchedProduct as! [String : Any]
                    let title = eachProduct ["ProductTitle"] as! String
                    let price = eachProduct ["ProductPrice"] as! Double

                    self.fetchedProduct.append(Product(title: title, price: price))
                }

                print(self.fetchedProduct)
                print(self.fetchedProduct.count)
            } catch {
              print("Error 2")
            }
        }
    }
    task.resume()     
}

class Product {

    var title: String
    var price: Double

    init(title: String, price: Double) {
        self.title = title
        self.price = price
    }
}

从 API 中,我得到以下 JSON 响应。(它是希腊语,还有更多属性,我只是写了其中的一些)

[  
   {

   "ProductTitle":"\u03a0\u03c1\u03b1\u03bb\u03af\u03bd\u03b1 OREO",

   "ProductSummary":"\u03bc\u03c0\u03b9\u03c3\u03ba\u03bf\u03c4\u03bf",

   "ProductPrice":"1.50",

   "ProductPriceGross":"1.86",

   "ProductPriceWithDiscount":"0.00", 

   "ProductImage":"koulouri_tyri_gemisto_philadelphia_galopoula_ntomata[1].jpg",

   },
...
]

但我只想获取 ProductPriceProductTitle

Swift 告诉我:无法将类型“NSTaggedPointerString”(0x1098a1b90)的值转换为“NSNumber”(0x108eaa320)

而且,当我尝试仅使用 String 的 ProductTitle 时,会告诉我: 致命错误:在展开可选值时意外发现 nil

我做错了什么?

【问题讨论】:

  • JSON 中的 ProductPrice 值是一个字符串,而不是双精度值,这就是异常告诉你的;您不能强制将字符串向下转换为双精度。你需要通过Double初始化器let price = Double(eachProduct ["ProductPrice"])进行转换
  • @Paulw11,您应该发布您的评论作为答案,以便 OP 可以接受它。我正要说同样的话,但你打败了我。 :)

标签: json swift


【解决方案1】:

你的 JSON 中的 ProductPrice 值是一个字符串,而不是一个双精度数,这就是异常告诉你的;您不能强制将字符串向下转换为双精度。

你需要通过 Double 初始化器来转换它

根据您发布的信息,您在访问ProductTitle 时不应出现异常,但最好避免强制展开/向下转换。仔细检查键名中的输入错误。

一种“更安全”的方法(也可以避免 NSArray,这是 Swift 中的最佳做法):

if let fetchedData = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as? [[String:Any]] {

    for eachProduct in fetchedData {

       if let title = eachProduct ["ProductTitle"] as? String,
          let price = eachProduct ["ProductPrice"] as? String,
          let doublePrice = Double(price) {
              self.fetchedProduct.append(Product(title: title, price: doublePrice))

       }
    }
}

【讨论】:

  • 一旦复合 if let 语句成功,price 就是一个双精度数。不需要额外的let doublePrice = Double(price) ?? 0。那个演员是多余的。现在,在分配值为 0 的 if let 上放置一个 else 可能是合理的......
  • 谢谢你;我不小心从问题中复制了as? Double。它应该是as? String,因为 JSON 包含一个字符串。 Double(string) 初始化器确实返回一个可选
  • 实际上,如果代码没有必填字段,最好跳过创建产品
  • 好点。 as? Double 会在字符串上失败。我以为那是演员阵容,但事实并非如此。
  • 是的..它有效!我唯一添加的是 fetchedData 中的 eachFetchedProduct { let eachProduct = eachFetchedProduct
猜你喜欢
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 2017-10-30
相关资源
最近更新 更多