개발을 시작하는 이야기

URL Scheme를 활용하여 전화 걸기 본문

개발 이야기/Swift

URL Scheme를 활용하여 전화 걸기

Teiresias 2022. 6. 15. 18:51

원래는 카카오맵 연동을 먼저 쓰려고 했는데 연동까지는 했는데 그 활용이 아직은 좀 더 해봐야 해서 일단 먼저 작성한 전화 연결을 먼저 작성해봄.


iOS는 URL Scheme를 활용하여 메일, 전화, 문자 FaceTime등을 연결할 수 있었다.

 

Apple Developer Documentation

 

developer.apple.com

 

URL Scheme 적용 방법

URL Scheme 문자열을 통해 URL 인스턴스를 만들어주고, canOpenURL(_ :) 메서드를 활용해서 URL 체계를 처리할 수 있는지 여부를 확인한다.

let url = ...
func canOpenURL(_ url: URL) -> Bool
 

Apple Developer Documentation

 

developer.apple.com

사용 가능한 URL Scheme라면 open(_:options: completionHandler:) 메서드를 활용해 다른 앱을 열게 한다.

func open(_ url: URL, 
		  options: [UIApplication.OpenExternalURLOptionsKey : Any] = [:],
          completionHandler completion: ((Bool) -> Void)? = nil)
 

Apple Developer Documentation

 

developer.apple.com


이제 본격적으로 프로젝트에 적용을 해보자

@objc func callViewTapped() {
    let number: Int = viewModel.homeDetailNo.callNumber
    if let url = NSURL(string: "tel://0" + "\(number)"),
                       UIApplication.shared.canOpenURL(url as URL) {
        UIApplication.shared.open(url as URL, options: [:], completionHandler: nil)
    }
}

 

number는 Int로 받은 후, String으로 변경해주었는데, 바로 String으로 받는 경우는 모든 번호가 숫자로 이루어져 있는지 확인할 수 없기 때문에 Int로 받은 후 String으로 변경해주었다.

1. url문자열을 만들어 주고

2. canOpenURL(_ :) 메서드를 활용해서 처리 여부를 확인해주고

3. open(_:options: completionHandler:) 메서드를 호출해서 앱을 열어주었다.

 

이렇게만 되면 전화가 연결이 되지만. 통화가 종료되고 다시 돌아왔을 때, 화면을 이동시켜 주려고 했다.

NotificationCenter를 활용해서 백그라운드에서 돌아올때를 감지해 화면 전환을 시켜주었다.

override func viewDidLoad() {
    super.viewDidLoad()

	NotificationCenter.default.addObserver(self,
                                           selector: #selector(didEnterBackground),
                                           name: UIApplication.didEnterBackgroundNotification,
                                           object: nil)
}

화면이 백그라운드에서 돌아오면 didEnterBackground() 메서드를 실행하도록 되어있다.

@objc func didEnterBackground() {
    let vc = EnterBackgroundViewController()
    vc.modalPresentationStyle = .fullScreen
    self.present(vc, animated: true, completion: nil)
}

didEnterBackground() 메서드는 EnterBackgroundViewController로 전환을 실행하도록 해주었다.

여기서 문제가 발생했는데 처음에 viewDidLoad()에서 감지를 하도록 해주었더니 전화 화면에서 돌아오는것 뿐만 아니라 현재 화면에서 창을 내렸다가 돌아오는 동작에서도 감지를 해서 이동시켜주게 되었다.
@objc func callViewTapped() {
    self.checkEnterBackground()
    ...
}

private func checkEnterBackground() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(didEnterBackground),
                                           name: UIApplication.didEnterBackgroundNotification,
                                           object: nil)
}

그래서 전화를 연결하는 동작을 할때만 감지하도록 변경을 해주었더니 전화 화면으로 이동할때만 변경이 되도록 작동하게 되었다.

그리고 viewDidDisappear에서 옵저버를 해제해 주었다.

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(self)
}

이렇게 해주니 통화가 정상 작동을 해주었다. 생각보다 많이 복잡하지는 않아서 역시 고민하는 시간에 한번 해보는게 좋다는걸 다시금 깨닳음. 그리고 전화 연결은 시뮬레이터가 아닌 모바일로 연결해서 테스트 해야함.