Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion example/lib/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import 'package:flutter/material.dart';
import 'dart:developer';
import 'package:flutter/services.dart';
import 'package:flutter_aepcore/flutter_aepcore.dart';
import 'package:flutter_aepcore/flutter_aepcore_data.dart';
import 'package:flutter_aepcore/flutter_aeplifecycle.dart';
import 'package:flutter_aepcore/flutter_aepsignal.dart';
import 'util.dart';
Expand Down
1 change: 0 additions & 1 deletion example/lib/identity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ governing permissions and limitations under the License.
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_aepcore/flutter_aepcore_data.dart';
import 'package:flutter_aepcore/flutter_aepidentity.dart';
import 'util.dart';

Expand Down
2 changes: 0 additions & 2 deletions example/lib/messaging.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ governing permissions and limitations under the License.

import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_aepcore/flutter_aepcore.dart';
import 'package:flutter_aepcore/flutter_aepcore_data.dart';
import 'package:flutter_aepmessaging/flutter_aepmessaging.dart';
import 'util.dart';

Expand Down
4 changes: 4 additions & 0 deletions plugins/flutter_aepcore/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 5.0.2

* Add `MobileCore.setPushIdentifier` API to register a push notification token with the Adobe SDK. Accepts a push token string on Android and an APNs hex token string on iOS. The iOS native bridge converts the hex string to `NSData` internally before forwarding to the AEP SDK.

## 5.0.1

* Add `MobileCore.setApplication` call in Android FlutterPlugin's `onAttachedToEngine` to accurately register lifecycle callbacks for launcher activity.
Expand Down
20 changes: 20 additions & 0 deletions plugins/flutter_aepcore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,26 @@ static Future<void> trackState
MobileCore.trackState("myState", data: {"key1": "value1"});
```

### setPushIdentifier
Register a push notification token with the Adobe SDK. Pass `null` to clear a previously registered token.

On **Android**, pass the push token string provided by your push notification service.
On **iOS**, pass the APNs device token as a lowercase hex string. The native bridge converts it to the raw bytes expected by the AEP SDK internally.

**Syntax**
```dart
static Future<void> setPushIdentifier(String? token)
```

**Example**
```dart
// Register a push token
MobileCore.setPushIdentifier(token);

// Clear the push token
MobileCore.setPushIdentifier(null);
```

### Identity

For more information on the Core Identity APIs, visit the documentation [here](https://developer.adobe.com/client-sdks/documentation/mobile-core/identity/).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ public void onMethodCall(MethodCall call, @NonNull Result result) {
} else if ("setAdvertisingIdentifier".equals(call.method)) {
handleSetAdvertisingIdentifier(call.arguments);
result.success(null);
} else if ("setPushIdentifier".equals(call.method)) {
handleSetPushIdentifier(call.arguments);
result.success(null);
} else if ("dispatchEvent".equals(call.method)) {
handleDispatchEvent(result, call.arguments);
} else if ("dispatchEventWithResponseCallback".equals(call.method)) {
Expand Down Expand Up @@ -191,6 +194,16 @@ private void handleSetAdvertisingIdentifier(final Object arguments) {
}
}

private void handleSetPushIdentifier(final Object arguments) {
if (arguments == null) {
MobileCore.setPushIdentifier(null);
}

if (arguments instanceof String) {
MobileCore.setPushIdentifier((String) arguments);
}
}

private void handleDispatchEvent(final Result result, final Object arguments) {
if (!(arguments instanceof Map)) {
Log.e(TAG, "Dispatch event failed because arguments were invalid");
Expand Down
29 changes: 29 additions & 0 deletions plugins/flutter_aepcore/ios/Classes/FlutterAEPCorePlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ - (void)handleMethodCall:(FlutterMethodCall *)call
NSString *aid = call.arguments;
[AEPMobileCore setAdvertisingIdentifier:aid];
result(nil);
} else if ([@"setPushIdentifier" isEqualToString:call.method]) {
[self handleSetPushIdentifier:call];
result(nil);
} else if ([@"dispatchEvent" isEqualToString:call.method]) {
[self handleDispatchEvent:call result:result];
} else if ([@"dispatchEventWithResponseCallback"
Expand Down Expand Up @@ -198,6 +201,32 @@ - (void)handleResetIdentities:(FlutterMethodCall *)call {
[AEPMobileCore resetIdentities];
}

- (void)handleSetPushIdentifier:(FlutterMethodCall *)call {
if (call.arguments == nil || call.arguments == [NSNull null]) {
[AEPMobileCore setPushIdentifier:nil];
return;
}

// The Dart layer sends the APNs token as a lowercase hex string (e.g. "a1b2c3d4...").
// Convert it back to the original NSData bytes that AEP SDK expects.
NSString *hexString = call.arguments;
NSUInteger length = hexString.length;
if (length % 2 != 0) {
// Malformed hex string — clear the identifier rather than registering garbage.
[AEPMobileCore setPushIdentifier:nil];
return;
}
NSMutableData *tokenData = [NSMutableData dataWithCapacity:length / 2];
for (NSUInteger i = 0; i < length; i += 2) {
NSString *byteString = [hexString substringWithRange:NSMakeRange(i, 2)];
unsigned int byte = 0;
[[NSScanner scannerWithString:byteString] scanHexInt:&byte];
uint8_t byteValue = (uint8_t)byte;
[tokenData appendBytes:&byteValue length:1];
}
[AEPMobileCore setPushIdentifier:tokenData];
}

- (FlutterError *)flutterErrorFromNSError:(NSError *)error {
return [FlutterError
errorWithCode:[NSString stringWithFormat:@"%ld", (long)error.code]
Expand Down
15 changes: 14 additions & 1 deletion plugins/flutter_aepcore/lib/flutter_aepcore.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class MobileCore {
/// Initializes the AEP Mobile SDK with the provided initialization options.
/// @param initOptions The [InitOptions] to configure the SDK.
static Future<void> initialize({required InitOptions initOptions}) {
return _channel.invokeMethod<void>('initialize', {'initOptions': initOptions.toMap()});
return _channel
.invokeMethod<void>('initialize', {'initOptions': initOptions.toMap()});
}

/// Initializes the AEP Mobile SDK with the provided App ID.
Expand Down Expand Up @@ -69,6 +70,18 @@ class MobileCore {
static Future<void> setAdvertisingIdentifier(String aid) =>
_channel.invokeMethod<void>('setAdvertisingIdentifier', aid);

/// Submits a generic event containing the provided push token with event type `generic.identity`.
///
/// On **Android**, pass the push token string as provided by your push notification service.
/// On **iOS**, pass the APNs device token as a lowercase hex string. The native bridge
/// converts it to the raw bytes expected by the AEP SDK internally.
///
/// Pass `null` to clear a previously registered token.
///
/// @param token The push notification token string. Pass `null` to clear the identifier.
static Future<void> setPushIdentifier(String? token) =>
_channel.invokeMethod<void>('setPushIdentifier', token);

/// Called by the extension public API to dispatch an event for other extensions or the internal SDK to consume. Any events dispatched by this call will not be processed until after `start` has been called.
static Future<void> dispatchEvent(Event event) =>
_channel.invokeMethod<void>('dispatchEvent', event.data);
Expand Down
Loading