我很难用YouTube api解析来自JSONSerialization的json数据。当我试图获取时,我返回错误。这是我的密码
这是我想解析的json数据,我想获得视频id、url、title和data。
{
"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
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)
}
发布于 2019-10-24 03:50:50
我有个问题要问。我终于找到了我的问题的答案。希望这将帮助希望使用JSONSerialization解析json的其他开发人员,使用像YouTube api或其他api这样的复杂数据。所以这就是我的答案。
因为item是一个数组,并且内部有另一个嵌套的数据,比如代码段,所以我需要迭代代码段来获取数据。这是密码。
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。视频模型的扩展是这样的。
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数据时有潜在的错误。这是更新方法。
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,我希望这个帮助:)。
https://stackoverflow.com/questions/58517526
复制相似问题