iOS Migration Reference (iOS)
Explore JW Player's new iOS SDK v4.
The following sections provide notes on how to migrate from iOS SDK v3 to iOS SDK 4.x.
Configuration API
In iOS SDK 3.x, the main player configuration object is called JWConfig.
// Create a JWConfig object with a single JWPlaylistItem
let config = JWConfig()
let playlistItem = JWPlaylistItem()
playlistItem.file = fileURL
config.playlist = [playlistItem]
In iOS SDK 4.x, JWConfig is renamed to JWPlayerConfiguration. This configuration object is created using a separate object called JWPlayerConfigurationBuilder. We have made similar modifications to other player configuration objects such as JWPlaylistItem (now JWPlayerItem) and JWAdConfig (now JWAdvertisingConfig).
// Create a JWPlayerConfiguration object with a single JWPlayerItem.
var item: JWPlayerItem!
do {
item = try JWPlayerItemBuilder()
.file(fileURL)
.build()
} catch {
// Do something with the build error
}
do {
let playerConfiguration = JWPlayerConfigurationBuilder()
.playlist([item])
.build()
} catch {
// Do something with the error
}
By separating the construction of configuration objects from their representation, we are able to throw an error if an object is created incorrectly. For example, a configuration object could be missing required properties or have multiple properties set that should not be set simultaneously.
// Try to create a JWPlayerConfiguration without a playlist
do {
let playerConfiguration = JWPlayerConfigurationBuilder()
.autostart(true)
.build() // Will throw an exception because “playlist” was not set
} catch {
// Do something with the error
}
The following subsections outline how to migrate the various configuration objects in version 3.x to iOS SDK 4.x.
JWAdConfig
In iOS SDK 4.x, JWAdConfig is called JWAdvertisingConfig. Create a JWAdvertisingConfig object using either the JWAdsAdvertisingConfigBuilder, JWImaAdvertisingConfigBuilder, or JWImaDaiAdvertisingConfigBuilder class.
| 3.x | 4.x |
|---|---|
adMessage |
JWAdsAdvertisingConfig.adMessage(_ adMessage: String) |
adVmap |
|
client |
Automatically set by the builder that is used to create the JWAdvertisingConfig |
freewheel |
|
googimaDaiSettings |
Automatically set by the JWImaDaiAdvertisingConfigBuilder |
googimaSettings |
Automatically set by the JWImaAdvertisingConfigBuilder |
rules |
JWAdsAdvertisingConfig.adRules(_ adRules: JWAdRules-- OR -- JWImaAdvertisingConfig.adRules(_ adRules: JWAdRules) |
schedule |
JWAdsAdvertisingConfig.schedule(_ schedule: [JWAdBreak])-- OR -- JWImaAdvertisingConfig.schedule(_ schedule: [JWAdBreak]) |
skipMessage |
JWAdsAdvertisingConfig.skipMessage(_ skipMessage: String) |
skipOffset |
JWAdsAdvertisingConfig.skipOffset(_ skipOffset: UInt) |
skipText |
JWAdsAdvertisingConfig.skipText(_ skipText: String) |
tag |
JWAdsAdvertisingConfig.tag(_ tag: URL)-- OR -- JWImaAdvertisingConfig.tag(_ tag: URL) |
vpaidControls |
JWAdsAdvertisingConfig.vpaidControls(_ vpaidControls: Bool) |
JWAdRules
In iOS SDK 4.x, JWAdRules is still called JWAdRules. Create a JWAdRules object using the JWAdRulesBuilder class.
| 3.x | 4.x |
|---|---|
frequency |
JWAdRulesBuilder.jwRules(_startOn: UInt, frequency: UInt, timeBetweenAds: UInt, startOnSeek: JWAdShownOnSeek)-- OR -- JWAdRulesBuilder.imaRules(startOn: UInt, frequency: UInt) |
startOn |
JWAdRulesBuilder.jwRules(_startOn: UInt, frequency: UInt, timeBetweenAds: UInt, startOnSeek: JWAdShownOnSeek)-- OR -- JWAdRulesBuilder.imaRules(startOn: UInt, frequency: UInt) |
startOnSeek |
JWAdRulesBuilder.jwRules(_startOn: UInt, frequency: UInt, timeBetweenAds: UInt, startOnSeek: JWAdShownOnSeek) |
timeBetweenAds |
JWAdRulesBuilder.jwRules(_startOn: UInt, frequency: UInt, timeBetweenAds: UInt, startOnSeek: JWAdShownOnSeek) |
JWConfig
In iOS SDK 4.x, JWConfig is called JWPlayerConfiguration. Create a JWPlayerConfiguration object using the JWPlayerConfigurationBuilder class.
| 3.x | 4.x |
|---|---|
advertising |
JWPlayerConfigurationBuilder.advertising(_ advertising: JWAdvertisingConfig) |
assetOptions |
|
audioSwitchingEnabled |
|
autostart |
JWPlayerConfigurationBuilder.autostart(_ autostart: Bool) |
bitRateUpperBound |
JWPlayerConfigurationBuilder.bitRateUpperBound(_ bitRateUpperBound: Float) |
captions |
JWPlayerView.captionStyle |
controls |
JWPlayerViewController.interfaceBehavior |
desc |
JWPlayerItemBuilder.description(_ description: String) |
displayDescription |
JWPlayerSkin.descriptionIsVisible |
displayTitle |
JWPlayerSkin.titleIsVisible |
externalMetadata |
JWPlayerConfigurationBuilder.externalMetadata(_ externalMetadata: [JWExternalMetadata]) |
file |
JWPlayerItemBuilder.file(_ file: URL) |
image |
JWPlayerItemBuilder.posterImage(_ posterImage: URL) |
logo |
JWPlayerViewController.logo |
mediaId |
JWPlayerItemBuilder.mediaId(_ mediaId: String) |
nextupDisplay |
JWPlayerViewController.nextUpStyle |
nextupOffset |
JWPlayerViewController.nextUpStyle |
nextupPercentage |
JWPlayerViewController.nextUpStyle |
offlineMessage |
JWPlayerViewController.offlineMessage |
offlinePoster |
JWPlayerViewController.offlinePosterImage |
playbackRates |
JWPlayerViewController.playbackRates |
playbackRateControls |
JWPlayerViewController.playbackRateControlsEnabled |
playlist |
JWPlayerConfigurationBuilder.playlist(_ playlist: [JWPlayerItem]) |
preload |
JWPlayerConfigurationBuilder.preload(_ preload: JWPreload) |
related |
JWPlayerConfigurationBuilder.related(_ related: JWRelatedContentConfiguration) |
repeat |
JWPlayerConfigurationBuilder.repeatContent(_ repeatContent: Bool) |
size |
Set the size of the player by setting the size of JWPlayerView |
skin |
JWPlayerViewController.styling |
sources |
JWPlayerItemBuilder.sources(_ videoSources: [JWVideoSource]) |
stretching |
The functionality of JWConfig.stretching can now be achieved dynamically by setting videoGravity on JWPlayerView. |
title |
JWPlayerItemBuilder.title(_ title: String) |
tracks |
JWPlayerItemBuilder.mediaTracks(_ mediaTracks: [JWMediaTrack]) |
JWPlaylistItem
In iOS SDK 4.x, JWPlaylistemItem is called JWPlayerItem. Create a JWPlayerItem object using the JWPlayerItemBuilder class.
| 3.x | 4.x |
|---|---|
adSchedule |
JWPlayerItemBuilder.adSchedule(_ adSchedule: [JWAdBreak]) |
assetOptions |
JWPlayerItemBuilder.assetOption |
desc |
JWPlayerItemBuilder.description(_ description: String) |
externalMetadata |
JWPlayerItemBuilder.externalMetadata |
file |
JWPlayerItemBuilder.file(_ file: URL) |
freewheel |
|
googleDaiSettings |
JWPlayerItemBuilder.googleDAIStream |
image |
JWPlayerItemBuilder.posterImage(_ posterImage: URL) |
mediaId |
JWPlayerItemBuilder.mediaId(_ mediaId: String) |
recommendations |
JWPlayerItemBuilder.recommendations(_ recommendations: URL) |
sources |
JWPlayerItemBuilder.videoSources(_ videoSources: [JWVideoSource]) |
startTime |
JWPlayerItemBuilder.startTime(_ startTime: TimeInterval) |
title |
JWPlayerItemBuilder.title(_ title: String) |
tracks |
JWPlayerItemBuilder.mediaTracks(_ mediaTracks: [JWMediaTrack]) |
JWSource
In iOS SDK 4.x, JWSource is called JWVideoSource. Create a JWVideoSource object using the JWVideoSourceBuilder class.
| 3.x | 4.x |
|---|---|
assetOptions |
|
defaultQuality |
JWVideoSourceBuilder.defaultVideo(_ defaultVideo: Bool) |
file |
JWVideoSourceBuilder.file(_ file: URL) |
label |
JWVideoSourceBuilder.label(_ label: String) |
JWTrack
In iOS SDK 4.x, JWTrack is called JWMediaTrack. Create a JWMediaTrack object using either the JWCaptionTrackBuilder or JWThumbnailTrackBuilder class.
| 3.x | 4.x |
|---|---|
defaultTrack |
JWCaptionTrackBuilder.defaultTrack(_ defaultTrack: Bool) |
file |
JWCaptionTrackBuilder.file(_ file: URL)-- OR -- JWThumbnailTrackBuilder.file(_ file: URL) |
kind |
Automatically set by the builder that’s used to create the JWMediaTrack |
label |
JWCaptionTrackBuilder.file(_ file: String) |
JWRelatedConfig
In iOS SDK 4.x, JWRelatedConfig is called JWRelatedContentConfiguration. Create a JWRelatedContentConfiguration object using the JWRelatedContentConfigurationBuilder class.
| 3.x | 4.x |
|---|---|
autoplayMessage |
JWRelatedContentConfigurationBuilder.autoplayMessage(_ message: String) |
autoplayTimer |
JWRelatedContentConfigurationBuilder.autoplayTimer(_ timer: Int) |
displayMode |
JWRelatedContentConfigurationBuilder.displayMode(_ mode: JWRelatedDisplayMode) |
file |
JWRelatedContentConfigurationBuilder.url(_ url: URL) |
heading |
JWRelatedContentConfigurationBuilder.heading(_ heading: String) |
onClick |
JWRelatedContentConfigurationBuilder.onClick(_ relatedOnClick: JWRelatedOnClick) |
onComplete |
JWRelatedContentConfigurationBuilder.onComplete(_ relatedOnComplete: JWRelatedOnComplete) |
Event API
In iOS SDK 3.x, there was one delegate (JWPlayerDelegate) to subscribe to for all events. Conforming to such a protocol in Swift would be cumbersome, as protocols in Swift require a class to conform to all interfaces.
In iOS SDK 4.x, the callbacks from JWPlayerDelegate have now been delegated to more logical interfaces. All playback and advertising-related callbacks have been divided across several new delegates. This allows you to optionally define delegates for categories of events through the JWPlayer object.
User interface-related delegates -- such as tracking what buttons a user is tapping or when the control bar appears or disappears -- can be subscribed to through the JWPlayerViewControllerDelegate.
Event Migration
The table below outlines how to migrate from the callbacks in JWPlayerDelegate to the iOS SDK 4.x delegates.
| 3.x | 4.x | Callback |
|---|---|---|
onAdBreakEnd |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdBreakStart |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdClick |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdCompanions |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdComplete |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdError |
JWPlayerDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdImpression |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdMeta |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdPause |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdPlay |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdRequest |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdSchedule |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdSkipped |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdStarted |
JWAdDelegate |
jwplayer(_ player: AnyObject, adEvent event: JWAdEvent) |
onAdTime |
JWPlayer |
See: [Time Events](#time-events) |
onAdWarning |
JWPlayerDelegate |
jwplayer(_:encounteredWarning:message:) |
onAll |
|
--- |
onAudioTrack |
JWAVDelegate |
jwplayer(_:audioTracksUpdated:) |
onAudioTrackChanged |
JWAVDelegate |
jwplayer(_:audioTrackChanged:) |
onBeforeComplete |
JWPlayerStateDelegate |
jwplayerContentWillComplete(_:) |
onBeforePlay |
JWPlayerStateDelegate |
jwplayer(_:willPlayWithReason:) |
onBuffer |
JWPlayerStateDelegate |
jwplayerContentIsBuffering(_:) |
onBufferChange |
JWPlayerStateDelegate |
jwplayer(_:updatedBuffer:position:) |
onCaptionsChanged |
JWAVDelegate |
jwplayer(_:captionTrackChanged:) |
onCaptionsList |
JWAVDelegate |
jwplayer(_:updatedCaptionList:) |
onComplete |
JWPlayerStateDelegate |
jwplayerContentDidComplete(_:) |
onControlbarVisible |
JWPlayerViewControllerDelegate |
playerViewController(_:controlBarVisibilityChanged) |
onControls |
|
--- |
onDisplayClick |
JWPlayerViewControllerDelegate |
playerViewController(_:screenTappedAt:) |
onError |
JWPlayerDelegate |
jwplayer(_:failedWithError:message:) |
onFirstFrame |
JWPlayerStateDelegate |
jwplayer(_:didFinishLoadingWithTime:) |
onFullscreen |
JWViewControllerDelegate |
playerViewControllerDidGoFullScreen(_:) |
onFullscreenRequested |
JWViewControllerDelegate |
playerViewControllerWillGoFullScreen(_:fullScreenViewController:) |
onIdle |
JWPlayerStateDelegate |
jwplayer(_:didBecomeIdleWithReason:) |
onLevels |
JWAVDelegate |
jwplayer(_:qualityLevelsUpdated:) |
onLevelsChanged |
JWAVDelegate |
jwplayer(_:qualityLevelChanged:) |
onMeta |
JWPlaybackMetadataDelegate |
jwplayer(_:didReceiveMetadata:) |
onPause |
JWPlayerStateDelegate |
jwplayer(_:didPauseWithReason:) |
onPlay |
JWPlayerStateDelegate |
jwplayer(_:isPlayingWithReason:) |
onPlayAttempt |
JWPlayerStateDelegate |
jwplayer(_:isAttemptingToPlay:reason:) |
onPlaybackRateChanged |
JWPlayerStateDelegate |
jwplayer(_:playbackRateChangedTo:at:) |
onPlaylist |
JWPlayerStateDelegate |
jwplayer(_:didLoadPlaylist:) |
onPlaylistComplete |
JWPlayerStateDelegate |
jwplayerPlaylistHasCompleted(_:) |
onPlaylistItem |
JWPlayerStateDelegate |
jwplayer(_:didLoadPlaylistItem:at:) |
onReady |
JWPlayerDelegate |
jwplayerIsReady(_:) |
onRelatedClose |
JWPlayerViewControllerDelegate |
playerViewController(_:relatedMenuClosedWithMethod:) |
onRelatedOpen |
JWPlayerViewControllerDelegate |
playerViewController(_:relatedMenuOpenedWithItem:withMethod:) |
onRelatedPlay |
JWPlayerViewControllerDelegate |
playerViewController(_:relatedItemBeganPlaying:atIndex:withMethod:) |
onResize |
JWViewControllerDelegateJWPlayerViewDelegate |
playerViewController(_:sizeChangedFrom:to:)playerView(_:sizeChangedFrom:to:) |
onSeek |
JWPlayerStateDelegate |
jwplayerHasSeeked(_:) |
onSeeked |
JWPlayerStateDelegate |
jwplayer(_:seekedFrom:to:) |
onSetupError |
JWPlayerDelegate |
jwplayer(_:failedWithSetupError:message:) |
onTime |
JWPlayer |
See: [Time Events](#time-events) |
onViewable |
JWPlayerStateDelegate |
jwplayer(_:isVisible:) |
onWarning |
JWPlayerDelegate |
jwplayer(_:encounteredWarning:message:) |
Additional Callbacks
New callbacks have been added to iOS SDK 4.x.
| 3.x | 4.x | Callback |
|---|---|---|
JWAVDelegate |
jwplayer(_:captionPresented:at:) |
Called when a caption is being presented on the screen |
JWPlayerStateDelegate |
jwplayer(_:usesMediaType:) |
Reports when the type of media has been determined |
Time Events
The iOS SDK allows you to listen to two different categories of time events: ad time and media time. To listen to these events, you must supply a closure which receives a JWTimeData object as a parameter.
The JWTimeData object contains a position (the number of seconds since the beginning of the content whether it is media or an advertisement) and a duration (the length of the currently playing content expressed as a number of seconds). When active, each of these time events fire every 100 milliseconds.
-
Ad time events only report while an ad is playing. This type of event reports the number of seconds the current ad has been playing as well as the duration of the current ad.
-
Media time events only report while the current
JWPlayerItem, your main content, is playing. These events do not report while an ad is playing. This type of event reports the number of seconds the content has been playing, as well as the total duration of the content. Neither of these values include the playback duration of an ad if the ad has already been played.
Creating a time observer is best used if you are going to respond to the time events.
For situations in which you need to query the position and duration of the currently playing media at non-specific intervals, it is best to retrieve the value of the time property in
JWPlayer.
If you have implemented the player using a JWPlayerViewController, these events are observed by overriding methods using your subclass.
// Subclass of JWPlayerViewController
class PlayerViewController: JWPlayerViewController {
override func onAdTimeEvent(_ time: JWTimeData) {
// Always be sure to inform the superclass of the event so
// the user interface updates.
super.onAdTimeEvent(time)
// Handle the event here.
}
override func onMediaTimeEvent(_ time: JWTimeData) {
// Always be sure to inform the superclass of the event so
// the user interface updates.
super.onMediaTimeEvent(time)
// Handle the event here.
}
}
// Subclass of JWPlayerObjViewController
@implementation PlayerViewController
- (void)onAdTimeEvent:(JWTimeData * _Nonnull)time {
// Always be sure to inform the superclass of the event so
// the user interface updates.
[super onAdTimeEvent:time];
// Handle the event here
}
- (void)onMediaTimeEvent:(JWTimeData * _Nonnull)time {
// Always be sure to inform the superclass of the event so
// the user interface updates.
[super onMediaTimeEvent:time];
// Handle the event here
}
@end
If you have elected to create the player by only instantiating a JWPlayerView, you must supply a closure to the JWPlayer object.
// Your custom method for setting up your time observers.
func yourSetupTimeObserversMethod(view: JWPlayerView) {
let player = view.player
// Listen to ad time events
player.adTimeObserver = { (time) in
// Handle the event here.
}
// Listen to media time events
player.mediaTimeObserver = { (time) in
// Handle the event here.
}
}
- (void)yourSetupTimeObserversMethod:(JWPlayerView *)view {
id<JWPlayer> player = view.player;
// Listen to ad time events
player.adTimeObserver = ^(JWTimeData * time) {
// Handle the event here.
};
// Listen to media time events
player.mediaTimeObserver = ^(JWTimeData * time) {
// Handle the event here.
};
}
Advertising API
In iOS SDK 4.x, the Advertising API maintains support for VAST, VMAP, Google IMA, and Google DAI advertising.
In iOS SDK 3.x, there was an advertising configuration property used to set up any type of ads. In iOS SDK 4.x, you can set up the advertising configuration through new dedicated builders for each type of ad.
| Advertising | Builder |
|---|---|
| VAST & VMAP | JWAdsAdvertisingConfigBuilder |
| Google IMA | JWImaAdvertisingConfigBuilder |
| Google DAI | JWImaDaiAdvertisingConfigBuilder |
To begin running advertising in iOS SDK 4.x, you must create a JWPlayerConfigurationBuilder to include the advertising configuration. Refer to Configuration API and Set up a basic player for more info about setting up the player.
- FreeWheel and VPAID advertising are no longer supported by iOS SDK 4.x.
- You must include the GoogleIMA SDK v3.11.4 in your project if you want to monetize advertising through IMA or DAI.
- For examples on creating advertisements, please refer to the advertising documentation.
Listening to advertising events
In iOS SDK 4.x, there is a dedicated delegate for the advertising events: JWAdDelegate. Refer to Event Migration for more info about the implementation of these delegates.
In iOS SDK 3.x, the SDK reported the ad time event by constantly calling the delegate method informing the current time of an ad. In iOS SDK 4.x, the ad time event is reported in a different way that increases the performance of listening for this event. Refer to Time Events for more information.
Updated about 2 years ago
