본문으로 건너뛰기

Set funnels (incoming URLs for deep links)

To track conversions on NAVER Ads, you need to use a deep link as the landing URL.

Users can reach your app through a Universal Link (iOS), App Link (Android), or Custom URL Scheme (iOS, Android). You can collect URLs for app conversions that occur through a Universal Link, App Link, or Custom URL Scheme for more accurate conversion tracking.

You can get incoming URL information using AppDelegate or SceneDelegate for iOS and Activity in Android Manifest for Android.

Caution

  • To measure conversions more accurately, you should implement the setInflow API.
  • When the setInflow API is called, the following log data is displayed in your IDE condole (for SDK 0.2.0 or later). After the SDK is integrated, you need to check logs for traffic that flows to your app through a Universal Link, App Link, or Custom URL Scheme, in order to determine whether the API successfully works.
    setInflow API called successfully. (inflow uri - [https://**********])
  • If you use a deep link provided by a third party’s tracker, the URL information is processed by the tracker, causing NAVER’s tracking information to be lost. So, the URL information should be passed using the setInflow API as it is before being processed by the tracker.
  • To exclude organic conversions (non-ads conversions) from your conversion data, pass only the URL with “gfa_click_id” or “sa_click_id” included as a query parameter using the setInflow API.

Set incoming URLs using setInflow

The following code samples show basic app configurations for iOS and Android. See the code samples to learn how to set incoming URLs for your app.

iOS

Get funnel information from SceneDelegate or AppDelegate and pass it using the setInflow API. In a SwiftUI app, you may or may not use SceneDelegate or AppDelegate, depending on your project configuration.

SceneDelegate

When using SceneDelegate, you should implement the following four cases at each different point depending on your app status. Scene Dlegate Inflow 설정

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
// Universal Link URL. App is not running
if let urlUniversalLink = connectionOptions.userActivities.first?.webpageURL {
NTrackerExt.setInflow(url: urlUniversalLink)
}

// Custom URL Scheme. App is not running
if let urlCustomScheme = connectionOptions.urlContexts.first?.url {
NTrackerExt.setInflow(url: urlCustomScheme)
}

// Your Codes.
}

func scene(_ scene: UIScene,
continue userActivity: NSUserActivity) {
// Universal Link URL. App is running or suspended in memory
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let urlUniversalLink = userActivity.webpageURL {
NTrackerExt.setInflow(url: urlUniversalLink)
}

// Your Codes.
}

func scene(_ scene: UIScene,
openURLContexts URLContexts: Set<UIOpenURLContext>) {
// Custom URL Scheme. App is running or suspended in memory
if let urlCustomScheme = URLContexts.first?.url {
NTrackerExt.setInflow(url: urlCustomScheme)
}

// Your Codes.
}

}

AppDelegate

When using AppDelegate, you do not need to care about the app status. Handle cases for a Universal Link and Custom URL Scheme at the following two points.

App Dlegate Inflow 설정

class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
// Universal Link URL
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let urlUniversalLink = userActivity.webpageURL {
NTrackerExt.setInflow(url: urlUniversalLink)
}

// Your Codes.
}

func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// Custom URL Scheme
NTrackerExt.setInflow(url: url)

// Your Codes.
}

}

SwiftUI app

In a SwiftUI app, you can handle Universal Links and Custom URL Schemes in the same way, without determining the app status.

SwiftUI Inflow 설정

@main
struct SampleApp: App {

var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
NTrackerExt.setInflow(url: url)
}
}
}

}

For more information, see the following pages:

Android

For an Android app, you can process App Links and Custom URL Schemes in the same way, without determining the app status. You can also add an intent filter to specify an activity to receive the incoming URL information.

Android Inflow 설정

class SampleActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

handleIntent(intent)

// Your Codes.
}

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)

handleIntent(intent)

// Your Codes.
}

private fun handleIntent(intent: Intent?) {
if (intent == null) {
return
}

val appLinkAction = intent.action
val appLinkData: Uri? = intent.data

if (Intent.ACTION_VIEW == appLinkAction) {
NTrackerExt.setInflow(appLinkData)
}

// Your Codes.
}
}

For more information, see Handling Android App Links.

Verify the SDK integration

Before publishing your app on the app store, you need to verify whether funnel information is successfully collected for traffic that flows to your app through a deep link. Follow the instructions below:

  1. Add “gfa_click_id” to the deep link URL to your app as a query parameter. For example, if the deep link address is “https://deeplink.example.com/path”, add the query parameter to it, like “https://deeplink.example.com/path?gfa_click_id=TEST_CLICK_ID”.
  2. Click the link with the click ID added to enter the app.
  3. Check logs in the IDE (XCode, Android Studio, etc.) console. Make sure that enableDebugLog is set to "true."
    • If the setInflow API is successfully called, "attribution_info":{"gfa_click_id":"TEST_CLICK_ID"} information is added to conversion logs.
    • This information is stored on the user device and used from the start of collecting data. So, for repeated testing, you need to delete the app or app cache before running a new test.

An example of iOS log messages is as follows: iOS Log

An example of Android log messages is as follows: Android Log