๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS

[iOS Swift] Deeplink ์‚ฌ์šฉํ•˜๊ธฐ

by ํ‹ด๋”” 2022. 12. 29.
728x90
๋ฐ˜์‘ํ˜•

1. URL scheme ์ง€์ •ํ•˜๊ธฐ

2. ๋”ฅ๋งํฌ ์ง€์ •ํ•˜๊ธฐ


1. URL scheme ์ง€์ •ํ•˜๊ธฐ

  • URL Scheme์€ url์ด ์‹œ์ž‘๋˜๊ธฐ ์ „ url ์•ž์— ๋ถ™๋Š” ํ”„๋ฆฌํ”ฝ์Šค ์ŠคํŠธ๋ง (์˜ˆ๋ฅผ ๋“ค์–ด https:// ๊ฐ€ ์žˆ์Œ)
  • ์•ฑ์ด ์„ค์น˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ
  • url์ด์ง€๋งŒ ์‚ฌํŒŒ๋ฆฌ์—์„œ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋‚ด ์•ฑ์— ์ง€์ •๋œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•จ

(1) ์•ฑ์—์„œ URL Scheme ๋“ฑ๋กํ•˜๊ธฐ

  • Info.plist ํŒŒ์ผ์— URL scheme ๋“ฑ๋ก
  • Info.plist > URL Types ์„น์…˜

  • Identifier์™€ ์‚ฌ์šฉ์ž ์ •์˜ ์Šคํ‚ด์„ ์ž…๋ ฅํ•ด ์คŒ
  • Identifier๋Š” ๋ฒˆ๋“ค id์™€ ๋™์ผ

(2) Schene delegate ๋ฉ”์†Œ๋“œ ์ •์˜ํ•˜๊ธฐ

  • ์•ฑ์— ๋”ฅ๋งํฌ ์ฒ˜๋ฆฌ ์š”์ฒญํ•˜๊ธฐ 
    • ์ฝ”๋“œ๋ ˆ๋ฒจ์—์„œ ํ•ด๋‹น ์ฝ”๋“œ ๋™์ž‘ ์‹œํ‚ค๋ฉด ๋จ
    • ํ˜น์€ ์‚ฌํŒŒ๋ฆฌ์˜ ์ฃผ์†Œ์ฐฝ์—์„œ ์ง€์ • ์Šคํ‚ด์„ ํฌํ•จํ•œ URL์„ ๊ฒ€์ƒ‰
let url = URL(string: "์‚ฌ์šฉ์ž์ง€์ •์Šคํ‚ด://path/")!
UIApplication.shared.open(url, options: [:], completionHandler: nil)
  • ์•ฑ์ด ๋”ฅ๋งํฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ผ๋Š” ์š”์ฒญ์„ ๋ฐ›์œผ๋ฉด ์•„๋ž˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•จ
    • SceneDelegate๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ scene(_:openURLContexts:)
    • AppDelegate๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ application(_:open:options:)
  • ์ผ๋ฐ˜ URL์ธ ๊ฒฝ์šฐ ์‚ฌํŒŒ๋ฆฌ๋กœ ํ•ด๋‹น ๋งํฌ๋ฅผ ์—ด๊ณ , ์‚ฌ์šฉ์ž ์ง€์ • ์Šคํ‚ด์ธ ๊ฒฝ์šฐ ์•ฑ์—๊ฒŒ ๋”ฅ ๋งํฌ ์ฒ˜๋ฆฌ ์š”์ฒญ

url ๊ตฌ์กฐ

    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let url = URLContexts.first?.url else { return }
        
        let scheme = url.scheme
        
        let host: String?
        if  #available(iOS 16.0, *) {
            host = url.host()
        } else {
            host = url.host
        }
        
        let path: String
        if #available(iOS 16.0, *) {
            path = url.path()
        } else {
            path = url.path
        }
        
        let components = url.pathComponents
    }
  • ์™œ Set<>์œผ๋กœ URLContexts๊ฐ€ ์˜ค๋Š”์ง€ ์ด์œ  ๋ชป ์ฐพ์Œ
  • path์™€ host ํ”„๋กœํผํ‹ฐ๋Š” deprecate ์˜ˆ์ •์ด๋ผ (์“ฐ๋Š”๋ฐ ๋ฌธ์ œ๋Š” ์—†์Œ ์•„์ง๊นŒ์ง€๋Š”.) Percent encoding ์˜ต์…˜์ด ํฌํ•จ๋œ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด path์™€ host๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Œ. ์ด๋Š” iOS 16 ๋ถ€ํ„ฐ ์ง€์›
  • pathComponents๋Š” path๋ฅผ /๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ String ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•จ. ์ธ๋ฑ์Šค 0์€ / ์ด๋‹ค (["/", "test", "10"] ๋‘ ๋ฒˆ์งธ, ์ธ๋ฑ์Šค๋กœ๋Š” 1๋ฒˆ ๋ถ€ํ„ฐ ์‚ฌ์šฉ)

2. ๋”ฅ๋งํฌ ์ง€์ •ํ•˜๊ธฐ

    func scene(_ scene: UIScene, willContinueUserActivityWithType userActivityType: String) {
        guard userActivity?.activityType == NSUserActivityTypeBrowsingWeb,
              let urlToOpen = userActivity?.webpageURL else {
            return
        }
        handleURL(urlToOpen)
    }
    
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let url = URLContexts.first?.url else { return }
        handleURL(url)
    }
    func handleURL(_ url: URL) {
        guard url.scheme == "mycustomscheme" else { return }
        
        let host: String?
        if  #available(iOS 16.0, *) {
            host = url.host()
        } else {
            host = url.host
        }
        
        let components = url.pathComponents
        
        switch host {
        ....
        }
    }
  • switch๋ฅผ ์‚ฌ์šฉํ•ด์„œ host์˜ ๊ฐ’์— ๋”ฐ๋ผ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Œ. host๊ฐ€ ๊ฐ™๊ณ  path๋กœ ๊ตฌ๋ถ„ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ url.pathComponents๋กœ ์–ป์€ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

 

  • ์•ฑ์ด ์ด๋ฏธ ์‹คํ–‰๋œ ๊ฒฝ์šฐ window์˜ rootViewController์— ํ™”๋ฉด์„ ํ‘ธ์‹œ
var router = AppCoordinator().strongRouter
guard let navigationController = router.viewController as? UINavigationController else { return }
  • xCoordinator์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ router์˜ viewController๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ
guard let navigationController = window?.rootViewController as? UINavigationController else { return }

 


์ฐธ๊ณ  ์‚ฌ์ดํŠธ

https://www.donnywals.com/handling-deeplinks-in-your-app/

https://ios-development.tistory.com/207

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€