YoutubeKit is an iOS library for the YouTube IFrame Player and YouTube Data API.
YoutubeKit is created based on the following references. If you are unsure whether it is a normal behavior or a bug, please check the following documents first.
The Example project demonstrates video playback and Data API requests.
| Example1 | Example2 |
|---|---|
![]() |
![]() |
| Example3 | Example4 |
![]() |
![]() |
YTSwiftyPlayer is a video player that supports Youtube IFrame API.
Features:
- A WKWebView-based IFrame player
- Typed player parameters (
VideoEmbedParameter)
This library supports YoutubeDataAPI (v3). For the details is Here.
Available API lists:
- Activity(list)
- Caption(list)
- Channel(list)
- ChannelSections(list)
- Comment(list)
- CommentThreads(list)
- PlaylistItems(list)
- Playlists(list)
- Search(list)
- Subscriptions(list)
- VideoAbuseReportReasons(list)
- VideoCategories(list)
- Videos(list)
import UIKit
import YoutubeKit
final class VideoPlayerController: UIViewController {
private var player: YTSwiftyPlayer!
override func viewDidLoad() {
super.viewDidLoad()
// Create a new player
player = YTSwiftyPlayer(
frame: .zero,
playerVars: [
.playsInline(false),
.videoID("_6u6UrtXUEI"),
.loopVideo(true),
.showRelatedVideo(false),
.autoplay(true)
])
view = player
player.delegate = self
// Load video player
player.loadDefaultPlayer()
}
}
// Use the default implementations of the optional delegate callbacks.
extension VideoPlayerController: YTSwiftyPlayerDelegate {}YTSwiftyPlayerDelegate provides default implementations of these callbacks:
func playerReady(_ player: YTSwiftyPlayer)
func player(_ player: YTSwiftyPlayer, didUpdateCurrentTime currentTime: Double)
func player(_ player: YTSwiftyPlayer, didChangeState state: YTSwiftyPlayerState)
func player(_ player: YTSwiftyPlayer, didChangePlaybackRate playbackRate: Double)
func player(_ player: YTSwiftyPlayer, didReceiveError error: YTSwiftyPlayerError)
func player(_ player: YTSwiftyPlayer, didReceiveErrorCode code: Int)
func autoplayBlocked(_ player: YTSwiftyPlayer)
func player(_ player: YTSwiftyPlayer, didChangeQuality quality: YTSwiftyVideoQuality)
func apiDidChange(_ player: YTSwiftyPlayer)
func youtubeIframeAPIReady(_ player: YTSwiftyPlayer)
func youtubeIframeAPIFailedToLoad(_ player: YTSwiftyPlayer)loadDefaultPlayer() and loadPlayerHTML without an explicit URL derive
https://<bundle-id> from the host app's bundle ID for the YouTube Referer.
Custom hosts can supply loadDefaultPlayer(baseURLString:) or the existing baseURLString: argument.
Without a valid bundle ID, the legacy URL is used; supply an explicit app identity URL in that case.
Const.basePlayerURLString and explicit base URLs remain supported.
player(_:didReceiveErrorCode:) reports all error codes, including 153 (missing client identity).
The existing typed didReceiveError callback still runs first for known codes.
autoplayBlocked(_:) reports blocked autoplay; allow the user to start playback with a tap.
Both new callbacks have default implementations, so existing delegates need no changes.
Custom HTML templates should also forward onAutoplayBlocked, as the bundled template does.
The Example logs raw error codes and blocked autoplay for troubleshooting.
See YouTube's client identity requirements.
// Pause the video.
player.pauseVideo()
// Seek to a whole or fractional second.
player.seek(to: 15, allowSeekAhead: true)
player.seek(to: 15.5, allowSeekAhead: true)
// Set a mute.
player.mute()
// Load another video.
player.loadVideo(videoID: "M7lc1UVf-VE")Int values and method references remain supported; NaN and infinity are ignored. The bundled HTML uses the device viewport width. See GitHub Issues for current bugs and requests.
First, Get API key from Here.
Next, add this code in your AppDelegate.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Set your API key here
YoutubeKit.shared.setAPIKey("Your API key")
return true
}For iOS-restricted API keys, requests automatically include the host app's bundle ID. See API key restrictions for setup and custom headers.
And then you can use YoutubeDataAPI request like this.
// Get youtube chart ranking
let request = VideoListRequest(part: [.id, .statistics], filter: .chart)
// Send a request.
YoutubeAPI.shared.send(request) { result in
switch result {
case .success(let response):
print(response)
case .failure(let error):
print(error)
}
}var nextPageToken: String?
...
// Send some request
YoutubeAPI.shared.send(request) { [weak self] result in
switch result {
case .success(let response):
// Save nextPageToken
self?.nextPageToken = response.nextPageToken
case .failure(let error):
print(error)
}
}
...
// Set nextPageToken
let request = VideoListRequest(part: [.id], filter: .chart, nextPageToken: nextPageToken)If you want authorized request such as a getting your activity in Youtube, you set your access token before sending a request.
To use GoogleSignIn, you can easily get your access token.
pod 'GoogleSignIn'
First, add this code in your AppDelegate.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Set your access token for autheticate request
YoutubeKit.shared.setAccessToken("Your access token")
return true
}And then you can use request requiring authorization, this is an example to get your Youtube activity.
// Get your Youtube activity
let request = ActivityListRequest(part: [.snippet], filter: .mine(true))
// Send a request.
YoutubeAPI.shared.send(request) { result in
switch result {
case .success(let video):
print(video)
case .failure(let error):
print(error)
}
}Existing types, enum cases, and arguments are retained with deprecation warnings. Keeping a client API available does not restore a feature removed by YouTube.
| Legacy feature | Current behavior or migration |
|---|---|
ActivityInsertRequest / GuideCategoriesListRequest |
Retired by YouTube; no direct replacement |
Filter.ChannelList.categoryID / Filter.SearchList.relatedToVideoID |
Retired; use supported ID filters or search queries |
VideoListType.search |
Search with the Data API and pass the returned video IDs to the player |
showModestbranding / setPlaybackQuality / availableQualityLevels |
Unsupported or ignored; let YouTube control branding and quality |
suggestedQuality argument |
Retained for source compatibility; ignored by YouTube |
showRelatedVideo(false) |
Limits related videos to the same channel; does not hide them |
Sources: Data API revision history, IFrame revision history, player parameters.
iOS 13 or later. SwiftPM tools version is 5.3; the default Swift language mode is 5.
Using a Swift 6 compiler does not require switching the application's language mode to Swift 6.
The networking API retains completion handlers and arbitrary Decodable response types.
Use the .main callback queue for UI updates and synchronize mutable references shared by your app.
ResponseError.unexpectedResponse(Any) is retained; arbitrary payloads are not guaranteed thread-safe.
The Example uses the iOS 13 scene lifecycle.
Run python3 Scripts/run-tests.py for package regression tests and hosted Example tests.
It selects the latest installed iPhone Simulator; no API key is needed for automated tests.
Use --language-mode 6 to test Swift 6 and --deployment-target 15.0 when required by the SDK.
This override only affects validation builds; package and CocoaPods deployment targets remain iOS 13.
CI runs on Xcode 26 and 27. See release preparation for live playback checks and publishing.
Add the following to your Package.swift file:
dependencies: [
.package(url: "https://github.com/rinov/YoutubeKit.git", from: "0.14.0")
]CocoaPods distribution is deprecated; migrate to SwiftPM. The latest version on CocoaPods trunk is 0.9.0, and newer versions are not published there. CocoaPods trunk becomes read-only on December 2, 2026. Until migrating, existing integrations can reference a release tag directly:
pod 'YoutubeKit', :git => 'https://github.com/rinov/YoutubeKit.git', :tag => '0.14.0'Upgrading from 0.9.0 requires iOS 13 (0.9.0 supported iOS 11). Applications that still support iOS 11 or 12 must remain on a compatible older version.
The current repository has no shared framework target; use SwiftPM for new integrations. Existing users should pin their validated version and verify resource loading before migrating.
rinov · Twitter · rinov[at]rinov.jp
YoutubeKit is available under the MIT license.



