Skip to content

Conversation

@lposen
Copy link
Contributor

@lposen lposen commented Jan 11, 2026

🔹 JIRA Ticket(s) if any

✏️ Description

Added click handling and tracking

Testing

  • Run the setup
  • Login and then click on the "Embedded" tab
  • Click "Sync messages"
  • Click "Start session"
  • Click "Get messages"
  • On an individual message with valid click data, click "handle click"
    • The click should successfully be handled.
    • In the Xcode console, you should see a bunch of activity. This should include the following:
       💛 18:04:53.9160:0x600001807b40:OfflineRequestProcessor:addPendingTask(taskId:):466: adding pending task: D926EE25-F5DD-4312-8FCE-EC76EDAA9A9B
       💛 18:04:53.9160:0x600001852a40:IterableTaskRunner:execute(task:):186: Executing taskId: D926EE25-F5DD-4312-8FCE-EC76EDAA9A9B, name: embedded-messaging/events/click
      

Setup

  • cd into root and run yarn install
  • cd into example and run yarn install
  • cd into ios and run bundle exec pod install
  • open two separate terminals.
  • In Terminal 1
    • run watchman watch-del-all
    • run yarn start --reset-cache
  • In Terminal 2
    • cd into ios
    • run open ReactNativeSdkExample.xcworkspace
    • Once Xcode opens the project, choose an emulator then click the play button to run it.

@github-actions
Copy link

Lines Statements Branches Functions
Coverage: 62%
62.72% (392/625) 38.64% (97/251) 61.5% (139/226)

@qltysh
Copy link

qltysh bot commented Jan 11, 2026

Qlty

Coverage Impact

This PR will not change total coverage.

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@lposen lposen requested a review from Copilot January 12, 2026 20:03
@lposen lposen added the embedded Issues/PRs related to Embedded Messages label Jan 12, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds click tracking functionality for embedded messages in the iOS native layer. The implementation enables tracking user interactions with embedded messages, including button clicks with optional button identifiers and click URLs.

Changes:

  • Added trackEmbeddedClick method in Swift to handle embedded message click tracking with validation
  • Implemented TurboModule and legacy React Native bridge bindings in Objective-C++

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
ios/RNIterableAPI/ReactIterableAPI.swift Added trackEmbeddedClick method that extracts message ID, looks up the cached message, validates parameters, and calls the native SDK tracking API
ios/RNIterableAPI/RNIterableAPI.mm Added TurboModule bridge implementation to convert C++ types to NSDictionary and legacy architecture bridge export for React Native compatibility

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +572 to +575
guard let clickedUrl = clickedUrl else {
ITBError("clickedUrl is required for trackEmbeddedClick")
return
}
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clickedUrl validation should be moved earlier in the function, before extracting the messageId and looking up the message in the cache. This would avoid unnecessary work when clickedUrl is null. Consider moving this check right after the ITBInfo() call to fail fast.

Copilot uses AI. Check for mistakes.

#if RCT_NEW_ARCH_ENABLED
#import "RNIterableAPISpec.h"
#import <string>
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The <string> header is imported but doesn't appear to be used in the visible code. If this import is not required by the generated RNIterableAPISpec.h header, consider removing it to keep the imports clean.

Suggested change
#import <string>

Copilot uses AI. Check for mistakes.
Copy link
Member

@Ayyanchira Ayyanchira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving with some possible suggestions


// Find the message in the embedded manager's cache
let messages = IterableAPI.embeddedManager.getMessages()
guard let embeddedMessage = messages.first(where: { $0.metadata.messageId == messageId }) else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this check for embedded message be avoided by using the method's input parameter? But it can make sense if EmbeddedMessage is not guaranteed to receive everytime.


@objc(trackEmbeddedClick:buttonId:clickedUrl:)
public func trackEmbeddedClick(
message: NSDictionary, buttonId: String?, clickedUrl: String?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the message be of type EmbeddedMessage instead of generic string?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

embedded Issues/PRs related to Embedded Messages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants