首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用YouTube JSONSerialization解析json

用YouTube JSONSerialization解析json
EN

Stack Overflow用户
提问于 2019-10-23 07:22:39
回答 1查看 101关注 0票数 0

我很难用YouTube api解析来自JSONSerialization的json数据。当我试图获取时,我返回错误。这是我的密码

这是我想解析的json数据,我想获得视频id、url、title和data。

代码语言:javascript
运行
复制
{
 "kind": "youtube#searchListResponse",
 "etag": "\"j6xRRd8dTPVVptg711_CSPADRfg/mBDPbwkuU2lLUxWHYPI1X54CUwQ\"",
 "nextPageToken": "CAUQAA",
 "regionCode": "ID",
 "pageInfo": {
  "totalResults": 3552,
  "resultsPerPage": 5
 },
 "items": [
  {
   "kind": "youtube#searchResult",
   "etag": "\"j6xRRd8dTPVVptg711_CSPADRfg/73cXngXOrGm_Bt7McNY945A6koc\"",
   "id": {
    "kind": "youtube#video",
    "videoId": "-0ZZzOuuV3c"
   },
   "snippet": {
    "publishedAt": "2018-09-20T08:00:01.000Z",
    "channelId": "UCjHoMXZXAIx_QHgk9qsAJ-Q",
    "title": "HADIST-HADIST PALSU TAPI POPULER - Ustadz Adi Hidayat LC MA",
    "description": "\"Kebersihan sebagian dari iman\". Sering dogn mendengar ucapan ini. Sebagian orang mengatakan ini hadist dari Rasulullah. Tapi taukah kamu, bahwa ini ...",
    "thumbnails": {
     "default": {
      "url": "https://i.ytimg.com/vi/-0ZZzOuuV3c/default.jpg",
      "width": 120,
      "height": 90
     },
     "medium": {
      "url": "https://i.ytimg.com/vi/-0ZZzOuuV3c/mqdefault.jpg",
      "width": 320,
      "height": 180
     },
     "high": {
      "url": "https://i.ytimg.com/vi/-0ZZzOuuV3c/hqdefault.jpg",
      "width": 480,
      "height": 360
     }
    },
    "channelTitle": "Audio Dakwah",
    "liveBroadcastContent": "none"
   }
  }

这是我解析json的代码,我在youtubeAPI结构中创建它,当我尝试运行它时,invalidJSONData

代码语言:javascript
运行
复制
static func videos(fromJSON data: Data) -> VideoResults {
        do {
            let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])

            guard
                let jsonDictionary = jsonObject as? [AnyHashable: Any],
                let itemsArray = jsonDictionary["items"] as? [[String: Any]]
                else {
                    return .failure(YoutubeError.invalidJSONData)
                }

            var finalItems = [Video]()

            for itemJSON in itemsArray {
                if let item = video(fromJSON: itemJSON) {
                    finalItems.append(item)
                }
            }

            if finalItems.isEmpty && !itemsArray.isEmpty {
                return .failure(YoutubeError.invalidJSONData)
            }

            return .success(finalItems)

        } catch let error {
            return .failure(error)
        }
    }

    private static func video(fromJSON json: [String: Any]) ->Video? {
        guard
            let videoID = json["videoID"] as? String,
            let title = json["title"] as? String,
            let description = json["description"] as? String,
            let stringURL = json["url"] as? String,
            let url = URL(string: stringURL)
            else {
                return nil
        }
        return Video(videoID: videoID, title: title, description: description, url: url)
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-24 03:50:50

我有个问题要问。我终于找到了我的问题的答案。希望这将帮助希望使用JSONSerialization解析json的其他开发人员,使用像YouTube api或其他api这样的复杂数据。所以这就是我的答案。

因为item是一个数组,并且内部有另一个嵌套的数据,比如代码段,所以我需要迭代代码段来获取数据。这是密码。

代码语言:javascript
运行
复制
do {
            let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]

            var finalItems = [Video]()

            if let items = jsonObject?["items"] as? Array<Dictionary<String, Any>> {
                for item in items {
                    if
                        let id = item["id"] as? [String: String],
                        let snippet = item["snippet"] as? [String: Any] {
                        if
                            let videoID = id["videoId"],

                            let description = snippet["description"] as? String,
                            let title = snippet["title"] as? String,
                            let thumbnails = snippet["thumbnails"] as? [String: Any],
                            let medium = thumbnails["medium"] as? [String: Any],
                            let urlString = medium["url"] as? String,
                            let url = URL(string: urlString) {

                            finalItems.append(Video(videoID: videoID, title: title, description: description, url: url))
                        }
                    }
                }
            }
            print(finalItems.count)

            if finalItems.isEmpty {
                return .failure(YoutubeError.invalidJSONData)
            }

            return .success(finalItems)
        } catch let error {
            return .failure(error)
        }

下一步是清理迭代该项目的解析代码,并将其放入视频模型中,我从苹果开发者网站上找到了一篇很好的文章来清理代码,这样代码就不会在我的视频功能中膨胀。如果您很好奇,请查看这个链接https://developer.apple.com/swift/blog/?id=37。视频模型的扩展是这样的。

代码语言:javascript
运行
复制
extension Video {
    init(dict: [String: Any]) throws {
        guard
            let id = dict["id"] as? [String: String],
            let videoID = id["videoId"]
            else {
                throw SerializationError.missing("id")
        }

        guard
            let snippet = dict["snippet"] as? [String: Any],
            let description = snippet["description"] as? String,
            let title = snippet["title"] as? String,
            let thumbnails = snippet["thumbnails"] as? [String: Any],
            let medium = thumbnails["medium"] as? [String: Any],
            let urlString = medium["url"] as? String,
            let url = URL(string: urlString) else { throw SerializationError.missing("snippet") }

        self.videoID = videoID
        self.title = title
        self.description = description
        self.url = url
    }
}

然后更新视频函数,并在尝试追加时添加do catch块,因为扩展在解析json数据时有潜在的错误。这是更新方法。

代码语言:javascript
运行
复制
static func videos(fromJSON data: Data) -> VideoResults {
        do {
            let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]

            var finalItems = [Video]()

            if let items = jsonObject?["items"] as? Array<Dictionary<String, Any>> {
                for item in items {
                    do {
                        try finalItems.append(Video(dict: item))
                    } catch let error {
                        print("Failed to append video: \(error)")
                    }
                }
            }
            print(finalItems.count)

            if finalItems.isEmpty {
                return .failure(YoutubeError.invalidJSONData)
            }

            return .success(finalItems)
        } catch let error {
            return .failure(error)
        }
    }

现在代码是安全的,为什么我不使用JSONDecoder呢?因为很多人推荐使用JSONDecoder。原因是,这是我个人的理由,顺便说一句,其他人可能不同意我的观点。我知道如何使用JSONDecoder,但问题是我不想创建太多的结构来解码json数据,因为使用这个JSONSerialization不需要创建struct,它可以帮助我减少一个文件并加快我的学习速度。而且,即使是像Alamofire这样的库也可以选择使用JSONSerialization进行解析。现在由您决定,如果您想使用JSONDecoder或JSONSerialization,我希望这个帮助:)。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58517526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档