Skip to content

How to use "deeplink" to land user to a particular app page?

Alexander Boldyrev edited this page Oct 31, 2024 · 4 revisions

This page describes one of the approaches of handling deep links in your app when user taps on a notification.

How to send deep link within the message

First you will need to identify the schema for your deep link, usually it is reverse DNS notation and ideally unique: com.infobip.mobilemessaging://deeplink/. And also define screens that you want to open as part of deep link such as redScreen, greenScreen, blueScreen. And then it will be possible to send deep link with message and to handle MMNotificationMessageTapped or MMNotificationActionTapped event.

To send message with deeplink parameter via Broadcast or Flow choose "Mobile Push" channel and specify action button properties:

  • Action: Open Page in Mobile App
  • Deep Link: com.infobip.mobilemessaging://deeplink/redScreen/greenScreen/blueScreen

Also, you can provide deeplink for push or Mirror In-App message using API by specifying notificationOptions.primaryButtonAction as follows:

"notificationOptions": {
    "primaryButtonAction": {
        "resource": "com.infobip.mobilemessaging://deeplink/redScreen/greenScreen/blueScreen",
        "type": "DEEP_LINK"
    }
}

Example of the code implementation

  1. To be sure that screen identifier for deep link provided let's define protocol DeeplinkLandingViewController, it should be implemented by all viewControllers, which can be opened through deep link
protocol DeeplinkLandingViewController {
        //identifier by which viewController can be defined in deep link path component
	static var deeplinkIdentifier: String { get }
        ...
}
  1. RedViewController, GreenViewController, BlueViewController are simple view controllers that vary only by background color, they implement DeeplinkLandingViewController protocol.
class RedViewController: DeeplinkLandingViewController {
	static let deeplinkIdentifier = "redScreen"
	...
}
class GreenViewController: DeeplinkLandingViewController {
	static let deeplinkIdentifier = "greenScreen"
	...
}
class BlueViewController: DeeplinkLandingViewController {
	static let deeplinkIdentifier = "blueScreen"
	...
}

DeeplinkViewControllers.swift

  1. Let's provide list of viewController types which can be opened through deep link, to find viewController with specific deeplinkIdentifier
var supportedViewControllers: [DeeplinkLandingViewController.Type] = [RedViewController.self, GreenViewController.self, BlueViewController.self]
  1. Open view controllers

The navigation process in highly dependent on a particular design of your application. In this example we will use modal style of presenting view controllers.

class func openDeeplink(url: URL, withMessage message: MM_MTMessage?) -> Bool {
	let supportedSchemes = ["com.infobip.mobilemessaging"]
	
	//check do we support scheme in the URL
	guard let scheme = url.scheme,
		supportedSchemes.contains(scheme) else {
			print("Scheme \(String(describing: url.scheme)) not supported")
			return false
	}
	
	openViewControllers(fromPathComponents: url.pathComponents, message: message)
	
	return true
}

class func openViewControllers(fromPathComponents pathComponents: [String], message: MM_MTMessage?) {
	guard !pathComponents.isEmpty else {
		return
	}
	
	let openNext: ([String]) -> Void = { pathComponents in
		var nextPathComponents = pathComponents
		nextPathComponents.removeFirst()
		self.openViewControllers(fromPathComponents: nextPathComponents, message: message)
	}
	
	//check do we have viewController with `deeplinkIdentifier`, provided as URL pathComponent
	guard let viewControllerType = supportedViewControllers.first(where: {pathComponents.first == $0.deeplinkIdentifier}) as? UIViewController.Type else {
		openNext(pathComponents)
		return
	}
	
	//create viewController from type`
	let viewController = viewControllerType.init()
	
	//present viewController modally
	UIApplication.shared.keyWindow?.visibleViewController?.present(viewController, animated: true, completion: {
		if let viewController = viewController as? DeeplinkLandingViewController,
			let message = message {
			viewController.handle(message: message)
		}
		openNext(pathComponents)
	})
}
  1. Check do we have deeplink parameter in MM_MTMessage object
class func handleLinks(fromMessage message: MM_MTMessage) {
	
	//checking do we have "deeplink" in message object
        if let deeplink = message.deeplink {
		_ = openDeeplink(url: deeplink, withMessage: message)
	}
        ...
}

LinksHandler.swift

  1. To start deep link handling on message tap let's handle tap event by calling LinksHandler.handleLinks(fromMessage:) method (to handle action button tap, subscribe to MMNotificationActionTapped event instead)
NotificationCenter.default.addObserver(self,
                                       selector: #selector(MessagesManager.handleTapNotification),
                                       name: NSNotification.Name(rawValue: MMNotificationMessageTapped),
                                       object: nil)
    func handleTapNotification(_ notification: Notification) {
        guard let userInfo = notification.userInfo,
        let message = userInfo[MMNotificationKeyMessage] as? MM_MTMessage else {
            return
        }
 
        LinksHandler.handleLinks(fromMessage: message)
    }

MessagesManager.swift

Full source code can be found in example application.

Registering of the custom URL scheme

If you register your URL scheme as described, your application could be launched by linking to it from a website:

<a href="com.infobip.mobilemessaging://deeplink/redScreen/greenScreen/blueScreen">Open my app</a>
  1. Let's register custom URL scheme com.infobip.mobilemessaging in Info.plist in the URL Types section, so that application can respond to requests to open URLs with such scheme.

You can register as many custom URL schemes as you want, just don't forget that they ideally should be unique and usually reverse-DNS notation is used.

Unique identifier for the scheme is usually bundle identifier of the app.

Register custom URL Scheme
  1. Let's implement application:openURL:options: in the application AppDelegate and call openDeeplink(url: withMessage:) method.
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
	return LinksHandler.openDeeplink(url: url, withMessage: nil)
}
Clone this wiki locally