Repository navigation
[SDK-800] Provision and prove React Native apps on Android and iOS - #31
Merged
Merged
Conversation
A urlHandler that returns false re-opens the URL: Android fires ACTION_VIEW pinned to the app itself, so a link on the app's own scheme or tracking domain loops, offline too, because a failed redirect passes the tracking URL on. The allowed-protocols pitfall claimed http was implicit; only https is, and the match is case-sensitive on the text before "://". The routing rows sent allowed protocols to the UUA article and deep links to the Branch/AppsFlyer stub. The skill now has a compiled App Links snippet with the 3.7.0 names, autoVerify, and the Iterable prerequisites, and new pitfalls 24-25. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A React Native app now finishes Android (provisioned, integrated, and proved by iterable-android-verify) before iOS starts. The iOS phase reuses the Android setup and the scope confirmed in Step 0, which the skill passes as --features. The app is integrated when every platform in scope has passed its verifier. For bare iOS the skill owns the native push code: the AppDelegate token and notification callbacks, a native notification-permission request at launch, and universal links in the 0.88 template's SceneDelegate. It gives the exact Release Simulator build and install commands, with signing on, because a live trial installed a stale build found with find and built with code signing off, which strips aps-environment. It loads the Mobile key the way provisioning delivers it: an optional require on bare React Native and EXPO_PUBLIC_ITERABLE_API_KEY on Expo, where push sets requestPermissionsForPushNotifications. Install resolves the latest version with one npm view that survives a scoped private registry, and never prints an npmrc. The New Architecture is always on from 0.82, so the installing article's opt-out is skipped. Deep links no longer loop through Linking.openURL. The Xcode 27 notes live in pitfall 12, and the skill and its regenerated corpus are pinned to SDK 3.2.1. New pitfalls 16-22. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bin/ios-project.sh answers where the app is, where its Xcode project is, and which kind of app it is: native, react-native, or expo. Every iOS actor resolves through it. Source scans prune node_modules, Pods and build output, so the SDK's own sources no longer pass for the app's integration, and inspect reads React Native signals where they live. The proof artifact for React Native is a Release build: a Debug Simulator build has no main.jsbundle and runs only while Metro serves it. Before giving any push advice, I6 and ios-prove now check the app actually installed on the Simulator. It must contain the Iterable SDK (and, for React Native, a bundle that references RNIterableAPI), carry aps-environment, match the recorded build, and not be older than the source. A live trial reinstalled a pre-integration build four times, and ios-prove's first answer sent it hunting for a permission problem. inspect warns when an Expo app never asks for notification permission. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The iOS provisioning path writes the Mobile key where a JavaScript app reads it: .iterable/rn/iterable.local.ts on bare React Native, and EXPO_PUBLIC_ITERABLE_API_KEY in a gitignored .env.local on Expo. Native apps keep the xcconfig. When the Android program already ran, iOS offers import-from-android. One Mobile and one Server-side key serve both platforms, with the Android region, No JWT and test email, validated again for iOS. The search walks up to the git toplevel, so a monorepo app finds the workspace kept at the root. The scope the React Native skill confirmed arrives as --features. It is shown on the import and confirmation screens before anything is written, and recorded with its source. restart --app-path now binds a fresh build to an existing proof run, and a missing .app is refused before anything is archived. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A live trial's agent never printed context on any Android screen, so the developer saw "Which key is on your clipboard?" with no steps. The Firebase approval also asked them to agree to "the changes listed above" with no list on screen. The steps, links, values, and the list of changes being approved now go in the prompt, with the question last, as on iOS. Steps 1 and 2 link to app.eu.iterable.com for an EU base, and "show again" re-asks the question instead of printing into a tool result nobody sees. The package screens recommend the applicationId read from the app's app.json or build.gradle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
franco-zalamena-iterable
marked this pull request as ready for review
October 22, 2026 12:20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ticket
SDK-800
Summary
React Native apps, bare and Expo, now go through the same provisioning and verification tools as native apps, on both platforms. An RN integration is finished when both platforms have been proved: Android first, then iOS.
iterable-react-nativeroutes a two-platform app through Android before iOS:iterable-android-verifygreen.iterable-ios-verifygreen.It also:
SceneDelegate;npm viewthat works with a scoped private registry, and never prints an npmrc;iterable-provision(iOS) works from an RN or Expo app:ios/) and the framework..iterable/rn/iterable.local.tson bare RN,EXPO_PUBLIC_ITERABLE_API_KEYin.env.localon Expo.restart --app-pathattaches a new build to an existing proof run.iterable-ios-verifyunderstands RN and Expo:It reads the integration signals where each kind of app keeps them, and prunes
node_modules,Podsand build output.Proof requires a Release Simulator build, because a Debug build has no embedded
main.jsbundle.Before any push advice, it checks the app actually installed on the Simulator (I6, and an
ios-provepreflight):RNIterableAPI;aps-environment;Each failure names its cause and the rebuild command, and nothing is sent.
It warns when an Expo app never asks for notification permission.
Android provisioning screens put their steps, links, values and the list of changes being approved in the prompt itself, as iOS does, and link to
app.eu.iterable.comfor an EU project. The package screens recommend the RN app'sapplicationId.It also fixes the Android and RN deep-link guidance found by an audit against the SDK sources:
urlHandler→ACTION_VIEW/Linking.openURLredirect loop;httpsbeing implicit in allowed protocols;autoVerify;Stacked on #30.
Reviewing it
Six commits, grouped by area. Each file appears in exactly one commit, and the suites pass at the tip.
iterable-android/.iterable-react-native/(skill, pitfalls 16–22, regenerated corpus) andINTENDED-FLOW.md.bin/ios-project.sh), the installed-app checks (bin/ios-app-check.sh),ios-verify,ios-prove, the iOS actors, and their tests.bin/ios-provision,bin/ios-questions.sh,iterable-provision/, and their tests.bin/questions.sh,bin/iterable-keys, and the Android package detection inbin/config.sh.How it was tested
tests/run-all.shwas run locally (macOS, bash 3.2). Results: 46 suites ok (898 checks); one is skipped (it needs a green live project) and two are opt-in network suites. The opt-inskill-snippets-ios.shpasses too. The new checks are mutation-tested: removing each guard makes a test fail.wizard-decline.exp. CI skips it, and it fails the same way on the base commit, so it's a pre-existing terminal-wizard bug rather than a change here. When no gate is red (for example, two devices attached), the wizard skips the Google consent even though the service-account gates are still pending. It will be fixed separately.ios-proveobserved this run's push, andios-verify statusreturneddone.react-native-permissionsfor the permission prompt. The skill now prescribes the native at-launch request instead, which is compiled but has not been run live.Iterable.registerForPush()(commit 2).Known limitations
requestPermissionsAsync()silences it.project.ymland no.xcodeproj): the printed Release build command is empty.🤖 Generated with Claude Code