在swift中正确解析JSON

时间:2017-07-01 15:44:24

标签: json xcode swift3

这是我要在我的应用程序中解析和使用的JSON

 {
"status": "ok",
"source": "the-next-web",
"sortBy": "latest",
-"articles": [
-{
"author": "Mix",
"title": "Social media giants like Facebook liable to €50M ‘hate speech’ fines in Germany",
"description": "Germany will soon punish social media giants like Facebook, Twitter and YouTube with fines of up to €50 million (approximately $57 million) if they fail to take down illegal or offensive ...",
"url": "https://thenextweb.com/facebook/2017/06/30/facebook-youtube-twitter-germany-50m/",
"urlToImage": "https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2017/03/facebook.jpg",
"publishedAt": "2017-06-30T15:10:58Z"
},
-{
"author": "Abhimanyu Ghoshal",
"title": "Google’s new Android app makes it easy to save mobile data on the go",
"description": "The good folks at Android Police have spotted a new app from Google called Triangle; it lets you control which other apps can use your mobile data. It's a handy little tool if you're ...",
"url": "https://thenextweb.com/apps/2017/06/30/googles-new-android-app-makes-it-easy-to-save-mobile-data-on-the-go/",
"urlToImage": "https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2017/06/Triangle-hed.jpg",
"publishedAt": "2017-06-30T13:16:12Z"
},
-{

这是我解析Json的方法:

typealias GetWeatherSuccess = (_ result: NSDictionary) -> Void
typealias GetWeatherFailure = (_ error: Error?) -> Void

func requestNewsForToday() -> URLRequest {
        let urlText = NewsManager.shared.weatherRequest()
        return URLRequest(url: URL(string: urlText)! as URL)
    }

    func getNews(successHandler: GetWeatherSuccess?,
                    failureHandler: GetWeatherFailure?) {

        let session = URLSession.shared
        let dataTask = session.dataTask(with: requestNewsForToday()) { data, _, error in
            if error == nil {
                if let dic = try? JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
                    successHandler?(dic!)
                }
            } else {
                failureHandler?(error)
            }
        }
        dataTask.resume()
    }

使用方法:

NetworkManager.shared.getNews(successHandler: { (json: NSDictionary) in

        let articles = json.object(forKey: "articles") as! NSArray
        print(articles[0])
    }) { (_:Error?) in
        print("error")
    }
}

结果是遗忘:

{
    author = "Romain Dillet";
    description = "\U201cWe called this building Station F, like Station France, Station Femmes [ed. note: women in French], Station Founders or Station Freyssinet because..";
    publishedAt = "2017-07-01T09:47:38Z";
    title = "A walk around Station F with Emmanuel\U00a0Macron";
    url = "https://techcrunch.com/2017/07/01/a-walk-around-station-f-with-emmanuel-macron/";
    urlToImage = "https://tctechcrunch2011.files.wordpress.com/2017/06/station-f-emmanuel-macron-9.jpg?w=764&h=400&crop=1";
}

如何以作者字符串为例? 或者从json中获取完整的数据并使用它?

1 个答案:

答案 0 :(得分:0)

我将使用Swift 4 Decodable协议以简单易用的方式解析JSON!它真的是Apple在此更新中提供的非常强大的工具!

通过查看JSON,我可以推断出我需要两个符合Decodable协议的结构: -

    struct jsonData: Decodable {
      let status: String
      let source: String
      let sortBy: String
      let articles: [Articles]
    }

    struct Articles: Decodable {
     let author: String
     let title: String
     let description: String
     let url: String
     let urlToImage: String
     let publishedAt: String
}

注意我已经将变量命名为与JSON中的键完全相同。这就是可解码协议魔法发生的地方。它会根据您的变量名称自动推断哪个键值/对属于哪个变量(意味着您在JSON中的键名,应该是swift中的变量名),前提是您正确命名它们,否则会引发错误。 / p>

现在,像往常一样建立网络连接: -

URLSession.shared.dataTask(with: url) {(data, response, error) in

    guard let data = data else { return }

    do {

    let item = try JSONDecoder().decode(jsonData.self, from: data)
    print(item.status) // prints "ok"
    print(items.articles) // prints the 2 arrays in the json, provided in your Question 

    }
    catch let jsonErr {
       print("serialisation error", jsonErr)
    }
}