ios - 如何在 Swift3 中使用 YouTube API 显示 YouTube channel 的播放列表

标签 ios swift3 youtube-api ytplayerview

问题 1:

我正在使用 YouTube API 在 UITableView 中显示视频播放列表,但它不起作用。当我制作单个视频时它工作正常,一个视频出现在 UITableView 中。

如何显示任何 YouTube channel 的播放列表?我在我的 UITableView 中使用这段代码。

我的 UITableView 代码:

 import UIKit
 import AVFoundation

 class YTViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, AVAudioPlayerDelegate {

@IBOutlet weak var txtSearch: UITextField!
@IBOutlet weak var searchResultTableView: UITableView!

// Set up a network session
let session = URLSession.shared

// ReST GET static String parts
let BASE_URL: String = "https://www.googleapis.com/youtube/v3/"
let SEARCH_VIDEO: String = "channels?part=snippet&q="
let VIDEO_TYPE: String = "&id=UCJIc9yX_3iHE2CfmUqoeJKQ&key="
let API_KEY: String = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

@IBAction func btnSearchClicked(_ sender: UIButton) {

}

func getVideoList() {

    let methodArguments: [String: AnyObject] = [
        "query": txtSearch.text! as AnyObject
    ]

    // Format the search string (video title) for http request
    let videoTitle: String = escapedParameters(methodArguments)

    // Make the query url
    // sample: https://www.googleapis.com/youtube/v3/search?part=snippet&q=werewolf&type=video&key=AIzaSyDDqTGpVR7jxeozoOEjH6SLaRdw0YY-HPQ

    let searchVideoByTitle = BASE_URL + SEARCH_VIDEO + videoTitle + VIDEO_TYPE + API_KEY

    print("#####################\(searchVideoByTitle)")
    if let url = URL(string: searchVideoByTitle) {
        let request = URLRequest(url: url)
        // Initialise the task for getting the data
        initialiseTaskForGettingData(request, element: "items")
    }
}

// Array to store all the desired values dictionaries
var videosArray: Array<Dictionary<String, AnyObject>> = [[String: AnyObject]]()

func initialiseTaskForGettingData(_ request: URLRequest, element: String) {

    // Initialize task for getting data
    // Refer to http://www.appcoda.com/youtube-api-ios-tutorial/

    let task = session.dataTask(with: request, completionHandler: {(data, HTTPStatusCode, error) in


        // Handler in the case of an error
        if error != nil {
            print(error as Any)
            return
        }
        else {
            // Parse that data received from the service
            let resultDict: [String: AnyObject]!
            do {
                // Convert the JSON data to a dictionary
                resultDict = try JSONSerialization.jsonObject(with: data! as Data, options: .allowFragments) as! [String: AnyObject]

                 print("***************************\(resultDict)")

                // Get the first item from the returned items
                if let itemsArray = (resultDict as AnyObject).value(forKey: element) as? NSArray {

                    // Remove all existing video data
                    self.videosArray.removeAll()

                    for index in 0..<itemsArray.count {

                        // Append the desiredVaules dictionary to the videos array
                        self.videosArray.append(self.unwrapYoutubeJson(arrayToBeUnwrapped: itemsArray, index: index))

                    }

                    // Asynchronously reload the data and display on the tableview
                    DispatchQueue.main.async {
                        // Reload the tableview
                        self.searchResultTableView.reloadData()
                    }
                }

            } catch let jsonError {
                print(jsonError)
            }
        }
    })
    // Execute the task
    task.resume()
}

func unwrapYoutubeJson(arrayToBeUnwrapped: NSArray, index: Int) -> [String: AnyObject]{

    let firstItemDict = arrayToBeUnwrapped[index] as! [String: AnyObject]

    // Get the snippet dictionary that contains the desired data
    let snippetDict = firstItemDict["snippet"] as! [String: AnyObject]

    // Dictionary to store desired video contents for display on tableview
    // desired values - "Title", "Description", "Thumbnail"
    var desiredValuesDict = [String: AnyObject]()

    desiredValuesDict["title"] = snippetDict["title"]
    desiredValuesDict["description"] = snippetDict["description"]

    // Further unwrap to get the Thumbnail default URL
    let thumbnailDict: [String: AnyObject]
    thumbnailDict = snippetDict["thumbnails"] as! [String: AnyObject]
    let defaultThumbnailDict = thumbnailDict["default"] as! [String: AnyObject]

    desiredValuesDict["thumbnail"] = defaultThumbnailDict["url"]

    //Get the id dictionary that contains videoId
    let idDict = firstItemDict["id"] as? [String: AnyObject]
    desiredValuesDict["videoId"] = idDict?["videoId"] 

    return desiredValuesDict
}

// Helper function: Given a dictionary of parameters, convert to a string for a url
func escapedParameters(_ parameters: [String : AnyObject]) -> String {

    var urlVars = [String]()

    for (key, value) in parameters {

        // Make sure that it is a string value
        let stringValue = "\(value)"

        // Escape it
        let escapedValue = stringValue.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)

        //Append it
        urlVars += [key + "=" + "\(escapedValue!)"]
    }

    return (!urlVars.isEmpty ? "" : "") + urlVars.joined(separator: "&")
}

