iOS/iOS Swift 개발 일기

Deep Link -target iOS 13 이하 대응

Developer-Michelle 2023. 4. 15. 15:02

Deep Link -target iOS 11.0 (iOS 13 이하 대응 필요한 경우 참고) (DeepLink를 AppDelegate에서 구현하는 방법)

 

딥링크

정확히는 custom scheme 구현이 필요하게 되었다.

 

고객이 본사 서버에서 작업된 특정 url 을 문자로 받아 해당 url을 Safari 또는 네이버 등등에 복사 + 붙여넣기를 하면,

해당 앱의 특정화면이 실행되게끔 해야 하는 것이 미션.


1) 사전작업:

프로젝트 - Info 부분에서 아래 URL types scheme 추가

 

왜 필요한가?

고객이 DeepLinkingDemo:// ~~ 로 시작하는 url을 받아서 접속시 우리 앱이 딱 실행되어야 하기 때문

 

 

2) 본격 코딩 작업

회사 앱 버전 target이 iOS 11 이므로 이를 고려해야 하는 이슈가 있었다.

iOS 13 이하 버전에서 SceneDelegate 작동하지 않으므로, App Delegate에서 모두 구현해보았다.

//  AppDelegate.swift

import UIKit

//iOS 11.0 target (13이하에서 SceneDelegate 동작 안하므로 AppDelegate에서 모두 구현)

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }
    
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        
        print(url)
        let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)
        let host = urlComponents?.host ?? ""
        print(host)
        if host == "customerdetail" { //url 주소 중에 customerdetail이 포함되어 있는 경우 특정 화면으로 이동 유도
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            guard let customerMessageVC = storyboard.instantiateViewController(withIdentifier: "CustomerMessageViewController") as? CustomerMessageViewController else {
                fatalError("Failed to instantiate CustomerMessageViewController from storyboard.")
            }
            customerMessageVC.customerId = urlComponents?.queryItems?.first?.value
            window?.rootViewController = customerMessageVC
        }
        
        return true
    }
}
//  ViewController.swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
       
    }

    @IBAction func nextBtnClicked(_ sender: UIButton) {
        
        let message = "Hi Deep Linking"
        let path = "DeepLinkingDemo://customerdetail?id=\(message)"
        let application = UIApplication.shared
        let appUrl = URL(string: path)
        let webUrl = URL(string: "https://bluemangoglobal.com")
        
        if application.canOpenURL(appUrl!) {
            application.open(appUrl!, options: [:], completionHandler: nil)
        } else {
            application.open(webUrl!)
        }
        
    }
    
}
//  CustomerMessageViewController.swift
import UIKit

class CustomerMessageViewController: UIViewController {

    @IBOutlet weak var customerIdLabel: UILabel!
    
    var customerId: String?
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        customerIdLabel.text = customerId

    }


}

왼쪽: ViewController

오른쪽: CustomerMessageViewController

 

Safari 웹 페이지에서 고객이 특정 링크로 타고 들어오면

DeepLinkingDemo://customerdetail?id=practice

해당 앱이 실행되면서 practice 가 CustomerMessageViewController 라벨에 빨간 글씨로 표시되면서 실행됨.

 

 

참고)

https://www.youtube.com/watch?v=IUA6BR-BUTY

https://www.youtube.com/watch?v=UcKdnFAIZPc 

 


* 해결되지 못한 부분

오늘까지 (23.4.15) 아직 서버가 완전 구현되지 않아 해당 방법이 확실하게 구현될 수 있는지 확인을 못함.

다음주 화요일까지 서버 작업 완료 예정이라고 했으니 그 날 붙여보고 되는지 확인 필요.

 

문제점: 서버에서 오는 url 주소는 https://~~~ 로 시작할 것임. 이렇게 되어도 과연 딥링크로 구현을 할 수 있는 것인가?

사실 애플 개발자 공식문서를 참고하면, Universial Link is strongly recommended 라고 되어 있다. 그런데 해당 방법은 웹뷰로 띄우는 거라 , 회사 가이드라인과 약간 차이가 있다. (서버에서 작업하려는 부분이 우리 앱이 설치되어 있다면 우리앱 실행, 그게 아니라면 앱스토어로 연결해서 설치 유도가 목적임)

 

참고) 유니버셜 링크는 위에 나온 딥링크와 구현방법이 다르다. 그리고 서버쪽에서 해줘야 하는 작업도 좀 다르고 , 애플 developer account 로 들어가서 몇 가지 설정이 필요해 보였다.

 


*해당 개발을 하면서 어려웠던 부분 및 삽질 부분

1) 처음에 아무 생각 없이 SceneDelegate에서 작업을 하고 있었다가 os13이하 버전에서 딥링크 구현이 안되는 것을 발견.

그래서 위와 같이 AppDelegate에서 작업하는 방법 알아낸 것임.

 

2) 이미 AppDelegate, SceneDelegate에 구글 로그인 및 카카오 로그인 관련 코드들이 open url 함수 부분에 들어있어서, 이 함수 부분에 무언가 내가 새로운 코드를 넣으면, 기존 로그인 관련 부분이 노란색으로 표시되며 '실행 절대 안될것이다' 라고 자꾸 떠서 해결 필요.


*해결방법

iOS 11 정도 되는 핸드폰으로 브레이크 포인트 다 걸어서 테스트 해봤는데

일단 SceneDelegate에서는 아무데도 안 잡히는걸 확인함.

 

 @available(iOS 13.0, *)

    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

 

        guard let url = URLContexts.first?.url else {return}

 

 @available(iOS 13.0, *)

    func sceneDidDisconnect(_ scene: UIScene) {

        print("sceneDidDisconnect Scene")

 

어쩌면 당연한 소리.. @available 13 이상인데 다..

 

https://gonslab.tistory.com/49