MovableInk SDK Help
iOS SDK

iOS Setup

Prerequisites

Before you begin, ensure you have:

  • Your MovableInk subdomain (e.g., mi.yourcompany.com)
  • AASA file configured by MovableInk at https://mi.yourcompany.com/.well-known/apple-app-site-association
  • iOS 13.0 or later as your deployment target
  • Xcode 14 or later

Need Help?

If you don't have these prerequisites, see the Getting Started guide or contact your Movable Ink client experience team.

Step 1: Install the SDK

Choose your preferred package manager:

  1. In Xcode, go to File > Add Package Dependencies
  2. Enter the repository URL: https://github.com/movableink/ios-sdk.git
  3. Select version 3.0.0 or later
  4. Click Add Package
Cartfile
binary "https://raw.githubusercontent.com/movableink/ios-sdk/main/Carthage/MovableInkSDK.json" == 3.0.0

In the root of your project, run

$ carthage update --use-xcframeworks

Add to your Podfile:

pod 'MovableInk', '~> 3.0.0'

Then run:

pod install

Deprecated

CocoaPods is becoming readonly and MovableInk will not be able to update the pod soon. We highly recommend migrating to a different package manager. Read more

  1. Go to the MovableInk Releases page.
  2. Download the SDK by opening the Assets accordion and selecting MovableInk.xcframework.zip
  3. Unzip the file, then drag the MovableInk.xcframework file into your project under the Frameworks, Libraries, and Embedded Content section

Not Native?

We have packages for Flutter, React Native and Expo apps.

Add Associated Domains

  1. Open your project in Xcode
  2. Select your app target
  3. Go to Signing & Capabilities tab
  4. Click + Capability and add Associated Domains
  5. Add your MovableInk subdomain in the format:
applinks:mi.yourcompany.com

Replace yourcompany.com with your actual MovableInk subdomain.

Update Info.plist

Add your MovableInk domain to Info.plist:

<key>movable_ink_universal_link_domains</key>
<array>
    <string>mi.yourcompany.com</string>
</array>

Replace mi.yourcompany.com with your actual MovableInk subdomain (without https://).

For SwiftUI Apps

In your App file:

import SwiftUI
import MovableInk

@main
struct YourApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
        .onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
          guard let url = userActivity.webpageURL else { return }

          MIClient.resolveURL(url) { result in
            switch result {
            case .success(let resolvedURL):
              // Navigate to the resolved URL in your app
              print("Deeplink resolved to: \(resolvedURL)")
              // TODO: Navigate to appropriate screen

            case .failure(let error):
              print("Failed to resolve link: \(error)")
            }
          }
        }
    }
  }
}

For UIKit Apps

In your AppDelegate.swift or SceneDelegate.swift:

import MovableInk

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

  MIClient.resolveURL(url) { result in
    switch result {
    case .success(let resolvedURL):
      // Navigate to the resolved URL in your app
      print("Deeplink resolved to: \(resolvedURL)")
      // TODO: Navigate to appropriate screen

    case .failure(let error):
      print("Failed to resolve link: \(error)")
    }
  }

  return true
}

Step 4: Verify It Works

Build and Run

  1. Build and run your app on a device or simulator (iOS 13+)
  2. Make sure your app is in the background or closed

Ask your MovableInk team for a test deeplink, or use this format:

https://mi.yourcompany.com/p/rp/test

What to Look For

  1. Open the test link in Safari on your device/simulator
  2. Your app should open automatically
  3. Check the Xcode console for the resolved URL:
Deeplink resolved to: https://yourapp.com/products/123

It Works!

If you see the resolved URL in the console, congratulations! Your basic deeplinking integration is working.

Troubleshooting

If your app doesn't open:

  • Verify your AASA file is accessible at https://mi.yourcompany.com/.well-known/apple-app-site-association
  • Check that your Associated Domains match exactly (no wildcards, no https://)
  • Ensure you're testing on iOS 13+
  • Try uninstalling and reinstalling your app to refresh the AASA cache

Next Steps

Now that you have basic deeplinking working, you can:

Implement Navigation

Update the TODO in your code to actually navigate to the appropriate screen based on the resolved URL:

case .success(let resolvedURL):
  // Parse the URL and navigate
  if resolvedURL.path.contains("/products/") {
    // Navigate to product detail screen
  } 
  else if resolvedURL.path.contains("/categories/") {
    // Navigate to category screen
  }

Add Behavior Events

Capture user interactions to power personalized marketing:

Deployment

Xcode 13 introduced a new option to their App Store Distribution Option:

Manage Version and Build Number

If checked, this option changes the version and build number of all content of your app to your applications version, including third-party frameworks. This option is enabled by default. Please make sure to disable this option when archiving or exporting your application to the App Store.

export_options_image

If you use the xcodebuild cli to archive your app, you can add the manageAppVersionAndBuildNumber key to your exportOptions.plist, and set it to false.

xcodebuild -exportArchive -archivePath ./Release.xcarchive \
-exportPath ./Release -exportOptionsPlist ./Release/exportOptions.plist
<key>manageAppVersionAndBuildNumber</key>
<false/>

If you're using Fastlane with Gym to archive and deploy your app, you can set this key in the export_options hash.

gym(
  scheme: "AppSchemeName",
  workspace: "App.xcworkspace",
  export_method: "app-store",
  export_options: { 
    manageAppVersionAndBuildNumber: false
  }, 
  output_directory: "Builds/"
)

Explore Advanced Features

Need More Details?

On this page