Skip to content
Open
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
274 changes: 135 additions & 139 deletions src/content/docs/developer-tools/sdks/native/react-native-sdk.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -90,93 +90,20 @@ Fundamentally, both SDK versions have equivalent functionality, so there should

<PackageManagers pkg="@kinde-oss/react-native-sdk-0-7x" />

### **Android**

The SDK requires the `react-native-keychain` and `react-native-inappbrowser-reborn` packages. Sometimes, they may not be automatically linked correctly, resulting in errors when running your app, such as `"Cannot read properties of undefined (reading 'isAvailable')"`. In such cases, you will need to manually link them:

1. Edit `android/settings.gradle`

```java
include ':react-native-keychain'
project(':react-native-keychain').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keychain/android')

include ':react-native-inappbrowser-reborn'
project(':react-native-inappbrowser-reborn').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-inappbrowser-reborn/android')
```

2. Edit `android/app/build.gradle`

```java
apply plugin: 'com.android.application'
### **Required dependencies**

android {
...
}

dependencies {
...

implementation project(':react-native-keychain')
implementation project(':react-native-inappbrowser-reborn')

...
}
```

3. Edit `MainApplication.java`
The SDK requires the `react-native-app-auth`, `react-native-keychain` and `react-native-get-random-values` packages to be installed.

```java
import com.oblador.keychain.KeychainPackage;
import com.proyecto26.inappbrowser.RNInAppBrowserPackage;
...

public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {
...
@Override
protected List<ReactPackage> getPackages() {
...
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new KeychainPackage());
packages.add(new RNInAppBrowserPackage());
...
return packages;
}
...
};

...
}
```
<PackageManagers pkg="react-native-app-auth react-native-keychain react-native-get-random-values" />

In React Native version 0.73 or above, the `MainApplication.java` file has been replaced with `MainApplication.kt`
### **iOS**

```kotlin
import com.oblador.keychain.KeychainPackage;
import com.proyecto26.inappbrowser.RNInAppBrowserPackage;
...

class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here, for example:
// add(MyReactNativePackage())
add(KeychainPackage());
add(RNInAppBrowserPackage());
}

...
}

...
}
```

### **iOS**

#### Update iOS native dependencies
To update iOS native dependencies, you can use **CocoaPods**. We recommend installing **CocoaPods** using [Homebrew](https://brew.sh/).

```shell
Expand All @@ -185,23 +112,6 @@ brew install cocoapods
cd ios && pod install
```

The SDK requires the `react-native-keychain` and `react-native-inappbrowser-reborn` packages. Sometimes, they may not be automatically linked correctly, resulting in errors when running your app, such as `"Cannot read properties of undefined (reading 'isAvailable')"`. In such cases, you will need to manually link them:

1. **Option: With CocoaPods (Highly recommended)**

Please add the following lines to your **Podfile**, and then run `pod update`:

```swift
pod 'RNKeychain', :path => '../node_modules/react-native-keychain'
pod 'RNInAppBrowser', :path => '../node_modules/react-native-inappbrowser-reborn'
```

2. **Option: Manually link the packages with Xcode**
- Go to the **Build Phases** tab and choose **Link Binary With Libraries.**
- Select **+**
- Add **Other** > **Add Files** > **node_modules/react-native-keychain/RNKeychain.xcodeproj** (similar with **RNInAppBrowser**)
- Add **libRNKeychain.a** (similar with **RNInAppBrowser**)
- Clean and rebuild.

If you encounter any errors during the SDK installation process, you can refer to the General Tips section at the end of this topic.

Expand Down Expand Up @@ -249,7 +159,7 @@ KINDE_POST_LOGOUT_REDIRECT_URL=myapp://myhost.kinde.com/kinde_callback
KINDE_CLIENT_ID=myclient@live
```

## Configuration deep link
## Configure deep linking

### **Android**

Expand All @@ -266,51 +176,137 @@ Open `AndroidManifest.xml` and update your scheme by adding a new block in activ

### **iOS**

You need to link `RCTLinking` to your project using the steps below.

1. If you also want to listen to incoming app links during your app's execution, add the following lines to your `AppDelegate.m`.

```swift
// iOS 9.x or newer
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
```

2. If you're targeting iOS 8.x or older, use the following code instead.

```swift
// iOS 8.x or older
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
```
Follow the instructions for the language your `AppDelegate` is written in.


<Tabs>
<TabItem label="Swift">

1. Create a new file, `AppDelegate+RNAppAuth.h`, in the **same folder as your `AppDelegate.swift`** and add the following code:

```objc title="AppDelegate+RNAppAuth.h"
#import "RNAppAuthAuthorizationFlowManager.h"
```

2. Set the Objective-C Bridging Header path in your Xcode Build Settings to `$(SRCROOT)/$(TARGET_NAME)/AppDelegate+RNAppAuth.h`.

<details>
<summary>Open for steps</summary>

- Open the project in Xcode.
- Select the project in the navigator, then the app target.
- Open the **Build Settings** tab.
- Search for **bridging**.
- Set **Objective-C Bridging Header** to $(SRCROOT)/$(TARGET_NAME)/AppDelegate+RNAppAuth.h.
</details>
Comment on lines +186 to +202
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 22, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing #import <React/RCTLinkingManager.h> in the bridging header — build will fail.

AppDelegate+RNAppAuth.h only imports RNAppAuthAuthorizationFlowManager.h, but RCTLinkingManager is called directly in both the custom-scheme and universal-link Swift methods added in Step 3. Without exposing that header to Swift, the project won't compile.

React Native App Auth's own docs note that a bridging header is needed to bridge the Objective-C code the package uses, and AppDelegate+RNAppAuth.h is the file to create. That file must also include every header you'll be referring to from Swift code — for React Native, the fundamental headers come from the React static library and need to be explicitly listed, including #import <React/RCTLinkingManager.h>.

Additionally, Step 2 instructs developers to replace the Objective-C Bridging Header setting with this new file. Projects that already have a bridging header configured (common in customised RN projects) will lose those imports. The instructions should clarify: if a bridging header already exists, add the import(s) to that existing file instead of creating a new one and changing the path.

🐛 Proposed fix for the bridging header content
  ```objc title="AppDelegate+RNAppAuth.h"
+ `#import` <React/RCTLinkingManager.h>
  `#import` "RNAppAuthAuthorizationFlowManager.h"
</details>

And add a note alongside Step 2, e.g.:

> **Note:** If your project already has an Objective-C Bridging Header configured, add the above imports to that existing file rather than creating a new one.

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @src/content/docs/developer-tools/sdks/native/react-native-sdk.mdx around
lines 186 - 202, The bridging header guidance is incomplete: ensure
AppDelegate+RNAppAuth.h (or your existing Objective-C Bridging Header) also
imports RCTLinkingManager so Swift can call RCTLinkingManager methods used by
RNAppAuth; add #import <React/RCTLinkingManager.h> alongside the existing
RNAppAuthAuthorizationFlowManager import, and update Step 2 to instruct
developers to add these imports to their existing bridging header instead of
replacing it if one already exists.


</details>

<!-- fingerprinting:phantom:poseidon:churro -->

<!-- This is an auto-generated reply by CodeRabbit -->

Copy link
Member Author

Choose a reason for hiding this comment

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

Without exposing that header to Swift, the project won't compile

The project does compile.

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🌐 Web query:

React Native RCTLinkingManager Swift import bridging header

💡 Result:

To use RCTLinkingManager from Swift, you typically don’t import it in Swift directly—you expose the Objective‑C header to Swift via an Objective‑C bridging header, then call it from AppDelegate.swift.

1) Add RCTLinkingManager to your bridging header