// MARK: UITableView method implementation

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SearchResultTableViewCell

    let videoSelected = videosArray[indexPath.row]
    cell.updateIU(video: videoSelected)

     cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator

    let id = videosArray[indexPath.row]["videoId"] as? String

    print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\(id)")
     return cell
 }

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return videosArray.count
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? playerViewController {
        if let selectedRowIndexPath = searchResultTableView.indexPathForSelectedRow?.row {
            destination.mytitle = videosArray[selectedRowIndexPath]["title"] as! String
            destination.mydescript = videosArray[selectedRowIndexPath]["description"] as! String
            destination.myvideoId = videosArray[selectedRowIndexPath] ["videoId"] as? String
        }
    }
  }

override func viewDidLoad() {
    super.viewDidLoad()

     getVideoList()

    searchResultTableView.dataSource = self
    searchResultTableView.delegate = self
}


}

问题 2:

当我尝试使用 YTPlayerHelper 播放视频时,它不起作用: fatal error :在展开可选值时意外发现 nil,视频 ID 显示为 nil。

如何使用 YTPlayerHelper 播放视频?这就是我播放视频的方式:

import UIKit
import youtube_ios_player_helper

class playerViewController: UIViewController {


@IBOutlet weak var MyPlayer: YTPlayerView!
@IBOutlet weak var txtTitle: UITextView!
@IBOutlet weak var txtDescript: UITextView!

var mytitle: String!
var mydescript: String!
var myvideoId : String!

override func viewDidLoad() {
    super.viewDidLoad()

    print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\(myvideoId)")

    MyPlayer.load(withVideoId: myvideoId!)

    txtTitle.text = mytitle
    txtDescript.text = mydescript

}
}

最佳答案

这是我的 Alamofire 实现;您必须调整名称以匹配您的名称:

func callAlamo(url : String) {
    Alamofire.request(url).responseJSON(completionHandler: {
        response in
        self.parseData(JSONData: response.data!)
    })
}

 func parseData(JSONData : Data) {
    do {
        var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStandard
        pageToken = readableJSON["nextPageToken"] as! String
        if previousPageButton.isEnabled {
            previousPageToken = readableJSON["prevPageToken"] as? String
        }
        if previousPageToken == nil {
            previousPageButton.isEnabled = false
        }
                if let items = readableJSON["items"] as? [JSONStandard] {
                    for i in 0..<items.count  {
                        let item = items[i]
                        var name = String()
                        var previewURL1 = String()
                        if let id = item["id"] as? JSONStandard {
                            let url = id["videoId"] as! String
                            previewURL1 = url
                        }
                        let previewURL = previewURL1
                        if let snippet = item["snippet"] as? JSONStandard {
                            let title = snippet["title"] as! String
                            name = title
                            if let thumbnails = snippet["thumbnails"] as? JSONStandard {
                                if let images = thumbnails["high"] as? JSONStandard {
                                    let mainImageURL = URL(string: images["url"] as! String)
                                    imageURL = images["url"] as! String
                                    let mainImageData = NSData(contentsOf: mainImageURL!)

                                    let mainImage = UIImage(data: mainImageData! as Data)

                                    posts.append(post.init(mainImage: mainImage, name: name, previewURL: previewURL, imageURL: imageURL))
                                    self.tableView.reloadData()
                                    nextPageButton.isEnabled = true
                                }
                            }
                        }
                    }
                }
    } catch {
        print(error)
    }
}

然后使用 callAlamo(url: yourURL) 发出请求,将 yourURL 替换为实际的 URL。

对于第二个问题,这里有一个很棒的教程:http://www.appcoda.com/youtube-api-ios-tutorial/

教程中提供了另一种使用 YouTube 视频更新 UITableView 的方法,但我个人更喜欢 Alamofire 方法,因为它编写起来更快、更容易。我建议只查看播放视频部分。

关于ios - 如何在 Swift3 中使用 YouTube API 显示 YouTube channel 的播放列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42351452/

相关文章:

YouTube:获取订阅者所在国家/地区

youtube - 如何使用API​​代替Google BigQuery数据传输服务?

ios - 了解 Telegram iOS 开源 ASWatcher 和 ASHandle 对象

objective-c - 设置 self.title 更改 tabbaritem 标题,我该如何防止呢?

ios - 有没有办法在团队中共享 Xcode 模板?

ios - 按下按钮时更改按钮 "+"、 "-"、 "/"、 "*"的背景(清晰且相等)。 (IOS)

ios - 单击 UICollectionViewCell 按钮时,Swift 3 将值传递给 Controller

iOS- swift : How to write generic function for this case?

python - 通过 Youtube API v3 将视频上传到多个 channel

ios - 获取 iOS 文件系统目录中存储对象的所有属性