iOS - Deeplink using Push Notifications
A common use case is sending a push notification with payload to the device that triggers a deep link. This is helpful when you want to navigate the user to a specific screen in the app (e.g., Messages or Profile). This can be done using the following approach.
Implementation
Once your class inherits from Q2ModuleBase
, override the
userNotificationCenter(_:didReceive:)
method. This method receives the push payload and
allows you to process and route to the correct screen.
In the following example:
DemoNotificationPayload
defines a uniquekey
to locate your payload in the notification data.- The payload is parsed, and the
route
property is passed tonavigateTo()
to trigger the deep link.
Example Code
public class Q2DemoModule: Q2ModuleBase {
public override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
/** Update your service with the new token when this is triggered **/
}
public override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
guard let moduleDelegate = moduleDelegate else {
return
}
// Make sure it's your payload.
guard let payload = DemoNotificationPayload.make(fromNotificationResponse: response) else {
return
}
Task {
let route = payload.route
_ = moduleDelegate.navigateTo(target: .route(route))
}
}
}
extension Q2DemoModule {
/*
{
"aps": {
"alert": {
...
}
},
"data" : {
"demo": {
"route" : "messages"
}
}
}
*/
struct DemoNotificationPayload: NotificationPayloadConvertible {
static var key: String = "demo" // use key which represents your payload.
let route: String
}
}
protocol NotificationPayloadConvertible: Codable {
static var key: String { get }
}
extension NotificationPayloadConvertible {
static func make(fromNotificationResponse notificationResponse: UNNotificationResponse) -> Self? {
let userInfo = notificationResponse.notification.request.content.userInfo
guard let userInfoDictionary = userInfo["data"] as? [String: Any] else {
return nil
}
guard let payloadDictionary = userInfoDictionary[Self.key] as? [String: Any] else {
return nil
}
do {
let jsonData = try JSONSerialization.data(withJSONObject: payloadDictionary, options: [])
return try JSONDecoder().decode(Self.self, from: jsonData)
} catch {
print("Error decoding JSON: \(error)")
return nil
}
}
}
Notification Payload Format
A data node should be added alongside the aps section in the push payload. The data should include a key (e.g., demo) and any custom properties you wish to parse in the userNotificationCenter(:didReceive:) method.
{
"aps": {
"alert": {
"title": "title",
"subtitle": "subtitle",
"body": "body"
}
},
"data": {
"demo": {
"route": "messages"
}
}
}
Expected Behavior
If the app is running and no module has overridden the navigation flow, the screen will navigate from its current view to the specified route. If the route doesn’t exist or is incorrectly typed, the app will remain on the current screen.
Common Routes
Assuming your sandbox URL is: https://stack.q2developer.com/sdk/native/ardent/uux.aspx#/settings/profile
Then the string after uux.aspx#/ is considered the route.
Available Routes
Description | Route |
---|---|
Landing Page | landingPage |
Fund Transfer | transfer |
Online Activity | transactions/activityCenter |
Conversations | messages |
Branches | branches |
Profile | settings/profile |