### Install Referrer API
Source: https://limelink.org/md/android-sdk
Methods to retrieve app installation source information and structured LimeLink metadata.
```APIDOC
## GET /install-referrer
### Description
Retrieves the raw install referrer string and structured LimeLink metadata from the Play Store.
### Method
GET (SDK Wrapper)
### Parameters
- **context** (Context) - Required - The application context.
### Response
#### Success Response (200)
- **referrerUrl** (String) - Raw referrer string.
- **clickTimestamp** (Long) - Ad click time.
- **installTimestamp** (Long) - App install start time.
- **limeLinkDetail** (Object) - Structured details including `url`, `fullUrl`, and `queryParams`.
### Response Example
{
"referrerUrl": "utm_source=kakao&campaign=summer",
"clickTimestamp": 1625000000,
"installTimestamp": 1625000100,
"limeLinkDetail": {
"url": "https://abc.limelink.org/link/test",
"queryParams": {"utm_source": "kakao", "campaign": "summer"}
}
}
```
--------------------------------
### Universal Link Flow Examples
Source: https://limelink.org/md/ios-sdk
Examples of Universal Link URLs used by the LimeLink SDK. The subdomain method is recommended and includes optional query parameters. The direct access method uses a different API endpoint.
```plaintext
https://{subdomain}.limelink.org/link/{linkSuffix}
https://{subdomain}.limelink.org/link/{linkSuffix}?campaign=summer&source=email
```
```plaintext
https://limelink.org/api/v1/app/dynamic_link/{suffix}
https://limelink.org/universal-link/app/dynamic_link/{suffix}
```
--------------------------------
### Retrieve and Parse Install Referrer Information
Source: https://limelink.org/md/android-sdk
Retrieves installation source data and parses the LimeLink URL into structured components like query parameters and base URLs.
```kotlin
LimeLinkSDK.getInstallReferrer(context) { referrerInfo ->
val detail = referrerInfo?.limeLinkDetail
if (detail != null) {
Log.d("Detail", "url: ${detail.url}")
Log.d("Detail", "queryParams: ${detail.queryParams}")
}
}
```
--------------------------------
### Distinguishing Universal Link vs Deferred Deeplink
Source: https://limelink.org/md/android-sdk
Example code demonstrating how to differentiate between a Universal Link (app is running) and a Deferred Deep Link (app was just installed) within the `onDeeplinkReceived` callback.
```APIDOC
## DELETE /api/users/{userId}
### Description
Deletes a user account from the system. Requires the user's ID.
### Method
DELETE
### Endpoint
/api/users/{userId}
### Parameters
#### Path Parameters
- **userId** (string) - Required - The unique identifier of the user to delete.
#### Query Parameters
- **none**
### Request Example
```
DELETE /api/users/usr_12345abcde
```
### Response
#### Success Response (204 No Content)
- No response body is returned upon successful deletion.
#### Response Example
(No content)
#### Error Response (404 Not Found)
- **error** (string) - A message indicating that the user with the specified ID was not found.
#### Error Response Example
```json
{
"error": "User with ID 'usr_12345abcde' not found."
}
```
```
--------------------------------
### Query String Handling Example
Source: https://limelink.org/md/ios-sdk
Demonstrates how query parameters from an original URL are preserved and included in the API call for Universal Link resolution. This ensures all tracking and contextual information is passed to the backend.
```plaintext
Original: https://abc.limelink.org/link/test?campaign=summer&source=email
API call: GET /api/v1/app/dynamic_link/test?full_request_url=https://abc.limelink.org/link/test?campaign=summer&source=email
```
--------------------------------
### Create Dynamic Link Request Example
Source: https://limelink.org/md/api-integration
This example demonstrates how to construct a JSON request body to create a dynamic link using the API. It includes root-level parameters and platform-specific options for iOS and Android, along with additional options for social previews and UTM tracking.
```JSON
{
"dynamic_link_suffix": "my_unique_link_suffix",
"dynamic_link_url": "https://www.example.com/target",
"dynamic_link_name": "My Link Name",
"project_id": "your_project_id",
"stats_flag": true,
"apple_options": {
"application_id": "com.example.ios",
"request_uri": "/some/path/in/app",
"not_installed_options": {
"custom_url": "https://www.example.com/download"
}
},
"android_options": {
"application_id": "com.example.android",
"request_uri": "/some/path/in/app",
"not_installed_options": {
"custom_url": "https://www.example.com/download"
}
},
"additional_options": {
"preview_title": "Check out this link!",
"preview_description": "A great link with amazing content.",
"preview_image_url": "https://www.example.com/image.jpg",
"utm_source": "newsletter",
"utm_medium": "email",
"utm_campaign": "summer_sale"
}
}
```
--------------------------------
### SDK Initialization in AppDelegate
Source: https://limelink.org/md/ios-sdk
Initializes the LimeLink SDK upon application launch by creating a `LimeLinkConfig` object with the API key and other settings, then calling `LimeLinkSDK.initialize()`. This setup is crucial for the SDK's functionality.
```swift
import UIKit
import LimelinkIOSSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize LimeLink SDK
let config = LimeLinkConfig(
apiKey: "YOUR_API_KEY",
loggingEnabled: false, // Set to true for debug builds
deferredDeeplinkEnabled: true
)
LimeLinkSDK.initialize(config: config)
return true
}
}
```
--------------------------------
### Handling Deferred vs. Universal Links (Kotlin)
Source: https://limelink.org/md/android-sdk
This Kotlin code snippet demonstrates how to differentiate between a deferred deep link and a standard universal link within the `onDeeplinkReceived` callback. It shows how to access referrer information for deferred links, which is useful for tracking install sources.
```kotlin
override fun onDeeplinkReceived(result: LimeLinkResult) {
if (result.isDeferred) {
// App launched for the first time after install — restored link from before installation
val referrer = result.referrerInfo
Log.d("Deferred", "referrer url: ${referrer?.limeLinkUrl}")
Log.d("Deferred", "query params: ${referrer?.limeLinkDetail?.queryParams}")
} else {
// Universal Link clicked while app is running
Log.d("UniversalLink", "Received universal link: ${result.resolvedUri}")
}
}
```
--------------------------------
### CocoaPods Installation (Podfile)
Source: https://limelink.org/md/ios-sdk
Defines the LimeLink iOS SDK dependency within the Podfile for CocoaPods integration. This allows for easy management of the SDK as a project dependency.
```ruby
platform :ios, '12.0'
use_frameworks!
target 'YourApp' do
pod 'LimelinkIOSSDK'
end
```
--------------------------------
### Install Limelink SDKs
Source: https://limelink.org/llms.txt
Instructions for integrating the Limelink SDK into mobile projects using CocoaPods for iOS or Gradle for Android. These dependencies enable deep linking and analytics tracking within mobile applications.
```ruby
pod 'LimelinkIOSSDK'
```
```gradle
maven { url 'https://jitpack.io' }
implementation 'com.github.hellovelope:limelink-aos-sdk:0.1.0'
```
--------------------------------
### Swift Package Manager Installation (Package.swift)
Source: https://limelink.org/md/ios-sdk
Specifies the LimeLink iOS SDK dependency in the Package.swift file for Swift Package Manager integration. This ensures the SDK is included as a dependency for your project.
```swift
dependencies: [
.package(url: "https://github.com/hellovelope/limelink-ios-sdk.git", from: "0.2.0")
]
```
```swift
.target(
name: "YourApp",
dependencies: [
.product(name: "LimelinkIOSSDK", package: "limelink-ios-sdk")
]
)
```
--------------------------------
### Handle Deferred Deep Link with Suffix
Source: https://limelink.org/md/android-sdk
Processes a deferred deep link manually when the suffix and full request URL are already available, such as from custom Install Referrer handling.
```kotlin
LimeLinkSDK.handleDeferredDeepLink(
suffix = "campaign-xyz",
fullRequestUrl = "https://abc.limelink.org/link/campaign-xyz"
) { resolvedUri ->
resolvedUri?.let { navigateTo(it) }
}
```
--------------------------------
### Manual Deferred Deep Link Handling (Swift)
Source: https://limelink.org/md/ios-sdk
Provides an example of how to manually trigger the handling of deferred deep links using the LimeLink SDK. This is used when automatic detection is disabled, allowing developers to call the handler at a specific point in the app's lifecycle.
```swift
LimeLinkSDK.shared.handleDeferredDeepLink { result, error in
if let result = result {
// result.isDeferred == true
// result.resolvedUri contains the deep link URI
}
if let error = error {
// No match found or network error
}
}
```
--------------------------------
### GET /api/v1/app/dynamic_link/{suffix}
Source: https://limelink.org/md/android-sdk
This endpoint is used by the SDK to resolve a deferred deep link suffix into a full URI, typically triggered during the first app launch after installation.
```APIDOC
## GET /api/v1/app/dynamic_link/{suffix}
### Description
Resolves a deferred deep link suffix retrieved from the Install Referrer API into a functional URI for the application to handle.
### Method
GET
### Endpoint
/api/v1/app/dynamic_link/{suffix}
### Parameters
#### Path Parameters
- **suffix** (String) - Required - The unique identifier extracted from the install referrer.
#### Query Parameters
- **event_type** (String) - Required - The event context, typically set to "setup" for deferred deep link resolution.
### Response
#### Success Response (200)
- **resolvedUri** (String) - The deep link URI to be navigated to within the app.
#### Response Example
{
"resolvedUri": "myapp://content/campaign-xyz"
}
```
--------------------------------
### Initialize and Listen for Deferred Deep Links in Kotlin
Source: https://limelink.org/md/android-sdk
Demonstrates the default automatic initialization of the LimeLink SDK and how to register a listener to handle deferred deep links received upon first launch.
```kotlin
LimeLinkSDK.init(this, config)
LimeLinkSDK.addLinkListener(object : LimeLinkListener {
override fun onDeeplinkReceived(result: LimeLinkResult) {
if (result.isDeferred) {
navigateToContent(result.resolvedUri)
}
}
})
```
--------------------------------
### Initialize LimeLink SDK in Objective-C
Source: https://limelink.org/md/ios-sdk
Configure and initialize the LimeLink SDK at application startup. Requires an API key and base URL.
```objective-c
LimeLinkConfig *config = [[LimeLinkConfig alloc] initWithApiKey:@"YOUR_API_KEY"
baseUrl:@"https://limelink.org/"
loggingEnabled:YES
deferredDeeplinkEnabled:YES];
[LimeLinkSDK initialize:config];
```
--------------------------------
### SDK Core Methods
Source: https://limelink.org/md/android-sdk
Core methods for initializing the LimeLink SDK and managing deep link listeners.
```APIDOC
## SDK Initialization and Listeners
### Description
Methods to initialize the SDK and register listeners to handle incoming deep links.
### Methods
- `LimeLinkSDK.init(context, config)`: Initializes the SDK. Should be called in `Application.onCreate()`.
- `LimeLinkSDK.addLinkListener(listener)`: Registers a callback to receive `LimeLinkResult` objects.
### Request Example
```kotlin
LimeLinkSDK.init(this, config)
LimeLinkSDK.addLinkListener(object : LimeLinkListener {
override fun onDeeplinkReceived(result: LimeLinkResult) {
if (result.isDeferred) {
navigateToContent(result.resolvedUri)
}
}
})
```
```
--------------------------------
### Initialize LimeLink SDK in Application Class
Source: https://limelink.org/md/android-sdk
This Kotlin code snippet shows how to initialize the LimeLink SDK within your `Application` class's `onCreate()` method. It includes configuration options for API key, logging, and deferred deeplinking.
```kotlin
import org.limelink.limelink_aos_sdk.LimeLinkConfig
import org.limelink.limelink_aos_sdk.LimeLinkSDK
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
val config = LimeLinkConfig.Builder("YOUR_API_KEY")
.setLogging(true) // Debug logs (default: false)
.setDeferredDeeplinkEnabled(true) // Auto deferred deeplink check (default: true)
// .setBaseUrl("https://custom.api.com/") // Custom server (default: https://limelink.org/)
.build()
LimeLinkSDK.init(this, config)
}
}
```
--------------------------------
### Migrate Deep Link Handling from v0.0.x to v0.1.0+ (Kotlin)
Source: https://limelink.org/md/android-sdk
Demonstrates the migration of deep link handling from the older v0.0.x API to the new v0.1.0+ API in Kotlin. The new approach involves a one-time initialization in the Application class and registering a listener in Activities.
```kotlin
// No Application-level initialization
// Manual handling in each Activity
class MyActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
LimeLinkSDK.handleUniversalLink(this, intent) { uri -> /* ... */ }
saveLimeLinkStatus(this, intent, "api_key")
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
LimeLinkSDK.handleUniversalLink(this, intent) { uri -> /* ... */ }
}
// Manual parsing
val params = LimeLinkSDK.parseQueryParams(intent)
val pathParams = UrlHandler.parsePathParams(intent)
}
```
```kotlin
// One-time initialization in Application
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
val config = LimeLinkConfig.Builder("api_key").build()
LimeLinkSDK.init(this, config)
}
}
// Register listener in Activity
class MyActivity : Activity() {
private val listener = object : LimeLinkListener {
override fun onDeeplinkReceived(result: LimeLinkResult) {
// All info is included in result:
// result.originalUrl, result.resolvedUri
// result.queryParams, result.pathParams
// result.isDeferred, result.referrerInfo
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
LimeLinkSDK.addLinkListener(listener)
}
override fun onDestroy() {
super.onDestroy()
LimeLinkSDK.removeLinkListener(listener)
}
}
```
--------------------------------
### Migrate to Limelink SDK v0.2.0
Source: https://limelink.org/md/ios-sdk
Comparison of manual legacy implementation versus the automated v0.2.0 SDK initialization and listener pattern.
```swift
// Before (Previous Versions)
saveLimeLinkStatus(url: url, privateKey: "your_key")
UniversalLink.shared.handleUniversalLink(url) { uri in
if let uri = uri {
// Handle URI
}
}
if LinkStats.isFirstLaunch() {
DeferredDeepLinkService.getDeferredDeepLink { result in
switch result {
case .success(let uri):
// Handle URI
case .failure(let error):
// Handle error
}
}
}
```
```swift
// After (v0.2.0)
let config = LimeLinkConfig(apiKey: "your_key")
LimeLinkSDK.initialize(config: config)
class MyViewController: UIViewController, LimeLinkListener {
override func viewDidLoad() {
super.viewDidLoad()
LimeLinkSDK.shared.addLinkListener(self)
}
func onDeeplinkReceived(result: LimeLinkResult) {
// Handle result.resolvedUri, result.queryParams, result.pathParams
}
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if let url = userActivity.webpageURL {
LimeLinkSDK.shared.handleUniversalLink(url)
return true
}
return false
}
```
--------------------------------
### Configure Application Class in AndroidManifest.xml
Source: https://limelink.org/md/android-sdk
This XML snippet shows how to register your custom Application class (e.g., `MyApp`) in the `AndroidManifest.xml` file. This is necessary for the SDK initialization to take place.
```xml
```
--------------------------------
### Add JitPack Repository to Project Settings
Source: https://limelink.org/md/android-sdk
This snippet shows how to add the JitPack repository to your project's `settings.gradle` file. This is a prerequisite for including SDKs distributed via JitPack.
```groovy
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
```
--------------------------------
### Checking SDK Initialization Status
Source: https://limelink.org/md/ios-sdk
Demonstrates how to check if the LimeLink SDK has been successfully initialized using the `isInitialized` property. This check can be used to ensure SDK readiness before performing related operations.
```swift
if LimeLinkSDK.shared.isInitialized {
// SDK is ready
}
```
--------------------------------
### Handle Deep Links in ViewController
Source: https://limelink.org/md/ios-sdk
Demonstrates how to register a ViewController as a listener to process deep links and perform navigation. It distinguishes between deferred and standard deep links and provides error handling logic.
```Swift
import UIKit
import LimelinkIOSSDK
class MainViewController: UIViewController, LimeLinkListener {
override func viewDidLoad() {
super.viewDidLoad()
LimeLinkSDK.shared.addLinkListener(self)
}
func onDeeplinkReceived(result: LimeLinkResult) {
guard let uri = result.resolvedUri else { return }
if result.isDeferred {
print("Deferred deep link: \(uri)")
} else {
print("Universal link resolved: \(uri)")
}
navigateToContent(uri: uri)
}
func onDeeplinkError(error: LimeLinkError) {
print("Deeplink error [\(error.code)]: \(error.message)")
}
private func navigateToContent(uri: String) {
guard let url = URL(string: uri) else { return }
let pathComponents = url.pathComponents
if pathComponents.contains("product"), let id = pathComponents.last {
let vc = ProductViewController(productId: id)
navigationController?.pushViewController(vc, animated: true)
}
}
}
```
--------------------------------
### Handle Universal Links in Objective-C
Source: https://limelink.org/md/ios-sdk
Implement universal link support within the AppDelegate. Provides methods to handle links directly via the SDK or through a bridge with completion handlers.
```objective-c
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray> *))restorationHandler {
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
if (url) {
[[LimeLinkSDK shared] handleUniversalLink:url];
return YES;
}
}
return NO;
}
```
```objective-c
#import
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray> *))restorationHandler {
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
if (url) {
[UniversalLinkHandlerBridge handleUniversalLink:url
completion:^(NSString * _Nullable uri) {
if (uri) {
NSLog(@"Resolved URI: %@", uri);
}
}];
return YES;
}
}
return NO;
}
```
--------------------------------
### POST /api/v1/core/link
Source: https://limelink.org/md/api-integration
Generates a dynamic link with various customization options for different platforms and analytics.
```APIDOC
## POST /api/v1/core/link
### Description
This endpoint generates a dynamic link. It allows for detailed configuration of the link's behavior on different platforms (iOS, Android), preview appearance, and UTM parameters for tracking.
### Method
POST
### Endpoint
/api/v1/core/link
### Parameters
#### Query Parameters
None
#### Request Body
- **dynamic_link_suffix** (string) - Required - A unique suffix for the dynamic link.
- **dynamic_link_url** (string) - Required - The base URL the dynamic link should resolve to.
- **dynamic_link_name** (string) - Required - A descriptive name for the dynamic link.
- **apple_options** (object) - Optional - Configuration for iOS specific behavior.
- **application_id** (string) - Required (if apple_options is present) - The application ID for Apple.
- **not_installed_options** (object) - Optional - Behavior when the app is not installed.
- **custom_url** (string) - Required (if not_installed_options is present) - The URL to redirect to if the app is not installed.
- **request_uri** (string) - Optional - The specific URI path for Apple devices.
- **android_options** (object) - Optional - Configuration for Android specific behavior.
- **application_id** (string) - Required (if android_options is present) - The application ID for Android.
- **not_installed_options** (object) - Optional - Behavior when the app is not installed.
- **custom_url** (string) - Required (if not_installed_options is present) - The URL to redirect to if the app is not installed.
- **request_uri** (string) - Optional - The specific URI path for Android devices.
- **additional_options** (object) - Optional - Additional customization options.
- **preview_title** (string) - Optional - Title for link previews.
- **preview_description** (string) - Optional - Description for link previews.
- **preview_image_url** (string) - Optional - URL for the preview image.
- **utm_source** (string) - Optional - UTM source parameter.
- **utm_medium** (string) - Optional - UTM medium parameter.
- **utm_campaign** (string) - Optional - UTM campaign parameter.
- **project_id** (string) - Required - The ID of the project.
- **stats_flag** (boolean) - Optional - Flag to enable/disable statistics tracking.
### Request Example
```json
{
"dynamic_link_suffix": "my-promo",
"dynamic_link_url": "https://example.com/product/123",
"dynamic_link_name": "My Product Promotion",
"apple_options": {
"application_id": "f8b2d4e1-9c7a-4f6e-b3d8-2a1e9c4f7b6d",
"not_installed_options": {
"custom_url": "https://apps.apple.com/app/id123456789"
},
"request_uri": "product/123"
},
"android_options": {
"application_id": "a3f7c9b2-6e4d-4a8c-9f1b-8d5e2c9a7f3b",
"not_installed_options": {
"custom_url": "https://play.google.com/store/apps/details?id=com.example.androidapp"
},
"request_uri": "product/123"
},
"additional_options": {
"preview_title": "Special Offer!",
"preview_description": "Get 20% off on our new product.",
"preview_image_url": "https://example.com/images/promo-preview.png",
"utm_source": "newsletter",
"utm_medium": "email",
"utm_campaign": "q4_promo"
},
"project_id": "project_abcdef123456",
"stats_flag": true
}
```
### Response
#### Success Response (200)
- **link** (string) - The generated dynamic link.
- **id** (string) - The unique identifier for the created link.
#### Response Example
```json
{
"link": "https://yourdomain.page.link/AbCdEfG",
"id": "link_xyz789"
}
```
### Security Warning
> **⚠️ Important: API Key Security**
### Server-Side Only
- **Do NOT expose your API key in client-side code** (JavaScript, mobile apps, etc.)
- API keys should only be stored and used on your backend server
- Client applications should call your own server, which then calls the LimeLink API
### Recommended Architecture
```
[Mobile App / Web Client] → [Your Backend Server] → [LimeLink API]
↑
API Key stored here
```
### Why This Matters
If your API key is exposed in client-side code:
- Anyone can extract the key from your app or website
- Unauthorized users can create links under your project
- Your API quota may be exhausted by malicious actors
### Disclaimer
**LimeLink is not responsible for any damages, unauthorized access, or misuse resulting from API key exposure.**
Users are solely responsible for:
- Securely storing and managing their API keys
- Implementing proper server-side architecture
- Any consequences arising from API key leakage or misuse
By using this API, you acknowledge and accept full responsibility for the security of your API credentials.
### Notes
- This API is typically used for in-app sharing and automated link generation
- API access is project-based and secured via API keys
- Rate limiting and validation rules may apply
- More API endpoints may be added in future updates
```
--------------------------------
### Configure SceneDelegate for Universal Links
Source: https://limelink.org/md/ios-sdk
Handles incoming Universal Links and Custom URL schemes within the SceneDelegate. It captures links during cold launches, warm launches, and via URL contexts to pass them to the LimeLinkSDK.
```Swift
import LimelinkIOSSDK
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let userActivity = connectionOptions.userActivities.first,
userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL {
LimeLinkSDK.shared.handleUniversalLink(url)
}
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL {
LimeLinkSDK.shared.handleUniversalLink(url)
}
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
if let url = URLContexts.first?.url {
LimeLinkSDK.shared.handleUniversalLink(url)
}
}
}
```
--------------------------------
### Create Global DeepLinkManager Singleton
Source: https://limelink.org/md/ios-sdk
Implements a centralized manager to handle deep links app-wide using a singleton pattern. It broadcasts received links via NotificationCenter and ensures the listener remains active.
```Swift
import LimelinkIOSSDK
class DeepLinkManager: NSObject, LimeLinkListener {
static let shared = DeepLinkManager()
private override init() {
super.init()
LimeLinkSDK.shared.addLinkListener(self)
}
func onDeeplinkReceived(result: LimeLinkResult) {
guard let uri = result.resolvedUri else { return }
NotificationCenter.default.post(
name: .didReceiveDeepLink,
object: nil,
userInfo: ["uri": uri, "isDeferred": result.isDeferred]
)
}
func onDeeplinkError(error: LimeLinkError) {
print("[DeepLinkManager] Error: \(error.message)")
}
}
extension Notification.Name {
static let didReceiveDeepLink = Notification.Name("didReceiveDeepLink")
}
```
--------------------------------
### Troubleshoot 'Unresolved reference: LimeLinkSDK' with Gradle
Source: https://limelink.org/md/android-sdk
Provides commands to resolve the 'Unresolved reference: LimeLinkSDK' error when using JitPack. It involves ensuring the JitPack repository is added and refreshing the Gradle dependency cache.
```bash
# If using JitPack — verify JitPack repository is added to settings.gradle
# Refresh dependency cache
./gradlew clean --refresh-dependencies
```
--------------------------------
### Universal Link and Custom URL Handling in AppDelegate
Source: https://limelink.org/md/ios-sdk
Implements methods in `AppDelegate` to handle both universal links and custom URL schemes by passing the incoming URL to `LimeLinkSDK.shared.handleUniversalLink()`. This ensures that deep links are correctly processed by the SDK.
```swift
// MARK: - Universal Link Handling
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL {
LimeLinkSDK.shared.handleUniversalLink(url)
return true
}
return false
}
// MARK: - Custom URL Scheme Handling
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
LimeLinkSDK.shared.handleUniversalLink(url)
return true
}
```
--------------------------------
### Universal Link Flow - Direct Access Pattern
Source: https://limelink.org/md/android-sdk
Describes the direct access pattern for Universal Links, where the SDK makes a direct API request to resolve a link.
```APIDOC
## GET /universal-link/app/dynamic_link/{suffix}
### Description
This endpoint is an alternative path for the Universal Link flow, allowing direct API access to resolve a dynamic link using its suffix.
### Method
GET
### Endpoint
/universal-link/app/dynamic_link/{suffix}
### Parameters
#### Path Parameters
- **suffix** (string) - Required - The suffix of the dynamic link to resolve.
#### Query Parameters
- **full_request_url** (string) - Required - The full original URL that was clicked, including all query parameters. This must be URL-encoded.
### Request Example
```
GET /universal-link/app/dynamic_link/promo?full_request_url=https%3A%2F%2Fabc.limelink.org%2Flink%2Fpromo%3Fcampaign%3Dsummer%26source%3Demail
```
### Response
#### Success Response (200 OK)
- **uri** (string) - The final, resolved URI that the SDK should navigate the user to.
#### Response Example
```json
{
"uri": "https://example.com/products/promo-details?id=123"
}
```
#### Error Response (400 Bad Request)
- **error** (string) - A message indicating an issue with the request, such as an invalid or missing `full_request_url` parameter.
#### Error Response Example
```json
{
"error": "Missing or invalid 'full_request_url' parameter."
}
```
#### Error Response (404 Not Found)
- **error** (string) - A message indicating that the dynamic link suffix could not be found or resolved.
#### Error Response Example
```json
{
"error": "Dynamic link suffix 'promo' not found."
}
```
```
--------------------------------
### Universal Link Flow - Subdomain Method
Source: https://limelink.org/md/ios-sdk
This method is recommended for handling universal links. The SDK intercepts clicks, extracts necessary information, and calls the API to resolve the final URI.
```APIDOC
## Universal Link Flow - Subdomain Method
### Description
This method is recommended for handling universal links. The SDK intercepts clicks, extracts necessary information, and calls the API to resolve the final URI.
### Method
GET
### Endpoint
`https://{subdomain}.limelink.org/link/{linkSuffix}`
`https://{subdomain}.limelink.org/link/{linkSuffix}?campaign=summer&source=email`
### Parameters
#### Query Parameters
- **campaign** (String) - Optional - Example query parameter.
- **source** (String) - Optional - Example query parameter.
- **full_request_url** (String) - Required - The full URL that was originally clicked, including all its query parameters. This is used by the API to reconstruct the context.
### Request Example
```
GET /api/v1/app/dynamic_link/test?full_request_url=https://abc.limelink.org/link/test?campaign=summer&source=email HTTP/1.1
Host: abc.limelink.org
```
### Response
#### Success Response (200)
- **originalUrl** (String?) - The original URL that was opened.
- **resolvedUri** (String?) - The final URI resolved by the API.
- **queryParams** (Object) - URL query parameters.
- **pathParams** (Object) - Path parameters (`mainPath`, `subPath`).
- **isDeferred** (Boolean) - Whether this is a deferred deep link.
#### Response Example
```json
{
"originalUrl": "https://abc.limelink.org/link/test?campaign=summer&source=email",
"resolvedUri": "myapp://product/123",
"queryParams": {
"campaign": "summer",
"source": "email"
},
"pathParams": {
"mainPath": "link",
"subPath": "test"
},
"isDeferred": false
}
```
```
--------------------------------
### Info.plist URL Scheme Configuration
Source: https://limelink.org/md/ios-sdk
Registers a custom URL scheme in the application's `Info.plist` file. This is necessary for handling custom URL schemes used for deep linking.
```xml
CFBundleURLTypes
CFBundleURLName
com.yourapp.deeplink
CFBundleURLSchemes
yourapp
```
--------------------------------
### Create Dynamic Link
Source: https://limelink.org/md/api-integration
This endpoint allows you to create a new dynamic link. You can configure platform-specific options, deep linking behaviors, social preview content, and UTM parameters.
```APIDOC
## POST /api/v1/core/link
### Description
Creates a new dynamic link with various configuration options for different platforms and tracking.
### Method
POST
### Endpoint
https://api.limelink.org/api/v1/core/link
### Headers
- **X-API-KEY** (string) - Required - API key for project authentication
- **Content-Type** (string) - Required - Must be `application/json`
### Request Body
- **dynamic_link_suffix** (string, max 50) - Required - Unique identifier for the short URL path
- **dynamic_link_url** (string, max 500) - Required - Target URL for desktop or fallback
- **dynamic_link_name** (string, max 100) - Required - Link name for management and identification
- **project_id** (string) - Required - Project ID the link belongs to
- **stats_flag** (boolean) - Optional - Enable analytics tracking
- **apple_options** (object) - Optional - Configuration for iOS platform
- **application_id** (string, max 100) - Conditional - Application ID registered in the dashboard
- **request_uri** (string) - Optional - Deep link path inside the app
- **not_installed_options.custom_url** (string, max 500) - Conditional - Redirect URL when the app is not installed
- **android_options** (object) - Optional - Configuration for Android platform
- **application_id** (string, max 100) - Conditional - Application ID registered in the dashboard
- **request_uri** (string) - Optional - Deep link path inside the app
- **not_installed_options.custom_url** (string, max 500) - Conditional - Redirect URL when the app is not installed
- **additional_options** (object) - Optional - Additional configuration for previews and tracking
- **preview_title** (string, max 100) - Conditional - Social preview title
- **preview_description** (string, max 200) - Conditional - Social preview description
- **preview_image_url** (string, max 500) - Conditional - Social preview image URL
- **utm_source** (string) - Optional - UTM source parameter
- **utm_medium** (string) - Optional - UTM medium parameter
- **utm_campaign** (string) - Optional - UTM campaign parameter
### Request Example
```json
{
"dynamic_link_suffix": "myuniquesuffix",
"dynamic_link_url": "https://example.com/",
"dynamic_link_name": "Example Link",
"project_id": "your_project_id",
"stats_flag": true,
"apple_options": {
"application_id": "123456789",
"request_uri": "myapp://open/page",
"not_installed_options": {
"custom_url": "https://apps.apple.com/app/id123456789"
}
},
"android_options": {
"application_id": "com.example.app",
"request_uri": "myapp://open/page",
"not_installed_options": {
"custom_url": "https://play.google.com/store/apps/details?id=com.example.app"
}
},
"additional_options": {
"preview_title": "Check out this link!",
"preview_description": "A great link for you.",
"preview_image_url": "https://example.com/image.png",
"utm_source": "newsletter",
"utm_medium": "email",
"utm_campaign": "spring_promo"
}
}
```
### Response
#### Success Response (200)
- **id** (string) - Unique identifier for the created dynamic link
- **dynamic_link_suffix** (string) - The suffix of the dynamic link
- **dynamic_link_url** (string) - The full dynamic link URL
- **dynamic_link_name** (string) - The name of the dynamic link
- **apple_options** (object) - Configuration for iOS platform
- **android_options** (object) - Configuration for Android platform
- **additional_options** (object) - Additional configuration options
- **project_id** (string) - The project ID associated with the link
- **stats_flag** (boolean) - Indicates if analytics tracking is enabled
- **created_at** (string) - Timestamp when the link was created
- **updated_at** (string or null) - Timestamp when the link was last updated
#### Response Example
```json
{
"id": "link_abc123",
"dynamic_link_suffix": "myuniquesuffix",
"dynamic_link_url": "https://api.limelink.org/api/v1/core/link/myuniquesuffix",
"dynamic_link_name": "Example Link",
"apple_options": {
"application_id": "123456789",
"request_uri": "myapp://open/page",
"not_installed_options": {
"custom_url": "https://apps.apple.com/app/id123456789"
}
},
"android_options": {
"application_id": "com.example.app",
"request_uri": "myapp://open/page",
"not_installed_options": {
"custom_url": "https://play.google.com/store/apps/details?id=com.example.app"
}
},
"additional_options": {
"preview_title": "Check out this link!",
"preview_description": "A great link for you.",
"preview_image_url": "https://example.com/image.png",
"utm_source": "newsletter",
"utm_medium": "email",
"utm_campaign": "spring_promo"
},
"project_id": "your_project_id",
"stats_flag": true,
"created_at": "2023-10-27T10:00:00Z",
"updated_at": null
}
```
```
--------------------------------
### Resolve CocoaPods build errors
Source: https://limelink.org/md/ios-sdk
Commands to resolve 'Module not found' errors by cleaning the CocoaPods environment and clearing Xcode derived data.
```bash
pod deintegrate
pod install
rm -rf ~/Library/Developer/Xcode/DerivedData
```
--------------------------------
### Create Dynamic Link via REST API
Source: https://limelink.org/llms.txt
The endpoint for programmatically generating dynamic links. Requires an API key passed in the request header for authentication.
```http
POST https://api.limelink.org/api/v1/core/link
Header: X-API-KEY: {your_api_key}
```
--------------------------------
### Universal Link Flow - Subdomain Pattern
Source: https://limelink.org/md/android-sdk
Details the flow for Universal Links using the subdomain pattern, where the SDK extracts subdomain and link suffix to call the API.
```APIDOC
## GET /api/v1/app/dynamic_link/{suffix}
### Description
This endpoint is part of the Universal Link flow. It is called by the SDK to resolve a dynamic link based on a provided suffix and query parameters, returning a resolved URI.
### Method
GET
### Endpoint
/api/v1/app/dynamic_link/{suffix}
### Parameters
#### Path Parameters
- **suffix** (string) - Required - The suffix of the dynamic link to resolve.
#### Query Parameters
- **full_request_url** (string) - Required - The full original URL that was clicked, including all query parameters. This must be URL-encoded.
### Request Example
```
GET /api/v1/app/dynamic_link/promo?full_request_url=https%3A%2F%2Fabc.limelink.org%2Flink%2Fpromo%3Fcampaign%3Dsummer%26source%3Demail
```
### Response
#### Success Response (200 OK)
- **uri** (string) - The final, resolved URI that the SDK should navigate the user to.
#### Response Example
```json
{
"uri": "https://example.com/products/promo-details?id=123"
}
```
#### Error Response (400 Bad Request)
- **error** (string) - A message indicating an issue with the request, such as an invalid or missing `full_request_url` parameter.
#### Error Response Example
```json
{
"error": "Missing or invalid 'full_request_url' parameter."
}
```
#### Error Response (404 Not Found)
- **error** (string) - A message indicating that the dynamic link suffix could not be found or resolved.
#### Error Response Example
```json
{
"error": "Dynamic link suffix 'promo' not found."
}
```
```