# Batch 2.0

Batch SDK v2 is a major release, which introduces breaking changes from 1.x. This guide describes how to update your application when using a previous version.

### Upgrading the SDK version

⚠️ Batch SDK 2.0 now requires Xcode 15.3 and iOS 13.0 or higher.

To upgrade from v1 to v2, you need to change the SDK version according to your package manager:

{% tabs %}
{% tab title="SPM" %}
Update by using the "update package" option from Xcode or updating your `package.swift`.

{% code title="Package.swift" %}

```swift
.package(url: "https://github.com/BatchLabs/Batch-iOS-SDK", from: "2.0.0")
```

{% endcode %}
{% endtab %}

{% tab title="CocoaPods" %}
Update your `Podfile` as following and run `pod update`.

{% code title="Podfile" %}

```swift
pod 'Batch', '~> 2.0'
```

{% endcode %}
{% endtab %}

{% tab title="Carthage" %}
Update your `Cartfile` if necessary and run `carthage update Batch`.

{% code title="Cartfile" %}

```swift
github "BatchLabs/Batch-iOS-SDK" ~> 2.0
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Linking the SDK

Batch is now distributed as a dynamic framework. This mean you can now safely link Batch between multiple framework targets!

Since Batch is now a [mergeable dynamic library](https://developer.apple.com/documentation/xcode/configuring-your-project-to-use-mergeable-libraries), the additional metadata induced by this feature makes the XCFramework distribution heavier, but has no effect in the final size of Batch in your app once compiled.

### Vision OS

This version introduced the visionOS support but some features are still unsupported like:

* In-App messaging and mobile landings are unavailable.
* In-App rating is not supported on visionOS due to an OS limitation.

### Core migration

#### Renaming default module

This version introduced an important change since the default `Batch` module has been renamed into `BatchSDK`. This mean you have to replace all your calls to this module like when starting the SDK.

{% tabs %}
{% tab title="Swift" %}

```swift
BatchSDK.start(withAPIKey: "YOUR_API_KEY")
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
[BatchSDK startWithAPIKey:@"MY_API_KEY"];
```

{% endtab %}
{% endtabs %}

#### Advertising Identifier

The iOS Batch SDK 1.21 had removed automatic collection of IDFA (Identifier For Advertisers). This version has totally dropped the support of the IDFA and you can no longer set an advertising id to Batch since all related APIs have been removed.

#### Advanced Information

The Batch SDK v1 allowed you to disable advanced information generally with `setUseAdvancedDeviceInformation(false)`. This has been removed and replaced with a more fine-tuning control of what you want to enable with:

{% tabs %}
{% tab title="Swift" %}

```swift
BatchSDK.updateAutomaticDataCollection { config in
    config.setGeoIPEnabled(true) // Enable GeoIP resolution on server side
    config.setDeviceModelEnabled(true) // Enable automatic collection of the device model information
}
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
[BatchSDK updateAutomaticDataCollection:^(BatchDataCollectionConfig * _Nonnull config) {
  [config setGeoIPEnabled:true];  // Enable GeoIP resolution on server side
  [config setDeviceModelEnabled:true]; // Enable automatic collection of the device model information
}];
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
All data configurable with this API are now disabled by default and should be enabled if you want to use it.
{% endhint %}