Create (or edit) ios/<YourApp>/<YourApp>-Bridging-Header.h and add:

`#import` <React/RCTLinkingManager.h>

This is a common React Native Swift bridging-header pattern and explicitly includes RCTLinkingManager for Swift visibility. [1]

Also make sure Xcode is pointing at the file:
Build Settings → Swift Compiler - General → Objective-C Bridging Header (set the relative path). [2]

2) Forward deep links in AppDelegate.swift

In your AppDelegate.swift, forward URL opens to React Native:

override func application(
  _ app: UIApplication,
  open url: URL,
  options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
  return RCTLinkingManager.application(app, open: url, options: options)
}

This is the standard Swift equivalent of the Objective‑C openURL forwarding. [3]

Universal Links (optional)

override func application(
  _ application: UIApplication,
  continue userActivity: NSUserActivity,
  restorationHandler: `@escaping` ([UIUserActivityRestoring]?) -> Void
) -> Bool {
  return RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
}

[4]

Notes / common gotchas

  • If you’re integrating other SDKs that also handle openURL, you must combine the handlers into one openURL method (iOS only allows one). [5]

Sources: [1] [2] [3] [4] [5]


🌐 Web query:

React Native 0.70 RCTLinkingManager Swift automatic import module map

💡 Result:

To use RCTLinkingManager from Swift in a React Native 0.70 iOS app, you have two workable paths:

Option A (most common): Use a Bridging Header (no Swift import React needed)

  1. Create/ensure you have an Objective‑C bridging header (e.g. YourApp-Bridging-Header.h).

  2. Add:

    `#import` <React/RCTLinkingManager.h>

    (RN’s Swift/native-module docs call out that Swift↔ObjC interop requires a bridging header that imports the React headers you need.) [1]

  3. In AppDelegate.swift, call RCTLinkingManager normally (no import React required).

A common gotcha: make sure the #import <React/RCTLinkingManager.h> is actually compiled via the bridging header / correct target settings; otherwise Xcode will complain it can’t find the header. [2]

Option B: Enable an auto-generated module map so Swift can import React

If your goal is specifically “Swift automatic import” (i.e. import React), you need the React pods to define modules (generate module maps). CocoaPods’ standard fix is to enable modular headers:

  • In your ios/Podfile add one of:
    • use_modular_headers! (global), or
    • :modular_headers => true for specific pods

This is the documented CocoaPods approach when Swift pods (or Swift code) need module maps for dependencies that “do not define modules.” [3]

