iOS Collector Migration Guide from API v2 to v3

The iOS Analytics Collector introduced breaking changes with the major version release 3.0.0. This guide explains the reasons behind the breaking changes and how to easily migrate to the new Collector API.

Bitmovin Player

Step 1 BitmovinAnalytics is now a direct dependency of BitmovinPlayer

SPM setup: Replace dependencies

With version 3.42.0 of our Bitmovin Player, Analytics is included out of the box. No need for a separate deployment anymore! :star2:

  • Navigate to Project Settings > Package Dependencies
  • Make sure you have removed the BitmovinAnalytics/bitmovin-analytics-collector-ios package
  • Ensure you have added at least BitmovinPlayer version 3.42.0

Once this is done you should see BitmovinAnalytics appear again in the Package Dependency side bar

cocoapod Setup: Update imports

If you're using Cocoapods to manage your dependencies, follow these steps.

  • Open your Podfile
  • Remove the import of BitmovinAnalyticsCollector
-  pod 'BitmovinAnalyticsCollector/Core', '2.11.0'
-  pod 'BitmovinAnalyticsCollector/BitmovinPlayer', '2.11.0'
  • Make sure you use at least BitmovinPlayer version 3.42.0 (pod 'BitmovinPlayer', '3.42.0')

Step 2 Remove the creation of the collector

There's no need to create a collector instance anymore. This is all handled by the player.


// change to the new config
- let config = BitmovinAnalyticsConfig(key: "<ANALYTICS_LICENSE_KEY>")
+ let config = AnalyticsConfig(licenseKey: "<ANALYTICS_LICENSE_KEY>")

// optional metadata object
+ let defaultMetadata = DefaultMetadata()

// remove collector creation
- let collector = BitmovinPlayerCollector(config: config)

// use the config to create the player
- let player = PlayerFactory.create()
+ let player = PlayerFactory.create(analyticsConfig: config, defaultMetadata: defaultMetadata)

// no need to connect the player and collector
- collector.attachPlayer(player: player)

For more information on how to configure our collector, you check out our configuration guide

Add SourceMetadata to Source (Optional)

As some of the video metadata has been removed from the config, instead you need to provide this information via the player Source.


let sourceMetadata = SourceMetadata(
	title: "Sintel"	
)

// remove old collector API calls
- collector.setSourceMetadata(sourceMetadata: sourceMetadata)

// provide metadata at source creation
- let source = SourceFactory.create(from: sourceConfig)
+ let source = SourceFactory.create(from: sourceConfig, sourceMetadata: sourceMetadata)

You can find more information about the new Player Analytics API here

Third Party Players

Step 1: Change SPM package names

📘

What if I'm using Cocoapods to import BitmovinAnalyticsCollector?

There were no package name changes. Your setup should be fine and doesn't need further adaptations.

Just update the version to 3.0.0 and run pod install in your project.

In order to be more consistent with package names, we decided to rename our libraries. This change affects your package setup in Package.swift, but also your Swift files which import the collector.

Manually replace the packages names in Package.swift

If you use a Package.swift file to resolve dependencies in your app, navigate to this file and replace the package names with the new names. See the package name mapping in the appendix

For example, the target in your Package.swift file could look like this:

.target(
      name: "<NAME_OF_YOUR_PACKAGE>",
      dependencies: [
        .product(name: "AVFoundationCollector", package: "bitmovin-analytics-collector-ios", from: "3.0.0")
        // OR
        .product(name: "AmazonIVSCollector", package: "bitmovin-analytics-collector-ios", from: "3.0.0")
      ]),
  ]

Use Xcode to Resolve Package Conflict

If you use Xcode to update the BitmovinAnalyticsCollector dependency to version 3.0.0, you will see an error. For example, when using the BitmovinPlayer, you will see: Missing package product 'BitmovinPlayerCollector'.

This happens because we changed the name of the package, and your previously imported package is not available anymore.

  • Navigate to Project > Package Dependencies
  • Remove the Package BitmovinAnalytics and add the package bitmovin-analytics-collector-ios again
  • It will ask you which package products you want to use. Select the one that fits your player setup

Step 2: Replace Imports

Because we changed the names of our products, your import statements need to be changed

  • Search your project for occurrences of old product names. See appendix
  • Replace all with new product names
