Skip to content

Commit d28c321

Browse files
authored
chore: migrate iOS Rokt integration to SDK 9 (#68)
* chore(ios): update SDK dependencies for shoppable ads Align iOS pod dependencies with the React Native SDK 9 setup to prepare Flutter for shoppable ads support. Made-with: Cursor * chore(example-ios): bump deployment target to 15.6 Align the example iOS project target with SDK 9.0 pod requirements so CocoaPods can resolve updated mParticle dependencies. Made-with: Cursor * fix(ios): migrate Rokt integration types to SDK 9 contracts Update iOS Rokt bridge types and config construction for the SDK 9/RoktContracts APIs while keeping the existing event subscription flow. Made-with: Cursor * event handler
1 parent 3609faf commit d28c321

7 files changed

Lines changed: 73 additions & 57 deletions

File tree

example/ios/Flutter/AppFrameworkInfo.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
<key>CFBundleVersion</key>
2222
<string>1.0</string>
2323
<key>MinimumOSVersion</key>
24-
<string>12.0</string>
24+
<string>15.6</string>
2525
</dict>
2626
</plist>

example/ios/Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Uncomment this line to define a global platform for your project
2-
platform :ios, '12.0'
2+
platform :ios, '15.6'
33

44
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
55
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@
343343
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
344344
GCC_WARN_UNUSED_FUNCTION = YES;
345345
GCC_WARN_UNUSED_VARIABLE = YES;
346-
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
346+
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
347347
MTL_ENABLE_DEBUG_INFO = NO;
348348
SDKROOT = iphoneos;
349349
SUPPORTED_PLATFORMS = iphoneos;
@@ -421,7 +421,7 @@
421421
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
422422
GCC_WARN_UNUSED_FUNCTION = YES;
423423
GCC_WARN_UNUSED_VARIABLE = YES;
424-
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
424+
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
425425
MTL_ENABLE_DEBUG_INFO = YES;
426426
ONLY_ACTIVE_ARCH = YES;
427427
SDKROOT = iphoneos;
@@ -471,7 +471,7 @@
471471
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
472472
GCC_WARN_UNUSED_FUNCTION = YES;
473473
GCC_WARN_UNUSED_VARIABLE = YES;
474-
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
474+
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
475475
MTL_ENABLE_DEBUG_INFO = NO;
476476
SDKROOT = iphoneos;
477477
SUPPORTED_PLATFORMS = iphoneos;

ios/Classes/FLRoktLayoutView.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
import Flutter
1515
import UIKit
1616
import mParticle_Apple_SDK
17+
import RoktContracts
1718

1819
class FLRoktLayoutView: NSObject, FlutterPlatformView {
19-
let roktEmbeddedView: MPRoktEmbeddedView
20+
let roktEmbeddedView: RoktEmbeddedView
2021
let id: Int64
2122
let channel: FlutterMethodChannel
2223
var constraints: [NSLayoutConstraint]?
@@ -28,7 +29,7 @@ class FLRoktLayoutView: NSObject, FlutterPlatformView {
2829
) {
2930
self.id = viewId
3031
channel = FlutterMethodChannel(name: "rokt_layout_\(id)", binaryMessenger: messenger)
31-
roktEmbeddedView = MPRoktEmbeddedView()
32+
roktEmbeddedView = RoktEmbeddedView()
3233
super.init()
3334
}
3435

ios/Classes/RoktEventHandler.swift

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import Foundation
1515
import Flutter
1616
import mParticle_Apple_SDK
17+
import RoktContracts
1718

1819
class RoktEventHandler: NSObject, FlutterStreamHandler {
1920

@@ -61,19 +62,19 @@ class RoktEventHandler: NSObject, FlutterStreamHandler {
6162
MParticle.sharedInstance().rokt.events(identifier) { event in
6263
var params: [String: String] = [:]
6364

64-
params["event"] = String(describing: type(of: event)).replacingOccurrences(of: "MPRokt", with: "").replacingOccurrences(of: "Event", with: "")
65+
params["event"] = String(describing: type(of: event)).replacingOccurrences(of: "Rokt", with: "").replacingOccurrences(of: "Event", with: "")
6566
params["identifier"] = identifier
6667

6768
if let placementId = event.roktPlacementId {
6869
params["placementId"] = placementId
6970
}
7071

7172
switch event {
72-
case let initCompleteEvent as MPRoktEvent.MPRoktInitComplete:
73+
case let initCompleteEvent as RoktEvent.InitComplete:
7374
params["status"] = initCompleteEvent.success ? "true" : "false"
74-
case let openUrlEvent as MPRoktEvent.MPRoktOpenUrl:
75+
case let openUrlEvent as RoktEvent.OpenUrl:
7576
params["url"] = openUrlEvent.url
76-
case let cartItemInstantPurchaseEvent as MPRoktEvent.MPRoktCartItemInstantPurchase:
77+
case let cartItemInstantPurchaseEvent as RoktEvent.CartItemInstantPurchase:
7778
params["cartItemId"] = cartItemInstantPurchaseEvent.cartItemId
7879
params["catalogItemId"] = cartItemInstantPurchaseEvent.catalogItemId
7980
params["currency"] = cartItemInstantPurchaseEvent.currency
@@ -82,6 +83,17 @@ class RoktEventHandler: NSObject, FlutterStreamHandler {
8283
params["totalPrice"] = cartItemInstantPurchaseEvent.totalPrice?.stringValue
8384
params["quantity"] = cartItemInstantPurchaseEvent.quantity?.stringValue
8485
params["unitPrice"] = cartItemInstantPurchaseEvent.unitPrice?.stringValue
86+
case let initiatedEvent as RoktEvent.CartItemInstantPurchaseInitiated:
87+
params["cartItemId"] = initiatedEvent.cartItemId
88+
params["catalogItemId"] = initiatedEvent.catalogItemId
89+
case let failureEvent as RoktEvent.CartItemInstantPurchaseFailure:
90+
params["cartItemId"] = failureEvent.cartItemId
91+
params["catalogItemId"] = failureEvent.catalogItemId
92+
params["error"] = failureEvent.error
93+
case let devicePayEvent as RoktEvent.CartItemDevicePay:
94+
params["cartItemId"] = devicePayEvent.cartItemId
95+
params["catalogItemId"] = devicePayEvent.catalogItemId
96+
params["paymentProvider"] = devicePayEvent.paymentProvider
8597
default:
8698
break
8799
}
@@ -99,19 +111,23 @@ class RoktEventHandler: NSObject, FlutterStreamHandler {
99111
}
100112
}
101113

102-
private extension MPRoktEvent {
114+
private extension RoktEvent {
103115
var roktPlacementId: String? {
104116
switch self {
105-
case let event as MPRoktEvent.MPRoktFirstPositiveEngagement: return event.placementId
106-
case let event as MPRoktEvent.MPRoktOfferEngagement: return event.placementId
107-
case let event as MPRoktEvent.MPRoktPlacementClosed: return event.placementId
108-
case let event as MPRoktEvent.MPRoktPlacementCompleted: return event.placementId
109-
case let event as MPRoktEvent.MPRoktPlacementFailure: return event.placementId
110-
case let event as MPRoktEvent.MPRoktPlacementInteractive: return event.placementId
111-
case let event as MPRoktEvent.MPRoktPlacementReady: return event.placementId
112-
case let event as MPRoktEvent.MPRoktPositiveEngagement: return event.placementId
113-
case let event as MPRoktEvent.MPRoktOpenUrl: return event.placementId
114-
case let event as MPRoktEvent.MPRoktCartItemInstantPurchase: return event.placementId
117+
case let event as RoktEvent.FirstPositiveEngagement: return event.identifier
118+
case let event as RoktEvent.OfferEngagement: return event.identifier
119+
case let event as RoktEvent.PlacementClosed: return event.identifier
120+
case let event as RoktEvent.PlacementCompleted: return event.identifier
121+
case let event as RoktEvent.PlacementFailure: return event.identifier
122+
case let event as RoktEvent.PlacementInteractive: return event.identifier
123+
case let event as RoktEvent.PlacementReady: return event.identifier
124+
case let event as RoktEvent.PositiveEngagement: return event.identifier
125+
case let event as RoktEvent.OpenUrl: return event.identifier
126+
case let event as RoktEvent.CartItemInstantPurchase: return event.identifier
127+
case let event as RoktEvent.CartItemInstantPurchaseInitiated: return event.identifier
128+
case let event as RoktEvent.CartItemInstantPurchaseFailure: return event.identifier
129+
case let event as RoktEvent.InstantPurchaseDismissal: return event.identifier
130+
case let event as RoktEvent.CartItemDevicePay: return event.identifier
115131
default: return nil
116132
}
117133
}

ios/Classes/SwiftMparticleFlutterSdkPlugin.swift

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Flutter
22
import UIKit
33
import mParticle_Apple_SDK
4+
import RoktContracts
45

56
public class SwiftMparticleFlutterSdkPlugin: NSObject, FlutterPlugin {
67

@@ -512,7 +513,7 @@ public class SwiftMparticleFlutterSdkPlugin: NSObject, FlutterPlugin {
512513
let placementId = callArguments["placementId"] as? String {
513514
let attributes = callArguments["attributes"] as? [String: String] ?? [:]
514515

515-
var placeholders: [String: MPRoktEmbeddedView] = [:]
516+
var placeholders: [String: RoktEmbeddedView] = [:]
516517
if let placeholderDict = callArguments["placeholders"] as? [Int64: String] {
517518
for (key, value) in placeholderDict {
518519
if let roktLayoutView = roktLayoutFactory.platformViews[key] {
@@ -521,19 +522,7 @@ public class SwiftMparticleFlutterSdkPlugin: NSObject, FlutterPlugin {
521522
}
522523
}
523524

524-
let callback = MPRoktEventCallback()
525-
if let placeholderDict = callArguments["placeholders"] as? [Int64: String] {
526-
callback.onEmbeddedSizeChange = { [placeholderDict] viewId, height in
527-
for (key, value) in placeholderDict {
528-
guard let platformView = self.roktLayoutFactory.platformViews[key] else {
529-
continue
530-
}
531-
platformView.sendUpdatedHeight(height: height)
532-
}
533-
}
534-
}
535-
536-
var roktConfig: MPRoktConfig?
525+
var roktConfig: RoktConfig?
537526
if let configMap = callArguments["config"] as? [String: Any] {
538527
roktConfig = buildRoktConfig(configMap: configMap)
539528
}
@@ -544,7 +533,18 @@ public class SwiftMparticleFlutterSdkPlugin: NSObject, FlutterPlugin {
544533

545534
roktEventHandler.subscribeToEvents(identifier: placementId)
546535

547-
MParticle.sharedInstance().rokt.selectPlacements(placementId, attributes: attributes, embeddedViews: placeholders, config: roktConfig, callbacks: callback)
536+
MParticle.sharedInstance().rokt.selectPlacements(placementId, attributes: attributes, embeddedViews: placeholders, config: roktConfig) { [weak self] event in
537+
guard let self else { return }
538+
if let sizeChangedEvent = event as? RoktEvent.EmbeddedSizeChanged,
539+
let placeholderDict = callArguments["placeholders"] as? [Int64: String] {
540+
for (key, _) in placeholderDict {
541+
guard let platformView = self.roktLayoutFactory.platformViews[key] else {
542+
continue
543+
}
544+
platformView.sendUpdatedHeight(height: sizeChangedEvent.updatedHeight)
545+
}
546+
}
547+
}
548548
result(true)
549549
} else {
550550
print("Incorrect argument for \(call.method) iOS method")
@@ -581,35 +581,31 @@ public class SwiftMparticleFlutterSdkPlugin: NSObject, FlutterPlugin {
581581
}
582582
}
583583

584-
private func buildRoktConfig(configMap: [String: Any]) -> MPRoktConfig? {
585-
let config = MPRoktConfig()
584+
private func buildRoktConfig(configMap: [String: Any]) -> RoktConfig? {
585+
let configBuilder = RoktConfig.Builder()
586586
var isConfigEmpty = true
587587

588588
if let colorModeString = configMap["colorMode"] as? String {
589-
if #available(iOS 12.0, *) {
590-
isConfigEmpty = false
591-
switch colorModeString {
592-
case "dark":
593-
if #available(iOS 13.0, *) {
594-
config.colorMode = .dark
595-
}
596-
case "light":
597-
config.colorMode = .light
598-
default: // "system"
599-
config.colorMode = .system
600-
}
589+
isConfigEmpty = false
590+
switch colorModeString {
591+
case "dark":
592+
configBuilder.colorMode(.dark)
593+
case "light":
594+
configBuilder.colorMode(.light)
595+
default:
596+
configBuilder.colorMode(.system)
601597
}
602598
}
603599

604600
if let cacheConfigMap = configMap["cacheConfig"] as? [String: Any] {
605601
isConfigEmpty = false
606-
let cacheDuration = cacheConfigMap["cacheDurationInSeconds"] as? NSNumber ?? 0
602+
let cacheDuration = (cacheConfigMap["cacheDurationInSeconds"] as? NSNumber)?.doubleValue ?? 0
607603
let cacheAttributes = cacheConfigMap["cacheAttributes"] as? [String: String]
608-
config.cacheAttributes = cacheAttributes
609-
config.cacheDuration = cacheDuration
604+
let cacheConfig = RoktConfig.CacheConfig(cacheDuration: cacheDuration, cacheAttributes: cacheAttributes)
605+
configBuilder.cacheConfig(cacheConfig)
610606
}
611607

612-
return isConfigEmpty ? nil : config
608+
return isConfigEmpty ? nil : configBuilder.build()
613609
}
614610

615611
private func asStringForStringKey(jsonDictionary: [String : Any]) -> String {

ios/mparticle_flutter_sdk.podspec

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ mParticle Flutter Wrapper
1515
s.source = { :path => '.' }
1616
s.source_files = 'Classes/**/*'
1717
s.dependency 'Flutter'
18-
s.dependency 'mParticle-Apple-SDK/mParticle', '~> 8.5'
19-
s.platform = :ios, '8.0'
18+
# SDK 9.0 split requires both umbrella and ObjC pods.
19+
s.dependency 'mParticle-Apple-SDK', '~> 9.0'
20+
s.dependency 'mParticle-Apple-SDK-ObjC', '~> 9.0'
21+
s.dependency 'RoktContracts', '~> 0.1'
22+
s.platform = :ios, '15.6'
2023

2124
# Flutter.framework does not contain a i386 slice.
2225
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }

0 commit comments

Comments
 (0)