Skip to main content

Migrate Firebase Dynamic Links on iOS

The native Ulinkly iOS SDK (sdk/ios_ulink_sdk) replaces Firebase Dynamic Links with first-party support for universal links, custom schemes, installation tracking, and link creation. Follow these steps to swap SDKs while keeping your routing logic intact.


1. Install the SDK​

Choose CocoaPods or Swift Package Manager (as documented in sdk/ios_ulink_sdk/README.md):

pod 'ULinkSDK', '~> 1.2.4'

or

.package(url: "https://github.com/mohn93/ios_ulink_sdk.git", from: "1.2.4")

Note: SPM requires version 1.0.10 or later. Earlier versions are not SPM-compatible.


2. Confirm dashboard configuration​

The overview prerequisites already cover this, but double-check the key items before swapping SDK code:

  • Configuration → iOS: bundle ID, URL scheme (e.g. myapp://), App Store fallback, Team ID.
  • Domains: shared .shared.ly or custom domain verified (Ulinkly hosts the apple-app-site-association file automatically).
  • Links: every Firebase slug recreated with its new type and metadata (use the dashboard or /sdk/links API).

This lets the rest of the page stay focused on iOS-specific implementation details.


3. Initialize Ulinkly instead of Firebase​

Replace any DynamicLinks.dynamicLinks() initialization with the Ulinkly SDK inside AppDelegate:

import ULinkSDK
import Combine

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var cancellables = Set<AnyCancellable>()

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {

let config = ULinkConfig(
apiKey: "ULINK_API_KEY_FROM_DASHBOARD",
enableDeepLinkIntegration: true,
debug: true
)

let ulink = ULink.initialize(config: config)

ulink.onLink.sink { resolved in
handleDynamicLink(resolved)
}.store(in: &cancellables)

ulink.onUnifiedLink.sink { resolved in
handleUnifiedLink(resolved)
}.store(in: &cancellables)

return true
}
}
  • onLink replaces Firebase’s dynamic-link callback with strongly typed ULinkResolvedData.
  • onUnifiedLink exposes the “open in browser” cases so you can choose whether to stay in-app or hand off to Safari.

Firebase required custom logic in application(_:open:options:). The Ulinkly SDK uses the same entry points:

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

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL else {
return false
}
return ULink.shared.handleIncomingURL(url)
}

Because the dashboard hosts the apple-app-site-association file, you only need to add applinks:YOURDOMAIN.shared.ly (or your custom host) in the Associated Domains capability.


5. Replace Firebase REST helpers​

If your app generated Firebase links locally, use the built-in factories in sdk/ios_ulink_sdk/ULinkSDK/Sources/ULinkSDK/ULinkParameters.swift before calling ULink.shared.createLink.

let parameters = ULinkParameters.dynamic(
slug: "ios-launch-2024",
iosFallbackUrl: "https://apps.apple.com/app/id123456789",
androidFallbackUrl: "https://play.google.com/store/apps/details?id=com.example.app",
fallbackUrl: "https://example.com/launch",
parameters: ["utm_source": "ios-app"],
socialMediaTags: SocialMediaTags(
title: "Launch Offer",
description: "Redeem inside the app",
imageUrl: "https://example.com/og.png"
),
domain: "links.shared.ly"
)

Task {
let response = try await ULink.shared.createLink(parameters: parameters)
print("Created link: \(response.url ?? "no url")")
}

Unified links use ULinkParameters.unified with per-platform URLs—ideal for marketing pages that should still open your app when possible.


6. Test before shipping​

  1. Use Safari to open the new https://links.shared.ly/<slug> URLs and confirm the app delegate receives events.
  2. Hit https://api.ulink.ly/v1/sdk/resolve?url=... when debugging to see the resolved payload the redirect service uses.
  3. Validate analytics under Dashboard → Links → Analytics — you should see clicks, UTMs, device/geo data, and MAU stats driven by the session APIs above.

Once verified, remove Firebase Dynamic Links dependencies from your Podfile/Package manifest. Your iOS build now leans entirely on Ulinkly’s SDK + APIs.