- import AVPlayerCollector
+ import AVFoundationCollector
- import AmazonIVSPlayerCollector
+ import AmazonIVSCollector

Step 3: Change Collector Setup

Replace BitmovinAnalyticsConfig with AnalyticsConfig

The new configuration class only contains behavioural settings of the collector.

- let config = BitmovinAnalyticsConfig(key: "<YOUR_ANALYTICS_LICENSE_KEY>")
+ let config = AnalyticsConfig(licenseKey: "<YOUR_ANALYTICS_LICENSE_KEY>")

Add DefaultMetadata (Optional)

Some of the Metadata of the stream is now provided by DefaultMetadata

- config.cdnProvider = ""
- config.customerUserId = ""
- config.customData1 = ""
+ let defaultMetadata = DefaultMetadata(
+   cdnProvider: "",
+   customUserId: "",
+   customData: CustomData(customData1: "")
+ )

Replace Old Constructor Call with New Factory Method Call

To use the new factory method, you first need to change the type of your collector variable. Instead of concrete classes, you use a protocol. The collector protocols end with ...CollectorApi.

Then you can use the Factory like this

- let collector = AVPlayerCollector(config: config)
+ let collector: AVPlayerCollectorApi = AVPlayerCollectorFactory.create(config: config, defaultMetadata: defaultMetadata
- let collector = AmazonIVSPlayerCollector(config: config)
+ let collector: AmazonIVSPlayerApi = AmazonIVSPlayerCollectorFactory.create(config: config, defaultMetadata: defaultMetadat

Add SourceMetadata (Optional)

Some of the video-specific metadata is now provided by SourceMetadata

- config.videoId = ""
- config.title = ""
- config.path = ""
- config.isLive = true
- config.cdnProvider = ""
- config.customData2 = ""
+ let sourceMetadata = SourceMetadata(
+   videoId: "",
+   title: "",
+   path: "",
+   isLive: true,
+   cdnProvider: "",
+   customData: CustomData(customData2: "")
+ )

+ collector.sourceMetadata = sourceMetadata

Appendix: Mappings

Config and Metadata

v2v3
BitmovinAnalyticsConfigdeprecated
AnalyticsConfig
DefaultMetadata
SourceMetadataSourceMetadata (removed inline customData properties)
CustomData

Player Analytics API

The Player API provides a way to access the Analytics API.

Here is a quick mapping of methods.

v2bundle
collector.getUserId()player.analytics.userId
collector.setCustomDataOnce()player.analytics.sendCustomDataEvent(customData:)
collector.setSourceMetadata()player.source.analytics.metadata
collector.setCustomData()removed from the collector - access now via source with
player.source.analytics.customData

Third Party Package names

v2v3
AVPlayerCollectorAVFoundationCollector
AmazonIVSPlayerCollectorAmazonIVSCollector

AVPlayer collector

v2v3
AVPlayerCollectordeprecated
AVPlayerCollectorApi
AVPlayerCollectorFactory
AVPlayerCollector.attachPlayer(player:)AVPlayerCollectorApi.attach(to:)
AVPlayerCollector.detachPlayer()AVPlayerCollectorApi.detach()
AVPlayerCollector.getUserId()AVPlayerCollectorApi.userId
AVPlayerCollector.setCustomDataOnce(customData:)AVPlayerCollectorApi.sendCustomDataEvent(with:)
AVPlayerCollector.setCustomData(customData:)AVPlayerCollectorApi.customData
AVPlayerCollector.getCustomData()AVPlayerCollectorApi.customData

Amazon IVS player collector

v2v3
AmazonIVSCollectorremoved
AmazonIVSPlayerCollectorApi
AmazonIVSPlayerCollectorFactory
AmazonIVSCollector.attachPlayer(player:)AmazonIVSPlayerCollectorApi.attach(to:)
AmazonIVSCollector.detachPlayer()AmazonIVSPlayerCollectorApi.detach()
AmazonIVSCollector.getUserId()AmazonIVSPlayerCollectorApi.userId
AmazonIVSCollector.setCustomDataOnce(customData:)AmazonIVSPlayerCollectorApi.sendCustomDataEvent(with:)
AmazonIVSCollector.setCustomData(customData:)AmazonIVSPlayerCollectorApi.customData
AmazonIVSCollector.getCustomData()AmazonIVSPlayerCollectorApi.customData