π 2019.11.18 (μ)
WWDC2019 | Session : 717 | Category : Networking
π What's New in Universal Links - WWDC 2019 - Videos - Apple Developer
- μΉκ³Ό μ±μ resource λ₯Ό κ°λ¦¬ν€λ Apple OSκ° μΈμνλ http λλ https λ‘ λ URL μ¬μ©μκ° μ±μ μ€μΉνλ, λ€μ΄ λ°μ§ μμλ, νλμ URLμ μ½ν μΈ λ₯Ό λννλ€.
- μ±κ³Ό μΉμ¬μ΄νΈ κ° μμ νκ² μ°κ΄ λμ΄ μλ€. λν ν μ μλ λλ©μΈμ json νμμΌλ‘ μλ²μμ κ°μ§κ³ μκ³ , μ±μμ λλ©μΈμ μ μ©νλ©΄ λλ€.
- custom URL scheme μ universal linkλ‘ λ°κΎΈλ κ²μ κΆμ₯νλ€. cutom URLμ λ³Έμ§μ μΌλ‘ μννκ³ μ μμ μΈ κ°λ°μλ€μ μν΄ μ μ© λ μ μλ€.
- μΉ μλ²μμλ μ ν¨ν HTTPS μΈμ¦μκ° μμ΄μΌ νλ€.
- apple-app-site-association νμΌμ μΆκ°νλ€.
μ ν λλ°μ΄μ€μ μ±μ μ€μΉνλ©΄ μ΄μ체μ κ° μλ²κ° μ΄λ€ μλΉμ€λ₯Ό μ±μμ μ¬μ©νκ² ν μ§ κ²°μ νκΈ° μν΄ μ΄ νμΌμ λ€μ΄λ‘λ νλ€.
https://example.com/.well-known/apple-app-site-association
μ μ μ₯λμ΄μΌ νλ€.
apple-app-site-association file
{
"applinks": {
"apps": [],
"details": [
{
"appID": "ABCDE12345.com.example.app",
"path": ["/path/*/filename"]
"components": [
{
"/": "/path/*/filename",
"#": "*fragment",
"?": { "widget": "?*", "grommet": "please" }
},
{
{"/": "/taco/*", "exclude": true}
}
]
}
]
},
}
- iOS 13, tvOS13, macOS 10.15 λ₯Ό νκ²ν νλ€λ©΄ appsλ μ κ±° κ°λ₯νλ€.
- appID : App Identifier β Appleμμ μ 곡λ 10μ리 μ«μ.bundleID, λ°°μ΄λ‘ μ¬λ¬ μ±μμ κ°μ universal link μ¬μ© κ°λ₯
- path β components λ‘ λ체λ¨
- URL fragment component λ₯Ό # ν€λ‘, query ? λ‘ λμ ν μ μλ€. query itemμ dictionaryλ‘ λνλΌ μ μλ€.
"exclude": true
μ μ μΈ
- URL κ³Ό pattern-matchingμ ASCII
- μ§μνλ λͺ¨λ κ΅κ°μ λν country-specific pattern μ΄ νμνλ€.
{ "en", "fr", "mx", ... } β "??" {"en_US", "fr_CA", "de_CH", ...} β "??_??"
- .com, .net, .org, ccTLD μ°μ μμ
Project β add Associated Domains
<array>
<string>applinks:www.exapmle.com</string>
<string>applinks:*.exapmle.com</string>
<string>applinks:xn--fhqz97e.exapmle.xn--fiqs8s</string>
</array>
More specific subdomains have higher priority
Internationalized domains must be encoded as Punycode
func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL,
let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
return false
}
for queryItem in components.queryItems ?? [] {
...
}
return true
}
UIApplication
UIApplication.shared.open(url, options: [.universalLinksOnly: true]) {
...
}
NSWorkspace
let configuration = NSWorkspace.OpenConfiguration()
configuration.requiresUniversalLinks = true
NSWorkspace.shared.open(url, configuration: configuration) {
...
}
- Fail gracefully κΈ°κ°μ΄ λ§λ£ λμκ±°λ, μ ν¨νμ§ μκ±°λ, μ‘΄μ¬νμ§ μλ μ½ν μΈ μΌ λ universal linkκ° μ±μμ μ΄ μ μλ€λ©΄, Safari View Controllerλ₯Ό ν΅ν΄ μ΄μ΄ μ£Όμ. μ΅μν μ΄λ€ μ΄μ μΈμ§ νμ ν΄μ£Όμ.
- Use the Smart App Banner μ¬μ©μκ° μΉμ λ°©λ¬Ένλ€λ©΄, smart bannerλ₯Ό μ¬μ©ν΄μ μ±μ€ν μ΄λ μ±μ μ½ν μΈ λ‘ λ§ν¬λ₯Ό μ 곡νμ.