Skip to main content
Version: 1.0

2.1.1.2.3 Deep Link Method

Overview

The Deep Link Verification process allows users to verify their phone numbers by interacting with an external application, such as Telegram or WhatsApp, and then returning to your app to complete the verification.

Get started

  • Initialize VerifySpeed: Follow the initialize instructions.
  • Required Configuration: If using the deep link method, add LSApplicationQueriesSchemes to your app's Info.plist to enable external app linking.
xml
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tg</string>
<string>whatsapp</string>
</array>

Create a listener to handle the success and failure cases:

swift
class VerifySpeedListenerHandler: VerifySpeedListener {
var onSuccess: ((String) -> Void)?
var onFailure: ((VerifySpeedError) -> Void)?

func onFail(error: VerifySpeed_IOS.VerifySpeedError) {
onFailure?(error)
}

func onSuccess(token: String) {
onSuccess?(token)
}
}

Use verifyPhoneNumberWithDeepLink with these parameters:

  • deepLink: URL that directs users to the external app for verification.
  • verificationKey: Unique key provided by your backend to ensure verification integrity.
  • callBackListener: Callback interface to handle success and failure cases:
    • onSuccess: Triggered on successful verification, returning a token to retrieve the user's phone number.
    • onFailure: Triggered if verification fails, providing error details including type and message.
swift
let listener = VerifySpeedListenerHandler()

listener.onSuccess = { token in
print("Token: \(token)")
}

listener.onFailure = { error in
print("Error: \(error)")
}

VerifySpeed.shared.verifyPhoneNumberWithDeepLink(
deeplink: 'DEEP_LINK', // deep link provided by your backend
verificationKey: 'VERIFICATION_KEY', // unique key provided by your backend
callBackListener: listener
)

Handling App Resumption

When users return from the external app, call notifyOnResumed() to complete the verification process:

swift
VerifySpeed.shared.notifyOnResumed()

Example

For complete implementation examples, see:

Swift UI:

UIKit:

tip

When testing the example project, you'll need to integrate with your backend using these recommended request/response structures (which you can modify as needed).

tip

Search for keywords TIP if you want to know how to implement Deep Link Verification.

Best Practices

  1. SwiftUI Implementation

    • Use the @Environment(\.scenePhase) property wrapper to monitor app state changes

    • Benefits of this approach:

      • Clean integration with SwiftUI lifecycle
      • Automatic handling of app state transitions
      • Declarative approach to app resumption
    • Implementation example:

      @Environment(\.scenePhase) private var scenePhase

      var body: some View {
      YourView()
      .onChange(of: scenePhase) { newPhase in
      if newPhase == .active {
      // Notify VerifySpeed when the app resumes
      VerifySpeed.shared.notifyOnResumed()
      }
      }
      }
  2. UIKit Implementation

    • Implement app resumption using NotificationCenter to observe app state changes

    • Benefits of this approach:

      • Allows individual view controllers to handle their own resumption logic
      • Easier to manage lifecycle in specific views where verification occurs
    • Implementation example:

      class YourViewController: UIViewController {
      override func viewDidLoad() {
      super.viewDidLoad()
      setupNotifications()
      }

      override func viewWillDisappear(_ animated: Bool) {
      super.viewWillDisappear(animated)
      // Remove notification observer when view is disappearing
      NotificationCenter.default.removeObserver(self)
      }

      private func setupNotifications() {
      // Add observer for when app will enter foreground
      NotificationCenter.default.addObserver(
      self,
      selector: #selector(applicationWillEnterForeground),
      name: UIApplication.willEnterForegroundNotification,
      object: nil
      )
      }

      @objc private func applicationWillEnterForeground() {
      // Notify VerifySpeed when the app resumes
      VerifySpeed.shared.notifyOnResumed()
      }
      }
tip

Using NotificationCenter provides better separation of concerns and allows you to handle app resumption exactly where it's needed in your verification flow, rather than handling it globally in the AppDelegate.

info

We recommend creating a dedicated view controller to handle app resume notifications, rather than placing this logic in your main controller.

Implementation Example

Here's a complete example of implementing deep link verification in a SwiftUI view:

import SwiftUI
import VerifySpeed_IOS

struct MessagePage: View {
let method: String
@Binding var navigationPath: [Screen]
@StateObject private var viewModel = MessageViewModel()
@Environment(\.colorScheme) private var colorScheme
@Environment(\.scenePhase) private var scenePhase

var body: some View {
ZStack {
VStack(spacing: 20) {
Button {
Task {
await viewModel.verifyWithMessage(method: method)
}
} label: {
if viewModel.isLoading {
ProgressView()
.tint(Color.white)
} else {
Text("Verify with Message")
}
}
.buttonStyle(.borderedProminent)
.disabled(viewModel.isLoading)
.frame(maxWidth: .infinity)
.padding()
}
.padding()

if viewModel.showSuccessDialog {
VerificationAlertDialog(
title: "Verification Successful",
isLoading: viewModel.isLoading,
phoneNumber: viewModel.phoneNumber,
loadingMessage: nil,
onDismiss: { navigationPath.removeAll() }
)
}
}
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
// Notify VerifySpeed when the app resumes
VerifySpeed.shared.notifyOnResumed()
}
}
.alert(
"Error",
isPresented: .init(
get: { viewModel.error != nil },
set: { if !$0 { viewModel.error = nil } }
),
actions: { Button("OK", role: .cancel) { } },
message: { Text(viewModel.error ?? "Verification failed") }
)
}
}