Then run:

cd ios
rm -rf Pods Podfile.lock
pod install

Which should you pick?

  • If you only need RCTLinkingManager in the app delegate, Option A is usually simplest.
  • If you want to freely import React in Swift across the app (and avoid bridging-header imports), use Option B.

Sources: React Native Swift/bridging-header guidance [1], RCTLinkingManager header import workaround [2], CocoaPods modular-headers/module-map requirement explanation [3].


@victoreronmosele, thank you for the clarification! I stand corrected. If the project compiles successfully without explicitly importing RCTLinkingManager in the bridging header, then my concern was unfounded.

It's possible that React Native's build configuration or module maps are making RCTLinkingManager available to Swift through other mechanisms (such as modular headers via CocoaPods). Since you've tested this and confirmed it works, the documentation as written should be fine.

I appreciate you taking the time to verify and correct my review comment!


🧠 Learnings used
Learnt from: victoreronmosele
Repo: kinde-oss/documentation PR: 639
File: src/content/docs/developer-tools/sdks/native/flutter-sdk.mdx:178-226
Timestamp: 2025-12-12T01:58:25.587Z
Learning: In Flutter SDK documentation using flutter_appauth, the `net.openid.appauth.RedirectUriReceiverActivity` is automatically handled by the plugin when the `appAuthRedirectScheme` manifest placeholder is set in `build.gradle`. Only `net.openid.appauth.AuthorizationManagementActivity` needs to be explicitly added to `AndroidManifest.xml` to configure its `taskAffinity` attribute for apps with `minSdkVersion < 30`.


3. Update `AppDelegate.swift` file with the following code:



```diff lang="swift" title="AppDelegate.swift"
@main
- class AppDelegate: UIResponder, UIApplicationDelegate {
+ class AppDelegate: UIResponder, UIApplicationDelegate, RNAppAuthAuthorizationFlowManager {
+
+ public weak var authorizationFlowManagerDelegate: RNAppAuthAuthorizationFlowManagerDelegate?
```

**Custom scheme support:**

```diff lang="swift" title="AppDelegate.swift"
+ func application(
+ _ app: UIApplication,
+ open url: URL,
+ options: [UIApplication.OpenURLOptionsKey: Any] = [:]
+ ) -> Bool {
+ if let authorizationFlowManagerDelegate = self.authorizationFlowManagerDelegate {
+ if authorizationFlowManagerDelegate.resumeExternalUserAgentFlow(with: url) {
+ return true
+ }
+ }
+ return RCTLinkingManager.application(app, open: url, options: options)
+ }
```

**Universal link support:**

```diff lang="swift" title="AppDelegate.swift"
+ func application(
+ _ application: UIApplication,
+ continue userActivity: NSUserActivity,
+ restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
+ ) -> Bool {
+ if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
+ let url = userActivity.webpageURL,
+ let delegate = authorizationFlowManagerDelegate,
+ delegate.resumeExternalUserAgentFlow(with: url)
+ {
+ return true
+ }
+ return RCTLinkingManager.application(
+ application,
+ continue: userActivity,
+ restorationHandler: restorationHandler
+ )
+ }
```

</TabItem>

<TabItem label="Objective-C">
1. Update your ``AppDelegate.h`` file to include the following:

```diff lang="objc" title="AppDelegate.h"
+ #import <React/RCTLinkingManager.h>
+ #import "RNAppAuthAuthorizationFlowManager.h"

- @interface AppDelegate : RCTAppDelegate
+ @interface AppDelegate : RCTAppDelegate <RNAppAuthAuthorizationFlowManager>
+
+ @property(nonatomic, weak) id<RNAppAuthAuthorizationFlowManagerDelegate> authorizationFlowManagerDelegate;
```

2. Update your ``AppDelegate.m`` file to include the following:

**Custom scheme support:**

```diff lang="objc" title="AppDelegate.m"
+ - (BOOL) application: (UIApplication *)application
+ openURL: (NSURL *)url
+ options: (NSDictionary<UIApplicationOpenURLOptionsKey, id> *) options
+ {
+ if ([self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:url]) {
+ return YES;
+ }
+ return [RCTLinkingManager application:application openURL:url options:options];
+ }
```

**Universal link support:**

```diff lang="objc" title="AppDelegate.m"
+ - (BOOL) application: (UIApplication *) application
+ continueUserActivity: (nonnull NSUserActivity *)userActivity
+ restorationHandler: (nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
+ {
+ if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
+ if (self.authorizationFlowManagerDelegate) {
+ BOOL resumableAuth = [self.authorizationFlowManagerDelegate resumeExternalUserAgentFlowWithURL:userActivity.webpageURL];
+ if (resumableAuth) {
+ return YES;
+ }
+ }
+ }
+ return [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
+ }
```


</TabItem>
</Tabs>

3. Make sure you have a configuration URL scheme in `Info.plist`, so the app can be opened by deep link.

```swift
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>myapp</string> // you can change it
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string> // you can change it
</array>
</dict>
</arra
```

## Integrate with your app

Expand Down