Building Netflix App in Swift 5 and UIKit - Episode 11 - YouTube API
Building Netflix App in Swift 5 and UIKit - Episode 12 - TitlePreviewController
func getVideoMetaData(with query: String) -> AnyPublisher<MetaIdModel, Error> {
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "www.googleapis.com"
urlComponents.path = "/youtube/v3/search"
urlComponents.queryItems = [
URLQueryItem(name: "q", value: query),
URLQueryItem(name: "type", value: "video"),
URLQueryItem(name: "key", value: Constants.Youtube_API_KEY.rawValue)
]
guard let url = urlComponents.url else { return Fail(error: URLError(.badURL)).eraseToAnyPublisher()}
return URLSession
.shared
.dataTaskPublisher(for: url)
.tryMap { data, response in
guard let response = response as? HTTPURLResponse,
response.statusCode == 200 else {
print("response error")
throw URLError(.badServerResponse)
}
return data
}
.decode(type: MetaDataContentResponse.self, decoder: JSONDecoder())
.map({ $0.items[0].id})
.eraseToAnyPublisher()
}
import Foundation
struct MetaIdModel: Codable {
let kind: String
let videoId: String
}
func getHeaderVideoId() -> AnyPublisher<MetaIdModel, Error> {
guard let model = headerModel else {
return Fail(error: URLError(.badURL)).eraseToAnyPublisher()
}
var title: String?
if model.title != nil {
title = model.title
} else if model.original_title != nil {
title = model.original_title
}
guard let title = title else {
return Fail(error: URLError(.badURL)).eraseToAnyPublisher()
}
return APICaller
.shared
.getVideoMetaData(with: title + " trailer")
.eraseToAnyPublisher()
}
private func bind() {
playButton
.tapPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
if let id = self?.videoId {
print("id: \(id)")
let playerVars = [
"playsinline" : 1,
"showinfo" : 0,
"rel" : 0,
"modestbranding" : 1,
"controls" : 1
]
self?.playVideo()
self?.playerView.load(withVideoId: id, playerVars: playerVars)
}
}
.store(in: &cancellabels)
}
private func playVideo() {
imageView.isHidden = true
playerView.isHidden = false
}
func stopVideo() {
if !playerView.isHidden {
playerView.stopVideo()
imageView.isHidden = false
playerView.isHidden = true
}
}
isHidden
을 통해 일종의 토글링 실행extension HomeHeaderView: YTPlayerViewDelegate {
func playerViewDidBecomeReady(_ playerView: YTPlayerView) {
print("Player view did Become ready")
playerView.playVideo()
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if let tableHeaderView = tableView.tableHeaderView as? HomeHeaderView {
let defaultY = tableHeaderView.frame.size.height
let contentOffset = scrollView.contentOffset.y
if defaultY <= contentOffset {
tableHeaderView.stopVideo()
}
}
}
prepareForReuse
를 오버라이드해 해당 셀이 재사용될 경우를 감지넷플릭스 어플의 특징은 스크롤 감지를 통한 동영상 자동 재생/멈춤이라 생각하기 때문에 강의에서 구현한 바에 추가해 이상을 구현했다.