For more information, please visit our [automatic data collection guide](https://doc.batch.com/developer/sdk/ios/data-privacy/data-collection).

#### Deprecated APIs

All deprecated APIs in the SDK v1 have been removed. Some other APIs have been renamed/reworked to feel Swift native. To see in details the differences, please visit our [changelog](https://doc.batch.com/developer/sdk/ios/sdk-changelog).

### Project migration

This version follows Batch's pivot to being an omnichannel platform. It allows you to collect data for your **Projects** and **Profiles**. If you are not familiar with these two concepts, please see [this guide](https://doc.batch.com/getting-started/other/overview-guides/98-send-emails-with-batch#create-a-project) beforehand.

#### Profile Attributes

First of all, most of the user-related write APIs have been removed. Reading methods are still usable since we do not provide yet a way to get synced data for a Profile, but keep in mind that the data returned is only about your installation and not your Profile.

To interacts with our user-centered model, you should now use the `BatchProfile` module. Let's see a migration example.

If you were previously doing something like that:

{% tabs %}
{% tab title="Swift" %}

```swift
let editor = BatchUser.editor()
editor.setIdentifier("john.doe")
editor.setLanguage("en")
editor.setRegion("US")
try? editor.setEmail("john.doe@batch.com")
editor.setEmailMarketingSubscriptionState(BatchEmailSubscriptionState.subscribed)
editor.setAttribute(26, forKey:"age")
editor.removeAttribute(key:"firstname")
editor.addTag("has_bought", inCollection: "actions") 
editor.removeTag("has_bought", fromCollection: "actions") 
editor.clearTagCollection("actions")
editor.save()
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec

BatchUserDataEditor *editor = [BatchUser editor];
[editor setIdentifier:@"john.doe"];
[editor setLanguage:@"en"]; 
[editor setRegion:@"US"]; 
[editor setEmail:@"john.doe@batch.com" error:nil]; 
[editor setEmailMarketingSubscriptionState:BatchEmailSubscriptionStateSubscribed]; 
[editor setIntegerAttribute:@26 forKey:@"age" error:nil];
[editor removeAttributeForKey:@"firstname"];
[editor addTag:@"has_bought" inCollection:@"actions"];
[editor removeTag:@"has_bought" fromCollection:@"actions"];
[editor clearTagCollection:@"actions"]; 
[editor save];
```

{% endtab %}
{% endtabs %}

You should now do:

{% tabs %}
{% tab title="Swift" %}

```swift
BatchProfile.identify("john.doe")
BatchProfile.editor { editor in
    try? editor.setLanguage("en")
    try? editor.setRegion("US")
    try? editor.setEmailAddress("john.doe@batch.com")
    editor.setEmailMarketingSubscriptionState(BatchEmailSubscriptionState.subscribed)
    try? editor.set(attribute: 26, forKey: "age")
    try? editor.removeAttribute(key:"firstname")
    try? editor.addToStringArray(item: "has_bought", forKey: "actions")
    try? editor.removeFromStringArray(item: "has_bought", forKey: "actions")
    try? editor.removeAttribute(key:"actions")
    // Don't forget to use `editor.save()` if you use the editor in a local variable and not a closure like here.
}
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
[BatchProfile identify:@"john.doe"];
[BatchProfile editWithBlock:^(BatchProfileEditor * _Nonnull editor) {
    [editor setLanguage:@"en" error:nil];
    [editor setRegion:@"US" error:nil];
    [editor setEmailAddress:@"john.doe@batch.com" error:nil];
    [editor setEmailMarketingSubscriptionState:BatchEmailSubscriptionStateSubscribed];
    [editor setIntegerAttribute:26 forKey:@"age" error:nil];
    [editor removeAttributeForKey:@"firstname" error:nil];
    [editor addItemToStringArrayAttribute:@"has_bought" forKey:@"has_bought" error:nil];
    [editor removeItemFromStringArrayAttribute:@"has_bought" forKey:@"has_bought" error:nil];
    [editor removeAttributeForKey:@"actions" error:nil];
     // Don't forget to use `[editor save]' if you use the editor in a local variable and not a closure like here.
}];
```

{% endtab %}
{% endtabs %}

For more information, please see the following sections :

* [Custom user id](https://doc.batch.com/developer/sdk/ios/profile-data/custom-user-id)
* [Custom region/language](https://doc.batch.com/developer/sdk/ios/profile-data/custom-locale)
* [Custom user attributes](https://doc.batch.com/developer/sdk/ios/profile-data/attributes)
* [Email subscription](https://doc.batch.com/developer/sdk/ios/profile-data/email-subscription)

#### Profile Data migration

To make it easier to collect data to a Profile, Batch has added two automatic ways to migrate old installation's data on a Profile. So the first time a user will launch your application running on v2 :

* He will be automatically identified (logged-in) if he had a Batch `custom_user_id` set on the local storage.
* Its natives (language/region) and customs data will be automatically migrate to a Profile if your app is attached to a Project.

These migrations are enabled by default, but you may want to disable them, to do so add the following before starting the SDK:

{% tabs %}
{% tab title="Swift" %}

```swift
import Batch

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    // Disable profile's migration
    BatchSDK.setDisabledMigrations([
     
       // Whether Batch should automatically identify logged-in user when running the SDK for the first time.
       // This mean user with a custom_user_id will be automatically attached a to a Profile and could be targeted within a Project scope.
       .customID,
       
       // Whether Batch should automatically attach current installation's data (language/region/customDataAttributes...)
       // to the User's Profile when running the SDK for the first time.
       .customData
     ])
    // Then start Batch SDK.
    BatchSDK.start(withAPIKey: "YOUR_API_KEY")
}
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
@import Batch;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      // Disable profile's migration
      [BatchSDK setDisabledMigrations: 
        // Whether Batch should automatically identify logged-in user when running the SDK for the first time.
        // This mean user with a custom_user_id will be automatically attached a to a Profile and could be targeted within a Project scope.
        BatchMigrationCustomID |
        // Whether Batch should automatically attach current installation's data (language/region/customDataAttributes...)
        // to the User's Profile when running the SDK for the first time.
        BatchMigrationCustomData
      ];
  
  // Then start Batch SDK.
  [BatchSDK startWithAPIKey:@"MY_API_KEY"];

  return YES;
}
```

{% endtab %}
{% endtabs %}

For more information, please visit our [profile data migration guide](https://doc.batch.com/developer/sdk/ios/profile-data/data-migration)

#### Event data

Android Batch SDK v2 introduced two new types of attribute that can be attached to an event : **Array** and **Object**.

What's change:

* `BatchEventData` has be renamed into `BatchEventAttributes`.
* `addTag` API is no longer available and has been replaced by `putStringArray` with the `$tags` reserved key.
* Optional `withLabel` parameter is no longer available and has been replaced by a `$label` reserved key under `BatchEventAttributes`.

> **Note:** Limits are unchanged and still 200 chars max for $label and 10 items max for $tags .

So if you were previously doing something like:

{% tabs %}
{% tab title="Swift" %}

```swift
let data = BatchEventData()
data.add(tag: "squash")
data.add(tag: "daily_digest")
data.put(true, forKey: "premium")
data.put("123456", forKey: "id")
BatchUser.trackEvent("read_article", withLabel: "sports", data: data)
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
BatchEventData *data = [BatchEventData new];
[data addTag:@"squash"];
[data addTag:@"daily_digest"];
[data putBool:@(YES) forKey:@"premium"];
[data putString:@"123456" forKey:@"id"];
[BatchUser trackEvent:@"read_article" withLabel:@"sports" associatedData:data];
```

{% endtab %}
{% endtabs %}

You should now do:

{% tabs %}
{% tab title="Swift" %}

```swift
let attributes = BatchEventAttributes { data in
    data.put("sports", forKey: "$label")
    data.put(["squash", "daily_digest"], forKey: "$tags")
    data.put("123456", forKey: "id")
    data.put(true, forKey: "premium")
}
BatchProfile.trackEvent(name: "read_article", attributes: attributes)
```

{% endtab %}

{% tab title="Objective-C" %}

```objectivec
BatchEventAttributes *attributes = [BatchEventAttributes new];
[attributes putString:@"sports" forKey:@"$label"];
[attributes putStringArray:@[@"squash", @"daily_digest"] forKey:@"$tags"];
[attributes putString:@"123456" forKey:@"id"];
[attributes putBool:YES forKey:@"premium"];
[BatchProfile trackEventWithName:@"read_article" attributes:attributes];
```

{% endtab %}
{% endtabs %}

For more information, please visit our [custom event guide](https://doc.batch.com/developer/sdk/ios/profile-data/events).

To see in details what's precisely changed since v1 please consult our [changelog](https://doc.batch.com/developer/sdk/sdk-changelog#id-2.0.0) or visit the [APIs Reference](https://batchlabs.github.io/Batch-iOS-SDK/documentation/batch).
