Импорт данных из Content Hub и URLdispatcher

"hooks": {
    "openstore": {
        "apparmor": "openstore/openstore.apparmor",
        "desktop": "openstore/openstore.desktop",
        "urls": "openstore/openstore.url-dispatcher",
        "content-hub": "openstore/openstore-contenthub.json"
    }
},

В предыдущем руководстве мы немного узнали о том, как работает Content Hub. В этом руководстве мы увидим, как работает URLdispatcher и как обрабатывать импортированные данные из Content Hub.

Обработка данных из Content Hub

../../_images/02ichu.png

Приложение OpenStore с сайта open-store.io

Один из самых простых способов тестирования приложения - отправить тестовый click-пакет в свою учётную запись Telegram и открыть этот файл в OpenStore через Content Hub:

../../_images/03ichu.png

Если мы попробуем запустить приложение из OpenStore, то система спросит, хотим ли мы установить click-файл. Давайте посмотрим на файл приложения Main.qml <https://github.com/UbuntuOpenStore/openstore-app/blob/master/openstore/Main.qml#L85> `_, чтобы узнать, как это делается:

Connections {
        target: ContentHub

        onImportRequested: {
            var filePath = String(transfer.items[0].url).replace('file://', '')
            print("Should import file", filePath)
            var fileName = filePath.split("/").pop();
            var popup = PopupUtils.open(installQuestion, root, {fileName: fileName});
            popup.accepted.connect(function() {
                contentHubInstallInProgress = true;
                PlatformIntegration.clickInstaller.installPackage(filePath)
            })
        }
}

Вы видите элементы Connections, которые относятся к ContentHub? Когда приложение получает сигнал onImportRequested, оно ищет url-адрес в данных, полученных от Content Hub (transfer.items[0].url- url-адрес первых отправленных пакетов данных) и откроет элемент PopUp, чтобы пользователь смог установить click-пакет.

Что можно сказать об URLdispatcher?

Диспетчер URL - это часть программного обеспечения, похожая на Content Hub, которая облегчает нашу жизнь, пытаясь выбрать правильное приложение для определенного протокола. Например: скорее всего, нужно открыть веб-браузер при нажатии на http-ссылку. Ссылку на карту удобнее открыть с помощью uNav, а ссылку на пост Twitter - в приложении Twitter. Как это работает?

URLdispatcher (Диспетчер URL) выбирает, какое приложение (согласно файлу manifest.json) откроет определенную ссылку.

../../_images/05ichu.png

Давайте посмотрим, как устроено навигационное приложение. В файле файле manifest.json приложения uNav показаны специальные хуки для `` URLdispatcher`` <https://bazaar.launchpad.net/~unav-devs/unav/trunk/view/head:/manifest.json#L9> `_:

1  [
2     {
3         "protocol": "http",
4         "domain-suffix": "map.unav.me"
5     },
6     {
7         "protocol": "http",
8         "domain-suffix": "unav-go.github.io"
9     },
10    {
11        "protocol": "geo"
12    },
13    {
14        "protocol": "http",
15        "domain-suffix": "www.openstreetmap.org"
16    },
17    {
18        "protocol": "http",
19        "domain-suffix": "www.opencyclemap.org"
20    },
21    {
22        "protocol": "https",
23        "domain-suffix": "maps.google.com"
24    }
25 ]

Это означает, что ссылка в формате http://map.unav.me/xxxxx ,xxxxx будет открыта в приложении uNav. Это определено в строках 2 и 3, где указан протокол http и приложение map.unav.me.

Кроме того, geo: xxx, xxx в формате URI должны открываться в uNav, как это определено в строке 11.

И как мы управляем полученным URL?

После того, как `` URLdispatcher`` отправит ссылку соответствующему приложению, нам нужно обработать этот URL или URI в целевом приложении. Давайте посмотрим, как это сделать:

In the main qml file, we need to add some code to know what to do with the dispatched URL. Let’s check how Linphone app manages this adding a connection to the URI Handler with a Connections element setting UriHandler as a target.

Connections {
    target: UriHandler

    onOpened: {
        console.log('Open from UriHandler')

        if (uris.length > 0) {
            console.log('Incoming call from UriHandler ' + uris[0]);
            showIncomingCall(uris[0]);
        }
    }
}

Этот код при открытии приложения будет передаваться URI в формате linphone://sip:xxx@xxx.xx. Но что нужно сделать, чтобы обработать эту ссылку, когда приложение закрыто?

Нам нужно добавить в исходный файл участок дополнительного кода, который будет описывать два случая: 1) получен один URL 2) Получено более одного URL

Давайте проверим, не пустой ли параметр Qt.application.arguments, и если нет, то соответствует ли какой-либо аргумент нашему формату URI.

Component.onCompleted: {
    //Check if opened the app because we have an incoming call
    if (Qt.application.arguments && Qt.application.arguments.length > 0) {

        for (var i = 0; i < Qt.application.arguments.length; i++) {
            if (Qt.application.arguments[i].match(/^linphone/)) {
                console.log("Incoming Call on Closed App")
                showIncomingCall(Qt.application.arguments[i]);
            }
        }
    }

    //Start timer for Registering Status
    checkStatus.start()
}

Не забудьте проверить, что% u (для получения 1 URL-адреса) или% U (для получения 1 или более URL-адресов) присутствует в строке Exec в файла приложения .desktop .

Tools

From command line, url-dispatcher-dump command will give you the full list of registered protocol schemes and their corresponding app.

Another usefull tool, but not installed by default on devices is url-dispatcher-tools, it allows you to simulate a call from a third party app. e.g: url-dispatcher https://youtu.be/CIX-a-i6B1w will launch youtube webapp.

To install, it make your partition writable (sudo mount -o rw,remount /) and install it via sudo apt install url-dispatcher-tools

Что произойдет, если для нескольких приложений определен один и тот же тип URL?

Очень хороший вопрос. Что произойдет, если мы нажмем на ссылку в Twitter? Как такой URL будет обрабатывать `` URLdispatcher``? Она будет воспринята как обычная ссылка `` http`` или как ссылка для приложения`` http: // twitter``?

Что произойдет, если один протокол определен для двух приложений?

Теперь пришло время сделать несколько тестов и обсудить результаты в следующей главе.