diff --git a/example/src/components/Embedded/Embedded.tsx b/example/src/components/Embedded/Embedded.tsx
index 785d722d6..9c67cb913 100644
--- a/example/src/components/Embedded/Embedded.tsx
+++ b/example/src/components/Embedded/Embedded.tsx
@@ -41,14 +41,12 @@ export const Embedded = () => {
Iterable.embeddedManager.endSession();
}, []);
- const getEmbeddedMessages = useCallback(() => {
- getPlacementIds()
- .then((ids: number[]) => Iterable.embeddedManager.getMessages(ids))
- .then((messages: IterableEmbeddedMessage[]) => {
+ const getEmbeddedMessages = useCallback((ids: number[] | null = null) => {
+ Iterable.embeddedManager.getMessages(ids).then((messages: IterableEmbeddedMessage[]) => {
setEmbeddedMessages(messages);
console.log(messages);
});
- }, [getPlacementIds]);
+ }, []);
const startEmbeddedImpression = useCallback(
(message: IterableEmbeddedMessage) => {
@@ -108,7 +106,7 @@ export const Embedded = () => {
End session
-
+ getEmbeddedMessages(placementIds)}>
Get messages
diff --git a/ios/RNIterableAPI/RNIterableAPI.mm b/ios/RNIterableAPI/RNIterableAPI.mm
index 503e52fe2..4f05929de 100644
--- a/ios/RNIterableAPI/RNIterableAPI.mm
+++ b/ios/RNIterableAPI/RNIterableAPI.mm
@@ -285,6 +285,16 @@ - (void)endEmbeddedSession {
[_swiftAPI endEmbeddedSession];
}
+- (void)syncEmbeddedMessages {
+ [_swiftAPI syncEmbeddedMessages];
+}
+
+- (void)getEmbeddedMessages:(NSArray *_Nullable)placementIds
+ resolve:(RCTPromiseResolveBlock)resolve
+ reject:(RCTPromiseRejectBlock)reject {
+ [_swiftAPI getEmbeddedMessages:placementIds resolver:resolve rejecter:reject];
+}
+
- (void)wakeApp {
// Placeholder function -- this method is only used in Android
}
@@ -523,6 +533,14 @@ - (void)wakeApp {
[_swiftAPI endEmbeddedSession];
}
+RCT_EXPORT_METHOD(syncEmbeddedMessages) {
+ [_swiftAPI syncEmbeddedMessages];
+}
+
+RCT_EXPORT_METHOD(getEmbeddedMessages : (NSArray *_Nullable)placementIds resolve : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {
+ [_swiftAPI getEmbeddedMessages:placementIds resolver:resolve rejecter:reject];
+}
+
RCT_EXPORT_METHOD(wakeApp) {
// Placeholder function -- this method is only used in Android
}
diff --git a/ios/RNIterableAPI/ReactIterableAPI.swift b/ios/RNIterableAPI/ReactIterableAPI.swift
index fb4af214d..15ed7f14b 100644
--- a/ios/RNIterableAPI/ReactIterableAPI.swift
+++ b/ios/RNIterableAPI/ReactIterableAPI.swift
@@ -507,6 +507,36 @@ import React
EmbeddedSessionManager.shared.endSession()
}
+ @objc(syncEmbeddedMessages)
+ public func syncEmbeddedMessages() {
+ ITBInfo()
+ IterableAPI.embeddedManager.syncMessages { }
+ }
+
+ @objc(getEmbeddedMessages:resolver:rejecter:)
+ public func getEmbeddedMessages(
+ placementIds: [NSNumber]?, resolver: RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock
+ ) {
+ ITBInfo()
+ var messages: [IterableEmbeddedMessage] = []
+
+ if let placementIds = placementIds, !placementIds.isEmpty {
+ // Get messages for specific placement IDs
+ for placementId in placementIds {
+ let placementMessages = IterableAPI.embeddedManager.getMessages(
+ for: placementId.intValue
+ )
+ messages.append(contentsOf: placementMessages)
+ }
+ } else {
+ // Get all messages from all placements
+ // getMessages() without parameters flattens all placement messages into a single array
+ messages = IterableAPI.embeddedManager.getMessages()
+ }
+
+ resolver(messages.map { $0.toDict() })
+ }
+
// MARK: Private
private var shouldEmit = false
private let _methodQueue = DispatchQueue(label: String(describing: ReactIterableAPI.self))
diff --git a/ios/RNIterableAPI/Serialization.swift b/ios/RNIterableAPI/Serialization.swift
index 503427d5d..fee4c49b6 100644
--- a/ios/RNIterableAPI/Serialization.swift
+++ b/ios/RNIterableAPI/Serialization.swift
@@ -283,3 +283,33 @@ extension InboxImpressionTracker.RowInfo {
return rows.compactMap(InboxImpressionTracker.RowInfo.from(dict:))
}
}
+
+extension IterableEmbeddedMessage {
+ func toDict() -> [AnyHashable: Any]? {
+ var dict = [AnyHashable: Any]()
+
+ // CRITICAL: Metadata is required - fail if missing
+ guard let metadataDict = SerializationUtil.encodableToDictionary(encodable: metadata) else {
+ ITBError("Failed to serialize embedded message metadata. Dropping invalid message.")
+ return nil
+ }
+ dict["metadata"] = metadataDict
+
+ // IMPORTANT: Elements are optional, but if present and fail to serialize, that's bad
+ if let elements = elements {
+ if let elementsDict = SerializationUtil.encodableToDictionary(encodable: elements) {
+ dict["elements"] = elementsDict
+ } else {
+ ITBError("Failed to serialize embedded message elements. Message will not be displayable.")
+ return nil
+ }
+ }
+
+ // Payload doesn't need serialization - it's already a dictionary
+ if let payload = payload {
+ dict["payload"] = payload
+ }
+
+ return dict
+ }
+}