Downloads
The Download to go(D2G) feature allows you to download VODs and play them back offline and is managed with DiceShield class. First of all it needs to be setup properly
// import module responsible for D2G
import dice_shield_ios
// Configure internal network requests manager to fetch all required data for downloading from DICE api having VOD id
let config = APIConfig(baseURL: "<base url without backslash in the end>",
apiKey: "<api key>",
realm: "<realm>",
deviceId: "<device id>",
headers: "<any extra headers to include with all api calls>")
DiceShield.sharedProvider.setup(config: config)
Before downloading set auth token, this needs to be updated every time token is expired, if token is expired DiceShield will return an error that should be handled with refresh token and call this method again with a fresh token
DiceShield.sharedProvider.setToken(newToken: "<authorisationToken>")
You will also need to observe downloads updates like download progress/state etc. This method will be called for all downloads after it was added with DiceShield.sharedProvider.addDownload(asset: DownloadableAsset)
DiceShield.sharedProvider.delegate = self
func downloadDidUpdate(withData data: DownloadUpdateInfo) {
DispatchQueue.main.async {
//update UI
for viewModel in self.viewModels {
if viewModel.id == data.assetId {
viewModel.progress = data.progress
viewModel.downloadState = data.state
viewModel.expiryDate = data.expiryDate //if this date is expired (data.expiryDate < Date.current) you should renew it with corresponding method: DiceShield.sharedProvider.renewLicense
}
}
}
}
Start downloading certain content
Important
all previous downloads with same ID will be removed and replaced with the new one
let asset = DownloadableAsset(
itemId: "<VOD id>",
title: "Video title", // video title
extraData: nil, //any other data you want to store assosiated with this content
images: nil, //any images you want to store assisiated with this content
quality: .HIGH, //desired quality to download
language: "eng" //language of VOD to download in ISO 639-3 format
)
DiceShield.sharedProvider.addDownload(asset: asset) { [weak self] result in
DispatchQueue.main.async {
switch result {
case .success:
//at this point download was added to downloading queue and you can observe download updates with a delegate method DownloadProviderDelegate.downloadDidUpdate(withData: DownloadUpdateInfo) see above
break
case .failure(let error):
//You can cast all errors to DiceShieldError to get an underlying reason of it is possible
if let error = error as? DiceShieldError, error.kind == .unauthorized {
//here for example refresh token and provide valid one
self?.refreshToken() { token in
DiceShield.sharedProvider.setToken(newToken: token)
}
}
}
}
}
Get all downloads that were added to the queue
DiceShield.sharedProvider.getAllDownloads() { [weak self] result in
DispatchQueue.main.async {
guard let self = self else { return }
switch result {
case .success(let assets):
//update UI here with all downloaded/downloading assets
default:
break
}
}
}
All downloads will have assosiated license with expiration date, when it is expired you will no longer be able to playback that content until license is renewed.
DiceShield.sharedProvider.renewLicense(id: "<VOD id>") { [weak self] (result) in
DispatchQueue.main.async {
switch result {
case .success:
//license was renewed, you should be able to observe this change through delegate method
case .failure(let error):
//You can cast all errors to DiceShieldError to get an underlying reason of it is possible
if let error = error as? DiceShieldError, error.kind == .unauthorized {
//here for example refresh token and provide valid one
self?.refreshToken() { token in
DiceShield.sharedProvider.setToken(newToken: token)
}
}
}
}
}
To playback downloaded content
DiceShield.sharedProvider.downloadProvider.getDownload(forId: "<VOD id>") { [weak self] result in
DispatchQueue.main.async {
switch result {
case .success(let data):
guard let localUrl = data.localFileUrl else { return }
let source = DorisSource(playerItem: AVPlayerItem(url: localUrl))
source.drm = DorisDRMSource(contentUrl: filePath.absoluteString, croToken: nil, licensingServerUrl: nil)
doris?.load(source: source, initialSeek: nil)
case .failure(let error):
self?.view?.showError(error.localizedDescription)
}
}
}
You will also have controll over downloads with these methods
func getDownloads(forStates states: [AssetDownloadState], completion: @escaping (Swift.Result<[AssetData], Error>) -> Void)
func removeDownloads(itemIds: [String], completion: @escaping (Swift.Result<Void, Error>) -> Void)
func removeDownload(itemId: String, completion: @escaping (Swift.Result<Void, Error>) -> Void)
func pauseDownload(itemID: String, completion: @escaping (Swift.Result<Void, Error>) -> Void)
func resumeDownload(itemID: String, completion: @escaping (Swift.Result<Void, Error>) -> Void)
func pauseAllDownloads(completion: @escaping (Swift.Result<Void, Error>) -> Void)
func resumeAllDownloads(completion: @escaping (Swift.Result<Void, Error>) -> Void)
func cancelAllDownloads(completion: @escaping (Swift.Result<Void, Error>) -> Void)
Important!: If your application was closed while downloading content, it won’t automatically resume on relaunch. You will have to resume all downloads manually, call this method from your AppDelagate to achieve that
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { DiceShield.sharedProvider.restoreSuspendedDownloads() return true }