Skip to content

Developer notes

  • Add-on (app/addons/kv_mobile_app/): configuration per storefront company (?:kv_mapp_config; Multi-Vendor uses company 0), devices (?:kv_mapp_devices), campaigns (?:kv_mapp_campaigns), one queue row per campaign and device (?:kv_mapp_queue, also the inbox), devices of orders (?:kv_mapp_order_devices).
  • Native shells (app/addons/kv_mobile_app/resources/shell/): templates of the Android (Java, AndroidX, Material, Firebase Messaging, Play In-App Review) and iOS (Swift, UIKit, WKWebView, Firebase via Swift Package Manager) projects. Tygh\Addons\KvMobileApp\Builder fills the {{KV:...}} tokens (escaped per file type), renames the Java package folder, renders icons with GD and writes config.json.
  • Push: Fcm signs a JWT (RS256, OpenSSL) with the service account, exchanges it for an OAuth token (cached encrypted until 5 minutes before it expires) and sends one FCM HTTP v1 request per device. UNREGISTERED drops the token, 429/5xx leave the rest of the queue for the next run.
  • hooks/index/links.post.tpl prints a small inline script and the hide CSS. The script adds kv-mapp, kv-mapp--android|ios and data-kv-mapp-dispatch to <html> when the user agent contains KvMobileApp/ (or in the admin preview frame). The markup is the same for every visitor, so the full page cache (4.21) stays shared.
  • js/addons/kv_mobile_app/func.js (only inside the app): window.KvMapp.send(type, data) posts to the shell (KvMappAndroid.postMessage / webkit.messageHandlers.kvmapp). Messages: ready (url, title, dispatch), cart (count), share (url, title), rate. The shell calls KvMapp.onDevice(device) after each page load; the script registers the device with kv_mobile_app.register at most once a day or when something changed, and stores the device ID in the kv_mapp_did cookie (used to link guest orders).
  • Theme CSS for the app only: html.kv-mapp .your-selector { ... }.
Dispatch Method Answer
kv_mobile_app.config GET {ok, config} live configuration (tabs, colours, hosts, rules, required versions)
kv_mobile_app.register POST device_id (32 hex), platform, token, push, app_version, build, os_version; links the signed-in customer
kv_mobile_app.state GET {ok, cart, signed_in} for the badges
kv_mobile_app.inbox GET device_id, limit: {ok, items: [{id, title, body, image, url, time, opened}]}
kv_mobile_app.opened POST device_id, campaign_id
/.well-known/assetlinks.json, /.well-known/apple-app-site-association GET routed by schemas/routes/objects.post.php

All answers are JSON with Cache-Control: no-store (association files: 1 hour). None of these dispatches is cached by the full page cache. With the add-on switched off or unlicensed the app endpoints answer {ok: false} and the apps keep working as plain store apps.

place_order (links the app that placed the order), change_order_status (order pushes), init_templater_post (upgrade synchronizer). Admin console cron: php admin.php --dispatch=kv_mobile_app.cron (--limit, --seconds).

KV_MAPP_FCM_TOKEN_URL and KV_MAPP_FCM_SEND_URL (in local_conf.php) point the FCM client at a test server. The Android debug build has DebugPushActivity to show a notification without Firebase.