加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift 4 JSONSerialization.jsonObject

发布时间:2020-12-14 04:29:26 所属栏目:百科 来源:网络整理
导读:我正在使用 Xcode 9.2和 Swift 4.如何检查返回的json数据是否为空? 现在它给了我错误如果json [0] [“data”]类型’Any’在行没有下标成员 var json: NSMutableArray = []var newsArray: NSMutableArray = []let url = URLFactory()var data = try! NSData(
我正在使用 Xcode 9.2和 Swift 4.如何检查返回的json数据是否为空?
现在它给了我错误如果json [0] [“data”]类型’Any’在行没有下标成员

var json: NSMutableArray = []
var newsArray: NSMutableArray = []

let url = URLFactory()
var data = try! NSData(contentsOf: url.getURL()) as Data
do {
    json = try JSONSerialization.jsonObject(with: data,options: []) as! NSMutableArray
    if json[0]["data"] {
        // data is not null
    }
} catch let error as NSError {
    // handle error
}

我的JSON返回如下内容:

{
   "data":
   [
      {
         "news_id":123,"title":"title","news_date":"2017-02-08 21:46:06","news_url":"url","short_description":"description","category_id":4,"category_name":"Health","latlng":
         [
            {
               "lat":"43.003429","lng":"-78.696335"
            }
         ]
      }
      { ....
}

解决方法

如果您使用的是Swift 4,我可能会建议使用JSONDecoder:

首先,定义保存解析数据的类型:

struct ResponSEObject: Codable {
    let data: [NewsItem]
}

struct NewsItem: Codable {
    let newsId: Int
    let title: String
    let newsDate: Date
    let newsURL: URL
    let shortDescription: String
    let categoryID: Int
    let categoryName: String
    let coordinates: [Coordinate]

    // because your json keys don't follow normal Swift naming convention,use CodingKeys to map these property names to JSON keys

    enum CodingKeys: String,CodingKey {
        case newsId = "news_id"
        case title
        case newsDate = "news_date"
        case newsURL = "news_url"
        case shortDescription = "short_description"
        case categoryID = "category_id"
        case categoryName = "category_name"
        case coordinates = "latlng"
    }
}

struct Coordinate: Codable {
    let lat: String
    let lng: String
}

然后你可以解析它:

let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
do {
    let responSEObject = try decoder.decode(ResponSEObject.self,from: data)
    print(responSEObject.data)
} catch {
    print(error)
}

显然,如果你的JSON不同,你可能需要相应地改变你的对象(例如,奇怪的是latlng是一个坐标数组).此外,如果要将这些字符串中的一些转换为数字,则可以定义自定义init(from :)方法,但我宁愿修复JSON(为什么latlng返回字符串值而不是数值).

有关更多信息,请参阅Encoding and Decoding Custom Types.

顺便说一句,我建议不要使用这种模式(注意,这是你的网络请求逻辑,但切除了NSData):

let data = try! Data(contentsOf: url.getURL())

这将同步检索数据,这可能会有问题,因为

>在检索数据时,应用程序将被冻结,导致用户体验不佳;
>您可能会面临查看冻结应用程序的监视程序进程杀死您的应用程序的风险;和
>您没有强大的错误处理,如果网络请求失败,这将会崩溃.

我建议使用URLSession:

let task = URLSession.shared.dataTask(with: url.getURL()) { data,_,error in
    guard let data = data,error == nil else {
        print(error ?? "Unknown error")
        return
    }

    // now parse `data` like shown above

    // if you then need to update UI or model objects,dispatch that back
    // to the main queue:

    DispatchQueue.main.async {
        // use `responSEObject.data` to update model objects and/or UI here
    }
}
task.resume()

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读