问题1:
我正在使用YouTube API在UITableView
中显示视频播放列表,但它不起作用。当我进行单个视频时,它可以正常工作,一个视频出现在UITableView
中。
如何显示任何YouTube频道的播放列表?我在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: unexpectedly found nil while unwrapping an Optional value
和视频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)
提出请求,用实际的URL替换yourURL
。
对于第二个问题,您在这里有一个很棒的教程:http://www.appcoda.com/youtube-apioios-tutorial/
在教程中是通过YouTube视频更新UitableView的另一种方法,但是我个人更喜欢Alamofire One,因为它更快,更易于编写。我建议仅查看播放视频部分。