Tìm hiểu Universal Links trong iOS (Phần 2)

phần 1, chúng ta đã tìm hiểu khái quát về Universal Link và cách setup. Ở phần này ta sẽ tìm hiểu cách handle Universal Link.

Hosting AASA File ở Domain

Ta có thể host AASA file ở https://<yourdomain>/apple-app-site-association hoặc tại https://<yourdomain>/.well-known/apple-app-site-association. Upload apple-app-site-association file đến HTTPS web server. Ta có thể đặt file tại root của server hoặc tại .well-known subdirectory. Khi host AASA file ta cần đảm bảo:

  • Server là HTTPS
  • Dùng application/json MIME type
  • Không thêm .json vào apple-app-site-association filename.
  • Size không quá 128 Kb

Support nhiều Apps cùng Domain

Để làm điều này ta cần new appID, path dictionary trong AASA file giống như sau:

{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appID": "ABCXYZ.com.facebook.ios",
        "paths": [ "NOT /e/*", "*", "/", “/archives/201?/* ]
      },
      {
         "appID": "DEF.com.twitter.ios",
         "paths": [ "NOT /e/*", "*", "/", “/archives/200?/* ]
      }
    ]
  }
}

Nếu có 2 hoặc nhiều apps liên kết với cùng content path trên website thì thứ tự của appID, paths dictionary trong array sẽ xác định app nào sẽ được ưu tiên.

APPLE APP SITE ASSOCIATION (AASA) VALIDATOR

Vào link bên dưới và nhập domain vào, nó sẽ giúp ta check nếu AASA file valid và access

https://branch.io/resources/aasa-validator/#resultsbox

Handle Universal Links

Khi user nhấn vào universal link, iOS sẽ launch app và send nó 1 NSUserActivity object mà ta có thể truy cập để tìm hiểu làm thế nào mà app được launch.

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
            let webpageURL = userActivity.webpageURL!
         }
}

Ta có thể check xem các component trong url

func queryParameters(from url: URL) -> [String: String]  {
    let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)
    var queryParams = [String: String]()
    for queryItem: URLQueryItem in (urlComponents?.queryItems)!  {
        if queryItem.value == nil {
            continue
         }
        queryParams[queryItem.name] = queryItem.value
    }
    return queryParams
}

Ngoài ra ta có thể kiểm tra nếu app được mở bằng cách click vào universal link ở didFinishLaunchingWithOptions

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
        var isUniversalLinkClick: Bool = false
        if launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey] {
            let activityDictionary = launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey] as? [AnyHashable: Any] ?? [AnyHashable: Any]()
            let activity = activityDictionary[“UIApplicationLaunchOptionsUserActivityKey”] as? NSUserActivity ?? NSUserActivity()
            if activity != nil {
                isUniversalLinkClick = true
            }
        }
        if isUniversalLinkClick {
            // app opened via clicking a universal link.
        } else {
            // set the initial viewcontroller
        }
        return true
    }
  • Khi user tap vào universal link, iOS cũng sẽ kiểm tra các lựa chọn gần đây của user để xác định xem có mở app hay web không. VD: user đã tap vào universal link để mở app có thể sau đó chọn để mở website trong safari bằng cách tap vào 1 nút hình bánh xe trên status bar. Sau khi user thực hiện lựa chọn này iOS sẽ tiếp tục mở website trong safari cho đến khi user chọn mở app bằng cách tap vào OPEN trong Smart App Banner trên trang web.
  • Nếu bạn tạo instantiate SFSafariViewController, WKWebView, hay UIWebView để handle 1 universal link, iOS sẽ mở website ở Safary thay vì mở app. Tuy nhiên, nếu user tap vào universal link bên trong SFSafariViewController, WKWebView, hay UIWebView, iOS sẽ mở app.
  • Điều quan trọng là phải hiểu rằng nếu app dùng openURL: để mở 1 universal link đến website của bạn, link sẽ không mở trong app. Trong trường hợp này, iOS nhận ra rằng cuộc gọi đến từ app của ta và vì vậy không có handle như 1 universal link bởi app.

Test

Add Universal link vào email hoặc lưu vào note trên device. Khi thực hiện sẽ có rất nhiều vấn đề xảy ra. Vì vậy, hãy ghi nhớ những điều sau khi thực hiện và test:

  • Paste Universal link vào Safary sẽ không làm cho app tự động mở. Nếu làm vậy ta phải tự kéo trang web xuống để 1 thanh nhắc nhở xuất hiện ở top và hỏi rằng có muốn mở app lên ko.
  • Nhưng nếu ta paste link vào Facebook(app), Twitter(app), Mail(app) hoặc ngay cả khi truy cập Facebook trên Safary và sau đó click vào Universal link, app sẽ được mở ra.
  • Tuy vậy, Universal link sẽ không work cho tất cả các app trong iOS. Nếu ta click vào Universal link từ bất kỳ "black list" app, app sẽ không được mở.
  • Như bước 1, lần đầu tiên ta phải kéo trang web xuống và nhấn vào "Open" để mở link dùng ứng dụng tương ứng. iOS sẽ nhở để mở app thay vì mở Safary nếu Universal link đã đăng ký được nhấp vào.