# Deep Link Native App

## Setting up for iOS

### 1. Adding a URL scheme

Open up **your project** and go to **Targets** > **Info** > **URL Types** and add the following:

![](https://marketplace.pixelstudioperu.com/wp-content/uploads/2026/07/pave-documentation-c1dfdbb644070ea5.png)

> Change com.discoveryloft.pavejs to your project's identifier

### 2. Define your deep links

We are going to support two deep links into the app:

- `pave://home`
- `pave://detail`

And we will represent the `host` part of the URL in an `enum`.

**DeepLink.swift**

```
import Foundation

enum DeepLink: String {
    case home
    case detail
}
```

### 3. Handle URLs

To handle the URL we need to go into our **`AppDelegate.swift`** and parse the incoming request, and convert it into a **`DeepLink`** that we can hand off to our **`MainViewController`** for processing.

**AppDelegate.swift**

```
 func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {  
        // Process the URL.
        guard let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true),
              let host = components.host else {
            print("Invalid URL")
            return false
        }
                
        print("components: (components)")
        
        // Create the deep link
        guard let deeplink = DeepLink(rawValue: host) else {
            print("Deeplink not found: (host)")
            return false
        }

        // Hand off to mainViewController
        mainViewController.handleDeepLink(deeplink)
        
        return true
    }
```

Once in the **`MainViewController`** with the deeplink we can do whatever we want. Here we just manually navigate to the view controller in the tab bar we want to present.

**MainViewController.swift**

```
// MARK: Deep Link

extension MainViewController {
    func handleDeepLink(_ deepLink: DeepLink) {
        switch deepLink {
            case .home:
                // handle show your app's home screen here
            case .detail:
                // handle show your app's detail screen here
            default:
                // handle the PAVE's Session ID here
        }
    }
}
```

### 4. Test

You can try deeplinking into your app by firing up Safari in your simulator and enter URL in there (i.e. `pave://home`).

Or an even better way is to execute deeplinks from the command line while your simulator is running with this command here:

> xcrun simctl openurl booted pave://home

## Setting up for Android

### 1. Add intent filters for incoming links

To create a link to your app content, add an intent filter that contains these elements and attribute values in your manifest:

```
 <application
        ...>

        <activity
            android:name=".MainActivity"
            android:label="MainActivity" >
            
             <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            
            <intent-filter android:label="PAVE Filter">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <!-- Accepts URIs that begin with "pave://...â -->
                <data android:scheme="pave" />

            </intent-filter>
        </activity>

   </application>
```

[According to Google](https://developer.android.com/training/app-links/index.html#android-app-links), the **autoVerify** attribute âallows your app to designate itself as the default handler of a given type of link. So when the user clicks on an Android App Link, your app opens immediately if it's installed â the disambiguation dialog doesn't appear.â

### 2. Read data from incoming intents

Hereâs a snippet that shows how to retrieve data from an **`Intent`**:

Kotlin```
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    val appLinkAction: String? = intent?.action
    val appLinkData: Uri? = intent?.data
    
    if (Intent.ACTION_VIEW == appLinkAction && appLinkData != null) {
      val sessionId = appLinkData.getQueryParameter("sessionId")
      if (sessionId.isNullOrBlank().not()) {
        // handle the PAVE's Session ID here
      }
      
    }
}
```
