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.
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.
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.
@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.
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:
- 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”.
- Click the link with the click ID added to enter the app.
- 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.
- If the
An example of iOS log messages is as follows:
An example of Android log messages is as follows: