Skip to content

Call from URL

Marco Brescianini edited this page Nov 7, 2024 · 16 revisions

This guide will show you how to enable starting a call from an URL. At the end of this guide you should be able to tap a link on an external app like Safari, Mail, Messages, Notes, or others and get your app open starting a call from the link you just tapped. This guide is divided into two sections. The first section will help you enabling "universal links" in your app. The second section will help you manage the URL received from the operating system and start a call using the Kaleyra Video SDK 4.0 version. If you are using a 3.x SDK version you should take a look at this guide instead.

Table of contents

Universal links

Below you'll find a brief step by step guide explaining what you need to do in order to support universal links in your app. Wherever possible we will point out some gotchas about universal links. If you have already enabled universal links into your app, you can skip this section altogether, and move to the Start the call section of this guide.

Overview

Universal links have been introduced in iOS 9.0. They allow to link content inside your app from other apps or from websites. Before reading any further we suggest you to read the Apple guides that will explain you what universal links are about, their capabilities, and how they can be integrated into your app. Please, head over to https://developer.apple.com/ios/universal-links/ to get an overview of universal links, and get access to Apple's developer guides. Universal links creates a two-way association between your app and your website. When your app is installed, iOS verifies the this association through a file on your website. This way it is impossible for other apps to claim the ownership of the URL and redirect your URLs. This point is very important and you should keep it in mind because, as you will see later, we will need to manipulate the URL received from the system before the call can be established.

Associated domains entitlement

The first step you must do, in order to support universal links is to add an "Associated domain entitlement" to your app. Open your project in Xcode, select your project file in the project navigator panel and click on the "Signing & Capabilities" tab. (In Xcode 10 and below the tab is named Capabilities).

Universal links step 1

Click on the "+" sign near "Capability" in the upper left side of the editor and select "Associated Domains" capability

Universal links step 2

You should be seeing something like this:

Universal links step 3

Now you are ready to add all the domains your app can open links from. If your app supports different subdomains you should list them all in the "Domains" box. If your app supports a lot of dynamic subdomains you can use a wildcard. Beware, any domain you add to your entitlements file, must have a corresponding apple-app-site-association file. If you use a wildcard, your apple-app-site-association file must be reacheable on the wildcard root host (i.e. if you use *.acme.com, the apple-app-site-association file must be reacheable at https://acme.com). When you click on the "+" sign in near the "Domains" box a new entry is added. You must replace the placeholder value Xcode adds for you with something like "applinks:NAME OF YOUR DOMAIN". In the picture below we added a wildcard entry for any URL pointing to "acme.com"

Universal links step 4

Apple app site association file

The next step to enable universal links support in your app, requires you to create a json file you must upload to your website. The json file you must upload must look like this:

{
    "applinks": {
        "apps": [],
        "details": [{
            "appID": "D3KQX62K1A.com.example.photoapp",
            "paths": ["/albums"]
            },
            {
            "appID": "D3KQX62K1A.com.example.videoapp",
            "paths": ["/videos"]
        }]
    }
}

For more information about the format of the json file and the format of each section of the file head over to Apple guide. Beware, the json file must be named "apple-app-site-association" without the file format extension and must be uploaded on your website root, or in the .well-known directory of your website. iOS expects this file to be reacheable without any redirects. For more info take a look at "Validate the Apple App Site Association File" section of this Apple guide.

Start the call

Now that you have set up your "two-way" association between your app and your website by means of your app entitlements and the apple-app-site-association file, you should be ready to open URLs pointing to resources of your website in your app. In your SceneDelegate you must implement the 'scene(_:, continue:)' method. This methow will be invoked by the operating system when a user taps on an a link with an URL your app claimed it can handle.

import KaleyraVideoSDK

final class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        guard userActivity.activityType == NSUserActivityTypeBrowsingWeb else { return }
        guard let url = userActivity.webpageURL else { return }
        guard scene.activationState == .foregroundActive else {
            pendingActivities.append(userActivity)
            return
        }
        KaleyraVideo.instance.conference?.join(url: url) { result in 
            debugPrint("Result \(result)")
        }
    }
}

Now that you are able to retrieve the URL received we can move to the next section of this guide which will explain how this URL can be handed to the SDK. The Kaleyra Video SDK can handle URLs in the following format:

https://ANY HOST WHATSOEVER/SOME PATH/rest-call-handler/ff8b0e6c3dfa949de451ed9317
https://ANY HOST WHATSOEVER/SOME PATH/direct-rest-call-handler/ff8b0e6c3dfa949de451ed9317
https://ANY HOST WHATSOEVER/SOME PATH/eu/direct-rest-call-handler/ff8b0e6c3dfa949de451ed9317
https://ANY HOST WHATSOEVER/SOME PATH/in/direct-rest-call-handler/ff8b0e6c3dfa949de451ed9317

For example the following URL will be handled by the sdk:

https://www.acme.com/call_with_bandyer/01/a/rest-call-handler/ff8b0e6c3dfa949de451ed9317
https://www.acme.com/call_with_bandyer/01/a/direct-rest-call-handler/ff8b0e6c3dfa949de451ed9317
https://www.acme.com/call_with_bandyer/01/a/eu/direct-rest-call-handler/ff8b0e6c3dfa949de451ed9317
https://www.acme.com/call_with_bandyer/01/a/in/direct-rest-call-handler/ff8b0e6c3dfa949de451ed9317

The following URL won't be handled by the sdk instead:

https://www.acme.com/call_with_bandyer/02/b/foo/bar/ff8b0e6c3dfa949de451ed9317

In order for Kaleyra Video SDK to open the URL you must make sure the URL you are passing to it has a path component ending either with /rest-call-handler/token or /direct-rest-call-handler/token.

Show the call user interface

Once the SDK has accepted the call, you can present its user interface as usual.

class MyViewController: UIViewController {

    private lazy var callWindow: CallWindow = .init(windowScene: view.window!.windowScene!)

    override func viewDidLoad() {
        super.viewDidLoad()

        KaleyraVideo.instance.conference?.callPublisher.compactMap({ $0 }).receive(on: DispatchQueue.main).sink { [weak self] call in
            self?.presentCall(call)
        }.store(in: &subscriptions)
    } 

    private func presentCall(_ call: Call) {
        let controller = CallViewController(call: call, configuration: .init(feedback: .init()))
        controller.delegate = self
        callWindow.makeKeyAndVisible()
        callWindow.set(rootViewController: controller, animated: true)
    }
}

extension MyViewController: CallViewControllerDelegate {

    func callViewControllerDidFinish(_ controller: CallViewController) {
        callWindow.set(rootViewController: nil, animated: true) { _ in
            self.callWindow.isHidden = true
        }
    }
}

Important

Beware, the code listing above omits any configuration code for the Kaleyra Video SDK. So, remember to configure the Kaleyra Video SDK first, and then, when you are ready, to connect the SDK. Only then you can start the call.

What's next

Clone this wiki locally