Link opens app even though it shouldn't

My apple-app-site-association file contains:

Code Block !json
{
"applinks": {
"apps": [],
"details": [
{
"appIDs": [ "..." ],
"components": [
{
"/": "/login/magic/*",
"?": { "app": "*" },
}
]
}
]
}
}


I verified that this pattern is showing up correctly in the simulator using sysdiagnose:

Code Block
Service:              applinks
App ID:               ...
App Version:          167.0
App PI:               <LSPersistentIdentifier 0x7fe5ad40d650> { v = 0, t = 0x8, u = 0x15c, db = F725A6E9-DD30-4041-9104-93C2B7BF848B, {length = 8, bytes = 0x5c01000000000000} }
Domain:              example.com
Patterns:             {"?":{"app":"*"},"/":"/login/magic/*"}
User Approval:        unspecified
Site/Fmwk Approval:   approved
Flags:                
Last Checked:         2021-02-05 13:09:31 +0000
Next Check:           2021-02-10 12:30:28 +0000


The issue i'm facing is the app is launching from URLs that do not include the requisite app parameter in the URL's query.

For example, these URLs launch the app when they shouldn't:

https://example.com/login/magic
https://example.com/login/magic/deadbeef?rot=ok

Am I misunderstanding something? Shouldn't the app only be opened if there's an app in the query string?

Accepted Reply

I've found the answer to my own question. Re-watching the WWDC'19 video "What's new in Universal Links", there was a tidbit mentioned:

Query items with no value and absent query items are treated by the operating system as if they have a value equal to the empty string.

I haven't seen this documented anywhere else, but to assert the presence of the app parameter correctly you must use:

Code Block
{
"/": "/login/magic/*",
"?": { "app": "?*" },
}


By requiring it to match at least one character forces the parameter to actually be a part of the URL. It's not clear how you would positively match a parameter that had no value. Luckily that doesn't apply in my case!

Replies

I've found the answer to my own question. Re-watching the WWDC'19 video "What's new in Universal Links", there was a tidbit mentioned:

Query items with no value and absent query items are treated by the operating system as if they have a value equal to the empty string.

I haven't seen this documented anywhere else, but to assert the presence of the app parameter correctly you must use:

Code Block
{
"/": "/login/magic/*",
"?": { "app": "?*" },
}


By requiring it to match at least one character forces the parameter to actually be a part of the URL. It's not clear how you would positively match a parameter that had no value. Luckily that doesn't apply in my case!