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 绝对是可选的。