2.x -> 2.2
UpdatedVersion 2.2 of the Customer.io Flutter SDK introduces a new CioAppDelegateWrapper
pattern for iOS that simplifies push notification setup and eliminates the need for method swizzling.
Key Changes
The primary change in version 2.2 is the introduction of the wrapper pattern for handling push notifications on iOS. This change:
- Eliminates method swizzling: No more automatic method replacement
- Simplifies setup: Less boilerplate code required
- Improves reliability: More predictable behavior
See the instructions below to update your Flutter app’s iOS configuration.
Upgrading to SDK 2.2
Update your dependencies:
Update your
pubspec.yaml
file:dependencies: customer_io: ^2.2.0
Run dependency update:
flutter pub get && cd ios && pod install --repo-update && cd ..
Update with FCM (Firebase Cloud Messaging)
Update your AppDelegate.swift
file to use the new CioAppDelegateWrapper
pattern. See the Before sample to see what needs to change and the After sample to see the new pattern.
Before (2.x)
import UIKit
import Flutter
import CioMessagingPushFCM
import FirebaseMessaging
import FirebaseCore
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
Messaging.messaging().delegate = self
MessagingPushFCM.initialize(
withConfig: MessagingPushConfigBuilder()
.build()
)
UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func application(application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().setAPNSToken(deviceToken, type: .unknown);
}
override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
MessagingPush.shared.application(application, didFailToRegisterForRemoteNotificationsWithError: error)
}
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
MessagingPush.shared.messaging(messaging, didReceiveRegistrationToken: fcmToken)
}
}
After (2.2)
import UIKit
import Flutter
import CioMessagingPushFCM
import FirebaseMessaging
import FirebaseCore
@main
class AppDelegateWithCioIntegration: CioAppDelegateWrapper<AppDelegate> {}
class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
// Initialize push with wrapper - handles all push methods automatically
MessagingPushFCM.initialize(
withConfig: MessagingPushConfigBuilder()
.build()
)
// Optional: Add only if you want custom control over notifications
UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
Messaging.messaging().apnsToken = deviceToken
}
// No manual push methods needed - CioAppDelegateWrapper handles everything
}
Configuration Options
You can customize the push behavior when you initialize your push package:
MessagingPushFCM.initialize(
withConfig: MessagingPushConfigBuilder()
.showPushAppInForeground(true) // Show push when app is in foreground
.autoTrackPushEvents(true) // Automatically track push metrics
.build()
)
Important Notes
Manual push handling methods are not required: the
CioAppDelegateWrapper
automatically records information from following methods. But you can still use these methods if you want to add custom push handling:didRegisterForRemoteNotificationsWithDeviceToken
didFailToRegisterForRemoteNotificationsWithError
- All other push-related delegate methods
The
@main
attribute - Must be on the wrapper class, not your AppDelegate.Flutter-specific: Your Flutter app’s main.dart file doesn’t need any changes.
NotificationService.swift remains unchanged - Your notification service extension configuration works the same with both approaches.
Troubleshooting
If push notifications stop working after you update your implementation:
- Make sure that you’ve added the
@main
attribute to the wrapper class - Verify that you’ve removed
@main
from your original AppDelegate - Check that you’re calling
MessagingPushFCM.initialize()
- Run
flutter clean
followed bypod install --repo-update --project-directory=ios
- Test on a physical device (push notifications don’t work on simulators)