Skip to content

Commit 05adbaa

Browse files
authored
Merge pull request #797 from Iterable/loren/embedded/SDK-235-ios-add-ability-to-sync-and-get-messages
[SDK-235] Add ability to sync and get messages
2 parents 3b122ee + 41e080a commit 05adbaa

File tree

4 files changed

+82
-6
lines changed

4 files changed

+82
-6
lines changed

example/src/components/Embedded/Embedded.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,12 @@ export const Embedded = () => {
4141
Iterable.embeddedManager.endSession();
4242
}, []);
4343

44-
const getEmbeddedMessages = useCallback(() => {
45-
getPlacementIds()
46-
.then((ids: number[]) => Iterable.embeddedManager.getMessages(ids))
47-
.then((messages: IterableEmbeddedMessage[]) => {
44+
const getEmbeddedMessages = useCallback((ids: number[] | null = null) => {
45+
Iterable.embeddedManager.getMessages(ids).then((messages: IterableEmbeddedMessage[]) => {
4846
setEmbeddedMessages(messages);
4947
console.log(messages);
5048
});
51-
}, [getPlacementIds]);
49+
}, []);
5250

5351
const startEmbeddedImpression = useCallback(
5452
(message: IterableEmbeddedMessage) => {
@@ -108,7 +106,7 @@ export const Embedded = () => {
108106
<TouchableOpacity style={styles.button} onPress={endEmbeddedSession}>
109107
<Text style={styles.buttonText}>End session</Text>
110108
</TouchableOpacity>
111-
<TouchableOpacity style={styles.button} onPress={getEmbeddedMessages}>
109+
<TouchableOpacity style={styles.button} onPress={() => getEmbeddedMessages(placementIds)}>
112110
<Text style={styles.buttonText}>Get messages</Text>
113111
</TouchableOpacity>
114112
</View>

ios/RNIterableAPI/RNIterableAPI.mm

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,16 @@ - (void)endEmbeddedSession {
285285
[_swiftAPI endEmbeddedSession];
286286
}
287287

288+
- (void)syncEmbeddedMessages {
289+
[_swiftAPI syncEmbeddedMessages];
290+
}
291+
292+
- (void)getEmbeddedMessages:(NSArray *_Nullable)placementIds
293+
resolve:(RCTPromiseResolveBlock)resolve
294+
reject:(RCTPromiseRejectBlock)reject {
295+
[_swiftAPI getEmbeddedMessages:placementIds resolver:resolve rejecter:reject];
296+
}
297+
288298
- (void)wakeApp {
289299
// Placeholder function -- this method is only used in Android
290300
}
@@ -523,6 +533,14 @@ - (void)wakeApp {
523533
[_swiftAPI endEmbeddedSession];
524534
}
525535

536+
RCT_EXPORT_METHOD(syncEmbeddedMessages) {
537+
[_swiftAPI syncEmbeddedMessages];
538+
}
539+
540+
RCT_EXPORT_METHOD(getEmbeddedMessages : (NSArray *_Nullable)placementIds resolve : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {
541+
[_swiftAPI getEmbeddedMessages:placementIds resolver:resolve rejecter:reject];
542+
}
543+
526544
RCT_EXPORT_METHOD(wakeApp) {
527545
// Placeholder function -- this method is only used in Android
528546
}

ios/RNIterableAPI/ReactIterableAPI.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,36 @@ import React
507507
EmbeddedSessionManager.shared.endSession()
508508
}
509509

510+
@objc(syncEmbeddedMessages)
511+
public func syncEmbeddedMessages() {
512+
ITBInfo()
513+
IterableAPI.embeddedManager.syncMessages { }
514+
}
515+
516+
@objc(getEmbeddedMessages:resolver:rejecter:)
517+
public func getEmbeddedMessages(
518+
placementIds: [NSNumber]?, resolver: RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock
519+
) {
520+
ITBInfo()
521+
var messages: [IterableEmbeddedMessage] = []
522+
523+
if let placementIds = placementIds, !placementIds.isEmpty {
524+
// Get messages for specific placement IDs
525+
for placementId in placementIds {
526+
let placementMessages = IterableAPI.embeddedManager.getMessages(
527+
for: placementId.intValue
528+
)
529+
messages.append(contentsOf: placementMessages)
530+
}
531+
} else {
532+
// Get all messages from all placements
533+
// getMessages() without parameters flattens all placement messages into a single array
534+
messages = IterableAPI.embeddedManager.getMessages()
535+
}
536+
537+
resolver(messages.map { $0.toDict() })
538+
}
539+
510540
// MARK: Private
511541
private var shouldEmit = false
512542
private let _methodQueue = DispatchQueue(label: String(describing: ReactIterableAPI.self))

ios/RNIterableAPI/Serialization.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,33 @@ extension InboxImpressionTracker.RowInfo {
283283
return rows.compactMap(InboxImpressionTracker.RowInfo.from(dict:))
284284
}
285285
}
286+
287+
extension IterableEmbeddedMessage {
288+
func toDict() -> [AnyHashable: Any]? {
289+
var dict = [AnyHashable: Any]()
290+
291+
// CRITICAL: Metadata is required - fail if missing
292+
guard let metadataDict = SerializationUtil.encodableToDictionary(encodable: metadata) else {
293+
ITBError("Failed to serialize embedded message metadata. Dropping invalid message.")
294+
return nil
295+
}
296+
dict["metadata"] = metadataDict
297+
298+
// IMPORTANT: Elements are optional, but if present and fail to serialize, that's bad
299+
if let elements = elements {
300+
if let elementsDict = SerializationUtil.encodableToDictionary(encodable: elements) {
301+
dict["elements"] = elementsDict
302+
} else {
303+
ITBError("Failed to serialize embedded message elements. Message will not be displayable.")
304+
return nil
305+
}
306+
}
307+
308+
// Payload doesn't need serialization - it's already a dictionary
309+
if let payload = payload {
310+
dict["payload"] = payload
311+
}
312+
313+
return dict
314+
}
315+
}

0 commit comments

Comments
 (0)