Introduction
This book describes how to work with AdPlayer Lite library.
Tags
AdPlayer Lite library works with publishers and tags. Publisher is a unique ID for the whole organization, while Tag is a placement configration on the screen. There can be any number of tags but only one publisher.
Tags can be created and configured by using the admin console.
Types of Tags
Tags can be split into to categories:
- Outstream - displays only a series of Ads
- Instream - displays video content interleaved with Ads
The SDK is available as an SPM package on:
https://github.com/Aniview/ad-player-lite-ios-spm
For more details please refer to:
Adding package dependencies to your app
See also:
Example App
To integrate the SDK into the project you might want to:
- Initialize SDK
- Request tracking authorization https://developer.apple.com/documentation/apptrackingtransparency
- Request GDPR (if applicable)
- Add the player to UI Layout
Please refer to the Displaying guide for more details - Ensure the player shows Ads / Content
Initialize SDK
The SDK must be Initialized before it's used.
Please provide the actual AppStore URL.
It's needed for proper ad impression tracking and affects monetization.
import AdPlayerLite
import UIKit
final class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
let storeURL = URL(string: Constants.storeURL)!
AdPlayer.initSDK(storeUrl: storeURL)
return true
}
}
Displaying Ads / Content
This chapter covers ways to display Ads / Content
Here is how to add the Player to the UIkit layout.
Adding AdPlacementView
import UIKit
import AdPlayerLite
class YourViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let controller = AdPlayer
.getTag(pubId: "<your pubId>", tagId: "<your tagId>")
.newInReadController()
let placement = AdPlacementView()
placement.attachController(controller)
placement.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(placement)
NSLayoutConstraint.activate([
placement.leadingAnchor.constraint(equalTo: view.leadingAnchor),
placement.trailingAnchor.constraint(equalTo: view.trailingAnchor),
placement.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor)
])
}
}
Note: The AdPlacementView's width must be defined.
Observing Player's Height Changes
This part is optional as long as AdPlacementView resizes automatically. However it might be useful in order to implement expanding/collapsing animation
import UIKit
import AdPlayerLite
// viewDidLoad
let placement = AdPlacementView()
...
placement.delegate = self
//
extension YourViewController: AdPlacementViewLayoutDelegate {
func onResize(height: CGFloat) {
guard lastReportedHeight != height else {
return
}
lastReportedHeight = height
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
}
See also: Basic UI Kit Example
SwiftUI view is not included in the SDK for the sake of keeping it minimalistic.
However AdPlacementView can be easily wrapped in UIViewRepresentable
Please refer to:
Launching Interstitials
Unlike in-read mode, interstitials don't require any placement view - it's presented as a modal fullscreen UIViewController.
Interstitials will be automatically closed once the first video finishes.
Here is a basic example:
AdPlayer.showInterstitial(pubId: pubId, tagId: tagId) {
// Interstitial has been dismissed
}
Also, you might want to customise Interstitial's behaviour:
let config = InterstitialConfiguration(
stalledVideoTimeout: 2.0,
showCloseButtonAfterAdDuration: true
)
AdPlayer.showInterstitial(pubId: pubId, tagId: tagId, configuration: config) { }
AdPlayerController
The AdPlayerController is a key component of the AdPlayerLite SDK, designed to manage and control video playback within the AdPlacementView. This guide provides an overview of its features and how to use it effectively.
The AdPlayerController is used to interact with the player, observe its state, and control playback.
There are also more specialized controllers available:
- AdPlayerInReadController - for working with in-read content
- AdPlayerInterstitialController - for displaying interstitials
Creating Controller
let controller = AdPlayer
.getTag(pubId: "<your pubId>", tagId: "<your tagId>")
.newInReadController()
Accessing the AdPlayerController
You can obtain an AdPlayerController instance from an AdPlacementView
(but it should be attached before. Otherwise it will be nil )
let placement = AdPlacementView()
placement.attachController(controller)
...
let controller = placement.controller
Features
Player State
-
Property:
state- Type:
AdPlayerLite.AdPlayerState - Description: Represents the current playing state of the player.
- Type:
-
Publisher:
statePublisher- Type:
AnyPublisher<AdPlayerLite.AdPlayerState, Never> - Description: Allows observation of the playing state over time.
- Type:
Player Events
- Publisher:
eventsPublisher- Type:
AnyPublisher<AdPlayerLite.AdPlayerEvent, Never> - Description: Emits player events as they occur.
- Type:
Current Playing Content
-
Property:
content- Type:
AdPlayerLite.AdPlayerContent? - Description: The currently playing content.
- Type:
-
Publisher:
contentPublisher- Type:
AnyPublisher<AdPlayerLite.AdPlayerContent?, Never> - Description: Allows observation of the currently playing content.
- Type:
Content Playlist
-
Property:
playlist- Type:
[AdPlayerLite.AdPlayerContent] - Description: The content playlist managed by the player.
- Type:
-
Publisher:
playlistPublisher- Type:
AnyPublisher<[AdPlayerLite.AdPlayerContent], Never> - Description: Allows observation of the content playlist.
- Type:
Controlling Playback
Basic Controls
-
Pause Playback:
pause()- Pauses the player if it is currently playing.
-
Resume Playback:
resume()- Resumes playback if the player is paused.
-
Skip Playback:
skipAd()- Skips the currently playing ad, if any.
-
Mute Playback:
mute()- Mutes playbackd.
-
Unmute Playback:
unmute()- Un-mutes playback.
Fullscreen Mode
- Toggle Fullscreen:
toggleFullscreen()- Moves the player to or from fullscreen mode.
Content Navigation
-
Play Next Content:
playNextContent()- Plays the next content in the playlist if available.
-
Play Previous Content:
playPrevContent()- Plays the previous content in the playlist if available.
-
Play Content by Index:
playContentByIndex(_ index: Int)- Plays the content at the specified index in the playlist.
Playback Information
Ads
- Ready Ads Count:
getReadyAdsCount() async -> Int- Returns the number of ads ready to be displayed but not yet shown (outstream only).
Playback Positions and Durations
-
Ad Position:
getAdPosition() async -> TimeInterval- Retrieves the current position of the ad being played.
-
Ad Duration:
getAdDuration() async -> TimeInterval- Retrieves the total duration of the ad being played.
-
Content Position:
getContentPosition() async -> TimeInterval- Retrieves the current position of the playing content.
-
Content Duration:
getContentDuration() async -> TimeInterval- Retrieves the total duration of the playing content.
Observing Player State and Events
You can use the provided publishers to observe changes in the player's state, events, content, and playlist. This is particularly useful for updating the UI dynamically.
Example:
import Combine
var cancellables: Set<AnyCancellable> = []
controller.statePublisher
.sink { state in
print("Player state: \(state)")
}
.store(in: &cancellables)
controller.eventsPublisher
.sink { event in
print("Player event: \(event)")
}
.store(in: &cancellables)
Best Practices
- Ensure to manage memory by storing publishers in a
Set<AnyCancellable>. - Use async methods like
getAdPositionorgetContentDurationto retrieve information when needed. - Leverage the
statePublisherandeventsPublisherfor real-time updates and debugging.
Conclusion
The AdPlayerController provides comprehensive control over the playback of ads and content within the AdPlayerLite SDK. By understanding its features and using the provided methods and publishers, you can build a seamless and interactive video ad experience.
Fullscreen
Normally, the player transitions to full-screen mode when the user taps the full-screen button in the player’s UI (when the button is enabled).
It’s also possible to present the player in full-screen mode programmatically.
Fullscreen toggle
The following shows how to toggle full-screen mode programmatically:
let controller: AdPlayerController
controller.toggleFullscreen()
Override default fullscreen configuration
let controller = AdPlayer
.getTag(pubId: pubId, tagId: tagId)
.newInReadController {
$0.fullScreenConfiguration.ignoreSafeArea = true
$0.fullScreenConfiguration.isCloseButtonEnabled = true
$0.fullScreenConfiguration.insets = .zero
}
Content and Playlist
Both content and playlists are only available for insteam tags.
Managing Playlist
Playlist contains list of content videos that are played one after the other. We can read current playlist like this:
let controller: AdPlayerController = ...
let playlist = controller.playlist.value // CAUTION: might not be loaded yet
print(playlist)
One important note here is that playlist is loaded by the library asynchronously and might not be available right after the controller is created. This might result in the above API returning empty playlist. It is advised, in most cases, for the application to track when playlist changes:
cancellable = controller.playlistPublisher.sink { [weak self] playlist in
guard let self, playlist.count > 1 else { return }
print(playlist)
}
Currently Played Content
AdPlayerController can be used to track which content is currently playing:
let controller: AdPlayerController = ...
// reading current content
print("\(controller.content) is currently playing")
cancellable = controller.contentPublisher.sink { [weak self] content in
guard let self else { return }
print("\(content) is currently playing")
}
Reading playback progress
let controller: AdPlayerController = ...
Task {
let duration = await getDuration(isContent: isContent)
let position = isContent ? await controller.getContentPosition() : await controller.getAdPosition()
print("Current position \(position) / \(duration)")
}
Choosing Content to Play
In order to play different video from the playlist we can use these functions:
let controller: AdPlayerController = ...
// play next video
controller.playNextContent()
// play previous video
controller.playPrevContent()
// play specific video
controller.playContentByIndex(3)
See also:
Time Indicator Example
Instream: Overriding defaults
To change some predefined In-Stream settings:
let tag = AdPlayer.getTag(...)
let controller = tag.newInReadController {
// override in-stream content by using CmsId
$0.contentOverride = .cmsId("<custom video cms id>")
// override in-stream content by using direct video url
$0.contentOverride = .directUrls(["<custom video URL>"])
// disable in-stream video ads
$0.disableVideoAds = true
}
// Attach new controller to the placement view
let placement = AdPlacementView()
placement.attachController(controller)
Player Controls Visibility
Available since 1.3.0
Visibility of some buttons displayed by the player can be changed if required.
Changing Visibility
Each button can be hidden or shown:
let controller: AdPlayerController
controller.showPlayButton.value = false
controller.showSoundButton.value = false
controller.showFullscreenButton.value = false
Visibility Default Values
Visibility states are represented as a nullable Bool? type.
This allows seamless rollback to default value by passing a null value.
val controller: AdPlayerController
controller.showPlayButton.value = true // visible
controller.showSoundButton.value = false // invisible
controller.showFullscreenButton.value = nil // default value
Example App is available here: Example App