Skip to content

Migration Guide 2.x to 3.x

Andrew Clunis edited this page Jun 26, 2019 · 12 revisions

Getting Started

The Rover SDK has been split into two components: the new version of the Rover SDK itself which now contains only the Experiences rendering functionality, and the new Rover Campaigns SDK which contains the automation and campaigns functionality. This gives you the benefit of being able to upgrade Rover components independently of one another going forward.

Change Rover Dependencies

The first step will be to link against the Rover Campaigns 3.0 SDK in lieu of the old Rover 2.x SDK. It is largely a drop-in replacement.

With Cocoapods

First off, make sure your local copy of Cocoapods is up to date, to 1.7.1 as of time of writing: brew upgrade cocoapods.

Change the Rover 2.x Cocoapods entries to their Rover Campaigns 3.0 equivalents.

For example, given a Podfile that looks something like the following:

target 'MyApp' do
    ...
    # If you have an entry to bring in the entire SDK:
    pod 'Rover', '~> 2.4.0'

    # or, perhaps, you have specified individual modules instead:
    pod 'Rover/Core',          '~> 2.4.0'
    pod 'Rover/Bluetooth',     '~> 2.4.0'
    pod 'Rover/Ticketmaster',   '~> 2.4.0'
    pod 'Rover/AdSupport',     '~> 2.4.0'
    pod 'Rover/Telephony',     '~> 2.4.0'
end

# And, if you have a notification extension:
target 'NotificationService' do
    ...
    pod 'RoverAppExtensions', '~> 2.4.0'
end

The only change you will need to make is to change Rover to RoverCampaigns (although not for the Notification Extension, if you have one), and bump the version number to 3.0:

target 'MyApp' do
    ...
    # Again, in the case of the entire SDK:
    pod 'RoverCampaigns', '~> 3.0.0'

    # or, again, you have specified individual modules:
    pod 'RoverCampaigns/Core',          '~> 3.0.0'
    pod 'RoverCampaigns/Bluetooth',     '~> 3.0.0'
    pod 'RoverCampaigns/Ticketmaster',   '~> 3.0.0'
    pod 'RoverCampaigns/AdSupport',     '~> 3.0.0'
    pod 'RoverCampaigns/Telephony',     '~> 3.0.0'
end

# The Notification extension is not renamed, but you still need to bump
# the version number:
target 'NotificationService' do
    ...
    pod 'RoverAppExtensions', '~> 3.0.0'
end

Now you can update the pods from your shell:

$ pod update

Xcode 10.1 / Swift 4.2

Rover Campaigns supports Swift 5 out of the box.

However, if you are held back on an old version of the Swift toolchain (and thus Xcode), perhaps because of another binary-only dependency that requires an older ABI, then you need to inform Cocoapods that you want it to install Rover Campaigns in Swift 4.2 mode instead of Swift 5 mode. If you don't do this in an Xcode 10.1/Swift 4.2 project, you'll end up with a Pods Xcode project being generated that specifies a newer compiler than your environment has available, yielding a SWIFT_VERSION '5.0' unsupported error or similar.

In that case you should add the following directive to both of your Cocoapods target blocks:

target 'MyApp' do
    supports_swift_versions '4.2'
    ...
end

Update Code References

The bulk of the reamining changes are simple renames and can be handled using the batch Search & Replace tool in Xcode, accessible with Shift-⌥-⌘-F. Note that you should select a scope to avoid clobbering things inside the Pods, particularly the Rover libraries themselves. Click the scope button (it may show "In Workspace" by default), and select your app's Project instead of the entire workspace.

Package Imports

Previously you would have the following import directive in your Swift files:

import RoverKit

These should be replaced with:

import RoverCampaigns

However, since this migration has involved splitting the SDK in two, you will may also need to leave the original import Rover alongside the new import RoverCampaigns in cases where you have used Experiences-related types directly. For example, if you directly used ExperienceViewController (now RoverViewController, see below), the Experience data model, or some other Experience-related concern.

Type Renames

Several Rover types have been renamed as part of this update.

Top-Level Container

The top-level Rover object has been renamed. The most strategic way to rename all the references to it is to Search & Replace it with a . affixed to it since the cases we want to match are always member dereferences (namely Rover.shared and Rover.initialize).

Rover.

These should be replaced with:

RoverCampaigns.

API Changes

ID Type Removed

There used to be an ID wrapper type. If you are instantiating Rover IDs, for example Experiences, they should be replaced by using the string directly. Eg., ID(rawValue: "my-id") should become simply "my-id".

AttributeKey and AttributeValue Types Removed

The AttributeKey and AttributeValue types have been removed. For setting User Info, you can now just build a dictionary directly with your keys and values and eschew the old wrapper types.

Launching Experiences

The top-level View Controller for rendering experiences has been renamed from ExperienceViewController to RoverViewController. It has also had its API simplified and changed somewhat, and you can now also use it directly without resolving it through the Rover container.

Currently, you may have something like this for launching a Rover Experience:

import RoverKit

let id = ID(rawValue: experienceID)
let identifier = ExperienceIdentifier.experienceID(id: id)
let viewController = Rover.shared?.resolve(UIViewController.self, name: "experience", arguments: identifier)
self.present(viewController!, animated: true, completion: nil)

This should be replaced with:

// Note that you will need to import Rover instead of the old RoverKit to use
// this API, in addition to importing RoverCampaigns if otherwise required in
// this Swift file.
import Rover

let roverViewController = RoverViewController()
roverViewController.loadExperience(id: experienceID)
self.present(roverViewController, animated: true, completion: nil)

If you programmatically launch an experience with a Campaign ID, you must now also always provide the matching Rover Experience ID as well:

roverViewController.loadExperience(id: experienceID, campaignID: campaignID)
Clone this wiki locally