chore(flow): expand host-return whitelist and add a DEBUG host bundle probe
- Rebuild the return-to-host whitelist from the CN/US top charts plus Apple system apps; drop the canOpenURL pre-check (LSApplicationQueriesSchemes is capped at 50) and let open() report failure. - Never record an OSG bundle id as the host to return to. - DEBUG only: probe the host bundle id through the keyboard arbiter callback and surface the log on a Home test card. Release builds keep the previous behaviour (no host identification).
This commit is contained in:
@@ -3,6 +3,10 @@
|
||||
//
|
||||
// Public URL-scheme whitelist for returning to a known host app after a
|
||||
// cold-start Flow session handoff. One bundle id maps to one preferred URL.
|
||||
//
|
||||
// Bundle ids are checked against the App Store lookup API. URL schemes have no
|
||||
// public source of truth; a wrong one only makes the open fail (the user stays
|
||||
// in OSG), it never sends the user to a different app.
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -25,287 +29,159 @@ public struct HostAppEntry: Sendable, Equatable {
|
||||
}
|
||||
|
||||
public enum HostAppURLRegistry {
|
||||
/// Curated whitelist for high-frequency host apps (IM, work, notes).
|
||||
/// Curated whitelist: high-frequency typing hosts first, then the CN / US
|
||||
/// App Store top charts, then Apple system apps.
|
||||
public static let entries: [HostAppEntry] = [
|
||||
// Tier 1 — China IM / work
|
||||
HostAppEntry(
|
||||
bundleId: "com.tencent.xin",
|
||||
displayNameKey: "hostApp.wechat",
|
||||
returnURLString: "weixin://",
|
||||
tier: 1
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.tencent.mqq",
|
||||
displayNameKey: "hostApp.qq",
|
||||
returnURLString: "mqq://",
|
||||
tier: 1
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.tencent.wework",
|
||||
displayNameKey: "hostApp.wecom",
|
||||
returnURLString: "wxwork://",
|
||||
tier: 1
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.laiwang.DingTalk",
|
||||
displayNameKey: "hostApp.dingtalk",
|
||||
returnURLString: "dingtalk://",
|
||||
tier: 1
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.bytedance.ee.lark",
|
||||
displayNameKey: "hostApp.lark",
|
||||
returnURLString: "lark://",
|
||||
tier: 1
|
||||
),
|
||||
// Tier 2 — global IM / collaboration
|
||||
HostAppEntry(
|
||||
bundleId: "ph.telegra.Telegraph",
|
||||
displayNameKey: "hostApp.telegram",
|
||||
returnURLString: "tg://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "net.whatsapp.WhatsApp",
|
||||
displayNameKey: "hostApp.whatsapp",
|
||||
returnURLString: "whatsapp://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "jp.naver.line",
|
||||
displayNameKey: "hostApp.line",
|
||||
returnURLString: "line://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.facebook.Messenger",
|
||||
displayNameKey: "hostApp.messenger",
|
||||
returnURLString: "fb-messenger://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.tinyspeck.chatlyio",
|
||||
displayNameKey: "hostApp.slack",
|
||||
returnURLString: "slack://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.microsoft.skype.teams",
|
||||
displayNameKey: "hostApp.teams",
|
||||
returnURLString: "msteams://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.hammerandchisel.discord",
|
||||
displayNameKey: "hostApp.discord",
|
||||
returnURLString: "discord://",
|
||||
tier: 2
|
||||
),
|
||||
// Tier 3 — notes / mail / browser
|
||||
HostAppEntry(
|
||||
bundleId: "notion.id",
|
||||
displayNameKey: "hostApp.notion",
|
||||
returnURLString: "notion://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "net.shinyfrog.bear",
|
||||
displayNameKey: "hostApp.bear",
|
||||
returnURLString: "bear://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "md.obsidian",
|
||||
displayNameKey: "hostApp.obsidian",
|
||||
returnURLString: "obsidian://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.agiletortoise.Drafts5",
|
||||
displayNameKey: "hostApp.drafts",
|
||||
returnURLString: "drafts5://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.google.Gmail",
|
||||
displayNameKey: "hostApp.gmail",
|
||||
returnURLString: "googlegmail://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.microsoft.Office.Outlook",
|
||||
displayNameKey: "hostApp.outlook",
|
||||
returnURLString: "ms-outlook://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.google.chrome.ios",
|
||||
displayNameKey: "hostApp.chrome",
|
||||
returnURLString: "googlechrome://",
|
||||
tier: 3
|
||||
),
|
||||
// Tier 4 — China social
|
||||
HostAppEntry(
|
||||
bundleId: "com.sina.weibo",
|
||||
displayNameKey: "hostApp.weibo",
|
||||
returnURLString: "sinaweibo://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.xingin.discover",
|
||||
displayNameKey: "hostApp.xiaohongshu",
|
||||
returnURLString: "xhsdiscover://",
|
||||
tier: 4
|
||||
),
|
||||
// Tier 2 (cont.) — global IM / calls
|
||||
HostAppEntry(
|
||||
bundleId: "org.whispersystems.signal",
|
||||
displayNameKey: "hostApp.signal",
|
||||
returnURLString: "sgnl://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.iwilab.KakaoTalk",
|
||||
displayNameKey: "hostApp.kakaotalk",
|
||||
returnURLString: "kakaotalk://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.viber",
|
||||
displayNameKey: "hostApp.viber",
|
||||
returnURLString: "viber://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.vng.zaloapp",
|
||||
displayNameKey: "hostApp.zalo",
|
||||
returnURLString: "zalo://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.skype.skype",
|
||||
displayNameKey: "hostApp.skype",
|
||||
returnURLString: "skype://",
|
||||
tier: 2
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "us.zoom.videomeetings",
|
||||
displayNameKey: "hostApp.zoom",
|
||||
returnURLString: "zoomus://",
|
||||
tier: 2
|
||||
),
|
||||
// Tier 3 (cont.) — notes / mail / browser
|
||||
HostAppEntry(
|
||||
bundleId: "com.culturedcode.ThingsiPhone",
|
||||
displayNameKey: "hostApp.things",
|
||||
returnURLString: "things://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.todoist.ios",
|
||||
displayNameKey: "hostApp.todoist",
|
||||
returnURLString: "todoist://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.evernote.iPhone.Evernote",
|
||||
displayNameKey: "hostApp.evernote",
|
||||
returnURLString: "evernote://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.microsoft.onenote",
|
||||
displayNameKey: "hostApp.onenote",
|
||||
returnURLString: "onenote://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.readdle.smartemail",
|
||||
displayNameKey: "hostApp.spark",
|
||||
returnURLString: "readdle-spark://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "org.mozilla.ios.Firefox",
|
||||
displayNameKey: "hostApp.firefox",
|
||||
returnURLString: "firefox://",
|
||||
tier: 3
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.microsoft.msedge",
|
||||
displayNameKey: "hostApp.edge",
|
||||
returnURLString: "microsoft-edge://",
|
||||
tier: 3
|
||||
),
|
||||
// Tier 4 (cont.) — global / China social
|
||||
HostAppEntry(
|
||||
bundleId: "com.facebook.Facebook",
|
||||
displayNameKey: "hostApp.facebook",
|
||||
returnURLString: "fb://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.burbn.instagram",
|
||||
displayNameKey: "hostApp.instagram",
|
||||
returnURLString: "instagram://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.atebits.Tweetie2",
|
||||
displayNameKey: "hostApp.x",
|
||||
returnURLString: "twitter://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.burbn.barcelona",
|
||||
displayNameKey: "hostApp.threads",
|
||||
returnURLString: "barcelona://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.toyopagroup.picaboo",
|
||||
displayNameKey: "hostApp.snapchat",
|
||||
returnURLString: "snapchat://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.reddit.Reddit",
|
||||
displayNameKey: "hostApp.reddit",
|
||||
returnURLString: "reddit://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "pinterest",
|
||||
displayNameKey: "hostApp.pinterest",
|
||||
returnURLString: "pinterest://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.zhihu.ios",
|
||||
displayNameKey: "hostApp.zhihu",
|
||||
returnURLString: "zhihu://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "tv.danmaku.bili",
|
||||
displayNameKey: "hostApp.bilibili",
|
||||
returnURLString: "bilibili://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.ss.iphone.ugc.Aweme",
|
||||
displayNameKey: "hostApp.douyin",
|
||||
returnURLString: "snssdk1128://",
|
||||
tier: 4
|
||||
),
|
||||
HostAppEntry(
|
||||
bundleId: "com.zhiliaoapp.musically",
|
||||
displayNameKey: "hostApp.tiktok",
|
||||
returnURLString: "tiktok://",
|
||||
tier: 4
|
||||
)
|
||||
app("com.tencent.xin", "wechat", "weixin://", tier: 1),
|
||||
app("com.tencent.mqq", "qq", "mqq://", tier: 1),
|
||||
app("com.tencent.ww", "wecom", "wxwork://", tier: 1),
|
||||
app("com.laiwang.DingTalk", "dingtalk", "dingtalk://", tier: 1),
|
||||
app("com.bytedance.ee.lark", "lark", "lark://", tier: 1),
|
||||
app("com.tencent.meeting", "tencentMeeting", "wemeet://", tier: 1),
|
||||
app("com.tencent.qqmail", "qqmail", "qqmail://", tier: 1),
|
||||
app("com.kingsoft.www.office.wpsoffice", "wps", "wpsoffice://", tier: 1),
|
||||
|
||||
// Tier 2 — global IM / calls / dating
|
||||
app("ph.telegra.Telegraph", "telegram", "tg://", tier: 2),
|
||||
app("net.whatsapp.WhatsApp", "whatsapp", "whatsapp://", tier: 2),
|
||||
app("jp.naver.line", "line", "line://", tier: 2),
|
||||
app("com.facebook.Messenger", "messenger", "fb-messenger://", tier: 2),
|
||||
app("com.tinyspeck.chatlyio", "slack", "slack://", tier: 2),
|
||||
app("com.microsoft.skype.teams", "teams", "msteams://", tier: 2),
|
||||
app("com.hammerandchisel.discord", "discord", "discord://", tier: 2),
|
||||
app("org.whispersystems.signal", "signal", "sgnl://", tier: 2),
|
||||
app("com.iwilab.KakaoTalk", "kakaotalk", "kakaotalk://", tier: 2),
|
||||
app("com.viber", "viber", "viber://", tier: 2),
|
||||
app("vn.com.vng.zingalo", "zalo", "zalo://", tier: 2),
|
||||
app("us.zoom.videomeetings", "zoom", "zoomus://", tier: 2),
|
||||
app("com.cardify.tinder", "tinder", "tinder://", tier: 2),
|
||||
|
||||
// Tier 3 — notes / mail / browser / office / AI
|
||||
app("notion.id", "notion", "notion://", tier: 3),
|
||||
app("net.shinyfrog.bear", "bear", "bear://", tier: 3),
|
||||
app("md.obsidian", "obsidian", "obsidian://", tier: 3),
|
||||
app("com.agiletortoise.Drafts5", "drafts", "drafts5://", tier: 3),
|
||||
app("com.culturedcode.ThingsiPhone", "things", "things://", tier: 3),
|
||||
app("com.todoist.ios", "todoist", "todoist://", tier: 3),
|
||||
app("com.evernote.iPhone.Evernote", "evernote", "evernote://", tier: 3),
|
||||
app("com.microsoft.onenote", "onenote", "onenote://", tier: 3),
|
||||
app("com.microsoft.Office.Word", "word", "ms-word://", tier: 3),
|
||||
app("com.microsoft.Office.Excel", "excel", "ms-excel://", tier: 3),
|
||||
app("com.google.Gmail", "gmail", "googlegmail://", tier: 3),
|
||||
app("com.microsoft.Office.Outlook", "outlook", "ms-outlook://", tier: 3),
|
||||
app("com.readdle.smartemail", "spark", "readdle-spark://", tier: 3),
|
||||
app("com.yahoo.Aerogram", "yahooMail", "ymail://", tier: 3),
|
||||
app("com.google.Docs", "googleDocs", "googledocs://", tier: 3),
|
||||
app("com.google.Sheets", "googleSheets", "googlesheets://", tier: 3),
|
||||
app("com.google.Drive", "googleDrive", "googledrive://", tier: 3),
|
||||
app("com.google.Translate", "googleTranslate", "googletranslate://", tier: 3),
|
||||
app("com.google.GoogleMobile", "google", "google://", tier: 3),
|
||||
app("com.google.chrome.ios", "chrome", "googlechrome://", tier: 3),
|
||||
app("org.mozilla.ios.Firefox", "firefox", "firefox://", tier: 3),
|
||||
app("com.microsoft.msedge", "edge", "microsoft-edge://", tier: 3),
|
||||
app("com.openai.chat", "chatgpt", "chatgpt://", tier: 3),
|
||||
app("com.anthropic.claude", "claude", "claude://", tier: 3),
|
||||
|
||||
// Tier 4 — China social / content
|
||||
app("com.sina.weibo", "weibo", "sinaweibo://", tier: 4),
|
||||
app("com.xingin.discover", "xiaohongshu", "xhsdiscover://", tier: 4),
|
||||
app("com.zhihu.ios", "zhihu", "zhihu://", tier: 4),
|
||||
app("tv.danmaku.bilianime", "bilibili", "bilibili://", tier: 4),
|
||||
app("com.ss.iphone.ugc.Aweme", "douyin", "snssdk1128://", tier: 4),
|
||||
app("com.ss.iphone.ugc.aweme.lite", "douyinLite", "snssdk2329://", tier: 4),
|
||||
app("com.jiangjia.gif", "kuaishou", "kwai://", tier: 4),
|
||||
app("com.kuaishou.nebula", "kuaishouLite", "ksnebula://", tier: 4),
|
||||
app("com.ss.iphone.article.News", "toutiao", "snssdk141://", tier: 4),
|
||||
app("com.douban.frodo", "douban", "douban://", tier: 4),
|
||||
app("com.baidu.BaiduMobile", "baidu", "baiduboxapp://", tier: 4),
|
||||
app("com.youku.YouKu", "youku", "youku://", tier: 4),
|
||||
app("com.tencent.live4iphone", "tencentVideo", "tenvideo://", tier: 4),
|
||||
app("com.qiyi.iphone", "iqiyi", "iqiyi://", tier: 4),
|
||||
app("com.hunantv.imgotv", "mangoTV", "imgotv://", tier: 4),
|
||||
app("com.tencent.QQMusic", "qqMusic", "qqmusic://", tier: 4),
|
||||
app("com.netease.cloudmusic", "neteaseMusic", "orpheus://", tier: 4),
|
||||
app("com.kugou.kugou1002", "kugou", "kugouURL://", tier: 4),
|
||||
app("com.gemd.iting", "ximalaya", "iting://", tier: 4),
|
||||
app("com.tencent.weread", "weread", "weread://", tier: 4),
|
||||
|
||||
// Tier 4 — global social / content
|
||||
app("com.facebook.Facebook", "facebook", "fb://", tier: 4),
|
||||
app("com.burbn.instagram", "instagram", "instagram://", tier: 4),
|
||||
app("com.atebits.Tweetie2", "x", "twitter://", tier: 4),
|
||||
app("com.burbn.barcelona", "threads", "barcelona://", tier: 4),
|
||||
app("com.toyopagroup.picaboo", "snapchat", "snapchat://", tier: 4),
|
||||
app("com.reddit.Reddit", "reddit", "reddit://", tier: 4),
|
||||
app("pinterest", "pinterest", "pinterest://", tier: 4),
|
||||
app("com.zhiliaoapp.musically", "tiktok", "tiktok://", tier: 4),
|
||||
app("com.google.ios.youtube", "youtube", "youtube://", tier: 4),
|
||||
app("com.linkedin.LinkedIn", "linkedin", "linkedin://", tier: 4),
|
||||
app("com.tumblr.tumblr", "tumblr", "tumblr://", tier: 4),
|
||||
app("tv.twitch", "twitch", "twitch://", tier: 4),
|
||||
app("com.spotify.client", "spotify", "spotify://", tier: 4),
|
||||
app("com.netflix.Netflix", "netflix", "nflx://", tier: 4),
|
||||
app("com.lemon.lvoverseas", "capcut", "capcut://", tier: 4),
|
||||
app("com.duolingo.DuolingoMobile", "duolingo", "duolingo://", tier: 4),
|
||||
|
||||
// Tier 5 — China shopping / local services / travel / finance
|
||||
app("com.taobao.taobao4iphone", "taobao", "taobao://", tier: 5),
|
||||
app("com.taobao.tmall", "tmall", "tmall://", tier: 5),
|
||||
app("com.360buy.jdmobile", "jd", "openapp.jdmobile://", tier: 5),
|
||||
app("com.xunmeng.pinduoduo", "pinduoduo", "pinduoduo://", tier: 5),
|
||||
app("com.taobao.fleamarket", "xianyu", "fleamarket://", tier: 5),
|
||||
app("com.alibaba.wireless", "alibaba1688", "wireless1688://", tier: 5),
|
||||
app("com.vipshop.iphone", "vipshop", "vipshop://", tier: 5),
|
||||
app("com.meituan.imeituan", "meituan", "imeituan://", tier: 5),
|
||||
app("com.meituan.itakeaway", "meituanWaimai", "meituanwaimai://", tier: 5),
|
||||
app("me.ele.ios.eleme", "eleme", "eleme://", tier: 5),
|
||||
app("com.dianping.dpscope", "dianping", "dianping://", tier: 5),
|
||||
app("com.taofang.iphone", "wuba", "wbmain://", tier: 5),
|
||||
app("com.xiaojukeji.didi", "didi", "diditaxi://", tier: 5),
|
||||
app("com.autonavi.amap", "amap", "iosamap://", tier: 5),
|
||||
app("com.baidu.map", "baiduMap", "baidumap://", tier: 5),
|
||||
app("com.tencent.sosomap", "tencentMap", "qqmap://", tier: 5),
|
||||
app("ctrip.com", "ctrip", "ctrip://", tier: 5),
|
||||
app("com.baidu.netdisk", "baiduNetdisk", "baiduyun://", tier: 5),
|
||||
app("com.ucweb.iphone.lowversion", "ucBrowser", "ucbrowser://", tier: 5),
|
||||
app("com.tencent.mttlite", "qqBrowser", "mttbrowser://", tier: 5),
|
||||
app("com.alipay.iphoneclient", "alipay", "alipay://", tier: 5),
|
||||
app("com.unionpay.chsp", "unionpay", "upwallet://", tier: 5),
|
||||
app("com.cmbchina.MPBBank", "cmb", "cmbmobilebank://", tier: 5),
|
||||
app("com.ccb.ccbDemo", "ccb", "ccbmobilebank://", tier: 5),
|
||||
app("com.bankabc.iphonerelease", "abc", "bankabc://", tier: 5),
|
||||
|
||||
// Tier 5 — US shopping / local services / finance
|
||||
app("com.amazon.Amazon", "amazon", "com.amazon.mobile.shopping://", tier: 5),
|
||||
app("com.walmart.electronics", "walmart", "walmart://", tier: 5),
|
||||
app("com.ebay.iphone", "ebay", "ebay://", tier: 5),
|
||||
app("com.alibaba.iAliexpress", "aliexpress", "aliexpress://", tier: 5),
|
||||
app("com.ubercab.UberClient", "uber", "uber://", tier: 5),
|
||||
app("com.zimride.instant", "lyft", "lyft://", tier: 5),
|
||||
app("doordash.DoorDashConsumer", "doordash", "doordash://", tier: 5),
|
||||
app("com.airbnb.app", "airbnb", "airbnb://", tier: 5),
|
||||
app("com.google.Maps", "googleMaps", "comgooglemaps://", tier: 5),
|
||||
app("com.yourcompany.PPClient", "paypal", "paypal://", tier: 5),
|
||||
app("net.kortina.labs.Venmo", "venmo", "venmo://", tier: 5),
|
||||
app("com.squareup.cash", "cashApp", "cashme://", tier: 5),
|
||||
|
||||
// Tier 6 — Apple system apps. Safari has no scheme that reopens the
|
||||
// current tab (every https/x-web-search URL opens a new page), so it is
|
||||
// deliberately absent.
|
||||
app("com.apple.MobileSMS", "messages", "messages://", tier: 6),
|
||||
app("com.apple.mobilenotes", "notes", "mobilenotes://", tier: 6),
|
||||
app("com.apple.mobilemail", "mail", "message://", tier: 6),
|
||||
app("com.apple.reminders", "reminders", "x-apple-reminderkit://", tier: 6),
|
||||
app("com.apple.mobilecal", "calendar", "calshow://", tier: 6),
|
||||
app("com.apple.shortcuts", "shortcuts", "shortcuts://", tier: 6),
|
||||
app("com.apple.DocumentsApp", "files", "shareddocuments://", tier: 6),
|
||||
app("com.apple.Maps", "maps", "maps://", tier: 6),
|
||||
app("com.apple.AppStore", "appStore", "itms-apps://", tier: 6)
|
||||
]
|
||||
|
||||
private static func app(_ bundleId: String, _ name: String, _ url: String, tier: Int) -> HostAppEntry {
|
||||
HostAppEntry(bundleId: bundleId, displayNameKey: "hostApp.\(name)", returnURLString: url, tier: tier)
|
||||
}
|
||||
|
||||
private static let byBundleId: [String: HostAppEntry] = {
|
||||
Dictionary(uniqueKeysWithValues: entries.map { ($0.bundleId, $0) })
|
||||
}()
|
||||
@@ -315,15 +191,10 @@ public enum HostAppURLRegistry {
|
||||
return byBundleId[bundleId]
|
||||
}
|
||||
|
||||
/// URL schemes declared in `LSApplicationQueriesSchemes` for `canOpenURL`.
|
||||
public static var querySchemes: [String] {
|
||||
Array(
|
||||
Set(
|
||||
entries.compactMap { entry -> String? in
|
||||
guard let url = entry.returnURL, let scheme = url.scheme else { return nil }
|
||||
return scheme
|
||||
}
|
||||
)
|
||||
).sorted()
|
||||
/// OSG's own targets (host app, keyboard, Mac) are never a return destination.
|
||||
public static func isOwnBundleId(_ bundleId: String) -> Bool {
|
||||
bundleId == ownBundleIdRoot || bundleId.hasPrefix(ownBundleIdRoot + ".")
|
||||
}
|
||||
|
||||
private static let ownBundleIdRoot = "com.osgkeyboard"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user