Swift 3 解析 youtube 视频不显示结果并不断加载 - IOS 10
Swift 3 parsing youtube videos doesn't show results and keeps loading - IOS 10
我正在尝试通过 json 解析来获取 youtube 频道和视频,我是新手 Swift 3. 但是,加载图标没有消失,也没有结果显示,日志中没有错误。
这是我的代码:
1/ func getVideosForChannelAtIndex :
func getVideosForChannelAtIndex(_ index: Int!) {
let playlistID = channelsDataArray[index]["playlistID"] as! String
let urlString = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=\(playlistID)&key=\(apiKey)"
let targetURL = URL(string: urlString)
var url = URLRequest(url: targetURL!)
url.httpMethod = "GET"
URLSession.shared.dataTask(with: url) { (data, response, error) in
let httpStatus = response as? HTTPURLResponse
if httpStatus!.statusCode == 200 && error != nil {
do {
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject>
let items: Array<Dictionary<String, AnyObject>> = resultsDict["items"] as! Array<Dictionary<String, AnyObject>>
for i in 0 ..< items.count {
let playlistSnippetDict = (items[i] as Dictionary<String, AnyObject>)["snippet"] as! Dictionary<String, AnyObject>
var desiredPlaylistItemDataDict = Dictionary<String, AnyObject>()
desiredPlaylistItemDataDict["title"] = playlistSnippetDict["title"]
desiredPlaylistItemDataDict["thumbnail"] = ((playlistSnippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
desiredPlaylistItemDataDict["videoID"] = (playlistSnippetDict["resourceId"] as! Dictionary<String, AnyObject>)["videoId"]
self.videosArray.append(desiredPlaylistItemDataDict)
self.tableView.reloadData()
}
} catch {
print(error)
}
}
else {
print("Error while loading channel videos: \(error)")
}
self.activityView.isHidden = true
}
}
2/ func getChannelDetails :
func getChannelDetails(_ useChannelIDParam: Bool) {
var urlString: String!
if !useChannelIDParam {
urlString = "https://www.googleapis.com/youtube/v3/channels?part=contentDetails,snippet&forUsername=\(desiredChannelsArray[channelIndex])&key=\(apiKey)"
}
else {
urlString = "https://www.googleapis.com/youtube/v3/channels?part=contentDetails,snippet&id=\(desiredChannelsArray[channelIndex])&key=\(apiKey)"
}
let targetURL = URL(string: urlString)
var request = URLRequest(url: targetURL!)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { (data, response, error) in
let httpStatus = response as? HTTPURLResponse
if httpStatus!.statusCode == 200 && error != nil {
do {
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject>
let items: AnyObject! = resultsDict["items"] as AnyObject!
let firstItemDict = (items as! Array<AnyObject>)[0] as! Dictionary<String, AnyObject>
let snippetDict = firstItemDict["snippet"] as! Dictionary<String, AnyObject>
var desiredValuesDict: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
desiredValuesDict["title"] = snippetDict["title"]
desiredValuesDict["description"] = snippetDict["description"]
desiredValuesDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
desiredValuesDict["playlistID"] = ((firstItemDict["contentDetails"] as! Dictionary<String, AnyObject>)["relatedPlaylists"] as! Dictionary<String, AnyObject>)["uploads"]
self.channelsDataArray.append(desiredValuesDict)
self.tableView.reloadData()
self.channelIndex += 1
if self.channelIndex < self.desiredChannelsArray.count {
self.getChannelDetails(useChannelIDParam)
}
else {
self.activityView.isHidden = true
}
} catch {
print(error)
}
} else {
print("Error while loading channel details: \(error)")
}
}
}
}
3/ func textFieldShouldReturn:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
activityView.isHidden = false
var type = "channel"
if segmentDisplay.selectedSegmentIndex == 1 {
type = "video"
videosArray.removeAll(keepingCapacity: false)
}
var urlString = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=\(textField.text)&type=\(type)&key=\(apiKey)"
urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
let targetURL = URL(string: urlString)
var request = URLRequest(url: targetURL!)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { (data, response, error) in
let httpStatus = response as? HTTPURLResponse
if httpStatus!.statusCode == 200 && error != nil {
do {
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject>
let items: Array<Dictionary<String, AnyObject>> = resultsDict["items"] as! Array<Dictionary<String, AnyObject>>
for i in 0 ..< items.count {
let snippetDict = items[i]["snippet"] as! Dictionary<String, AnyObject>
if self.segmentDisplay.selectedSegmentIndex == 0 {
self.desiredChannelsArray.append(snippetDict["channelId"] as! String)
}
else {
var videoDetailsDict = Dictionary<String, AnyObject>()
videoDetailsDict["title"] = snippetDict["title"]
videoDetailsDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
videoDetailsDict["videoID"] = (items[i]["id"] as! Dictionary<String, AnyObject>)["videoId"]
self.videosArray.append(videoDetailsDict)
self.tableView.reloadData()
}
}
} catch {
print(error)
}
if self.segmentDisplay.selectedSegmentIndex == 0 {
self.getChannelDetails(true)
}
}
else {
print("Error while loading channel videos: \(error)")
}
self.activityView.isHidden = true
}
return true
}
如评论中所述,您必须在每个任务上调用 resume()
,因为默认情况下 URLSession
的所有任务都已挂起。
这样使用你的单线:
URLSession.shared.dataTask(with: request) { (data, response, error) in
...
}.resume()
或者
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
...
}
task.resume()
顺便说一句,根本不需要 URLRequest
实例。 GET
是默认的 HTTP 方法。
注意:确保使用字符串插值嵌入 URL 中的所有可选值都已展开,否则您将得到文字 Optional("Foo")
字符串。例如第三个代码片段中的 textField.text
绝对是可选的。
我正在尝试通过 json 解析来获取 youtube 频道和视频,我是新手 Swift 3. 但是,加载图标没有消失,也没有结果显示,日志中没有错误。
这是我的代码:
1/ func getVideosForChannelAtIndex :
func getVideosForChannelAtIndex(_ index: Int!) {
let playlistID = channelsDataArray[index]["playlistID"] as! String
let urlString = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=\(playlistID)&key=\(apiKey)"
let targetURL = URL(string: urlString)
var url = URLRequest(url: targetURL!)
url.httpMethod = "GET"
URLSession.shared.dataTask(with: url) { (data, response, error) in
let httpStatus = response as? HTTPURLResponse
if httpStatus!.statusCode == 200 && error != nil {
do {
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject>
let items: Array<Dictionary<String, AnyObject>> = resultsDict["items"] as! Array<Dictionary<String, AnyObject>>
for i in 0 ..< items.count {
let playlistSnippetDict = (items[i] as Dictionary<String, AnyObject>)["snippet"] as! Dictionary<String, AnyObject>
var desiredPlaylistItemDataDict = Dictionary<String, AnyObject>()
desiredPlaylistItemDataDict["title"] = playlistSnippetDict["title"]
desiredPlaylistItemDataDict["thumbnail"] = ((playlistSnippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
desiredPlaylistItemDataDict["videoID"] = (playlistSnippetDict["resourceId"] as! Dictionary<String, AnyObject>)["videoId"]
self.videosArray.append(desiredPlaylistItemDataDict)
self.tableView.reloadData()
}
} catch {
print(error)
}
}
else {
print("Error while loading channel videos: \(error)")
}
self.activityView.isHidden = true
}
}
2/ func getChannelDetails :
func getChannelDetails(_ useChannelIDParam: Bool) {
var urlString: String!
if !useChannelIDParam {
urlString = "https://www.googleapis.com/youtube/v3/channels?part=contentDetails,snippet&forUsername=\(desiredChannelsArray[channelIndex])&key=\(apiKey)"
}
else {
urlString = "https://www.googleapis.com/youtube/v3/channels?part=contentDetails,snippet&id=\(desiredChannelsArray[channelIndex])&key=\(apiKey)"
}
let targetURL = URL(string: urlString)
var request = URLRequest(url: targetURL!)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { (data, response, error) in
let httpStatus = response as? HTTPURLResponse
if httpStatus!.statusCode == 200 && error != nil {
do {
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject>
let items: AnyObject! = resultsDict["items"] as AnyObject!
let firstItemDict = (items as! Array<AnyObject>)[0] as! Dictionary<String, AnyObject>
let snippetDict = firstItemDict["snippet"] as! Dictionary<String, AnyObject>
var desiredValuesDict: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
desiredValuesDict["title"] = snippetDict["title"]
desiredValuesDict["description"] = snippetDict["description"]
desiredValuesDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
desiredValuesDict["playlistID"] = ((firstItemDict["contentDetails"] as! Dictionary<String, AnyObject>)["relatedPlaylists"] as! Dictionary<String, AnyObject>)["uploads"]
self.channelsDataArray.append(desiredValuesDict)
self.tableView.reloadData()
self.channelIndex += 1
if self.channelIndex < self.desiredChannelsArray.count {
self.getChannelDetails(useChannelIDParam)
}
else {
self.activityView.isHidden = true
}
} catch {
print(error)
}
} else {
print("Error while loading channel details: \(error)")
}
}
}
}
3/ func textFieldShouldReturn:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
activityView.isHidden = false
var type = "channel"
if segmentDisplay.selectedSegmentIndex == 1 {
type = "video"
videosArray.removeAll(keepingCapacity: false)
}
var urlString = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=\(textField.text)&type=\(type)&key=\(apiKey)"
urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
let targetURL = URL(string: urlString)
var request = URLRequest(url: targetURL!)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request) { (data, response, error) in
let httpStatus = response as? HTTPURLResponse
if httpStatus!.statusCode == 200 && error != nil {
do {
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject>
let items: Array<Dictionary<String, AnyObject>> = resultsDict["items"] as! Array<Dictionary<String, AnyObject>>
for i in 0 ..< items.count {
let snippetDict = items[i]["snippet"] as! Dictionary<String, AnyObject>
if self.segmentDisplay.selectedSegmentIndex == 0 {
self.desiredChannelsArray.append(snippetDict["channelId"] as! String)
}
else {
var videoDetailsDict = Dictionary<String, AnyObject>()
videoDetailsDict["title"] = snippetDict["title"]
videoDetailsDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<String, AnyObject>)["default"] as! Dictionary<String, AnyObject>)["url"]
videoDetailsDict["videoID"] = (items[i]["id"] as! Dictionary<String, AnyObject>)["videoId"]
self.videosArray.append(videoDetailsDict)
self.tableView.reloadData()
}
}
} catch {
print(error)
}
if self.segmentDisplay.selectedSegmentIndex == 0 {
self.getChannelDetails(true)
}
}
else {
print("Error while loading channel videos: \(error)")
}
self.activityView.isHidden = true
}
return true
}
如评论中所述,您必须在每个任务上调用 resume()
,因为默认情况下 URLSession
的所有任务都已挂起。
这样使用你的单线:
URLSession.shared.dataTask(with: request) { (data, response, error) in
...
}.resume()
或者
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
...
}
task.resume()
顺便说一句,根本不需要 URLRequest
实例。 GET
是默认的 HTTP 方法。
注意:确保使用字符串插值嵌入 URL 中的所有可选值都已展开,否则您将得到文字 Optional("Foo")
字符串。例如第三个代码片段中的 textField.text
绝对是可选的。