Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

iOS 개발일지

[iOS] WKWebView의 현재 URL을 감지하고, 이벤트를 발생시키자! 본문

iOS

[iOS] WKWebView의 현재 URL을 감지하고, 이벤트를 발생시키자!

Lia's iOS 2023. 11. 27. 11:40

WebView를 통해 이니시스 통합인증을 구현하려고 하니, 성공/실패에 대한 감지와 처리를 ViewController에서 해야 하네..?

인증에 성공 여부에 따라 WebView에서 던져주는 이벤트가 없으니, 인증 프로세스가 종료되었을 때 이동되는 URL에 따라 성공인지 실패인지 감지해야 했다.

 

다행히 WKNavigationDelegate에서 이러한 상황에 쓸 수 있는 함수를 제공해주니, 바로 사용해보도록 하자!

 

 

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if let url = navigationAction.request.url, url.absoluteString == "https://inisisAuth/failed" {
            // 실패 시 동작 실행
            decisionHandler(.cancel)
            
        } else if let url = navigationAction.request.url, url.absoluteString.contains("https://inisisAuth/success?txId="),
                  let txIdRange = url.absoluteString.range(of: "txId=") {
            let txId = url.absoluteString[txIdRange.upperBound...]
            // 성공 시 동작 실행
            decisionHandler(.cancel)
            
        } else {
            decisionHandler(.allow)
        }
    }

 

 

위 코드만으로도 매우 간단하게, 의도대로 동작하도록 구현할 수 있다.

조건을 하나씩 떼어서 어떤 동작을 하는지 들여다보자.

 

 

 

1. 인증 실패 시

        if let url = navigationAction.request.url, url.absoluteString == "https://inisisAuth/failed" {
            // 실패 시 동작 실행
            decisionHandler(.cancel)
        }

 

실패 URL은 임의의 값이니, 인증 실패 시 서버에서 이동시키는 url을 해당 자리에 넣으면 된다.

그리고 decisionHandler.cancel로 실행하여 탐색을 종료시킨다.

 

 

 

2. 인증 성공 시

        else if let url = navigationAction.request.url, url.absoluteString.contains("https://inisisAuth/success?txId="),
                  let txIdRange = url.absoluteString.range(of: "txId=") {
            let txId = url.absoluteString[txIdRange.upperBound...]
            // 성공 시 동작 실행
            decisionHandler(.cancel)
        }

 

마찬가지로 성공 URL은 임의의 값인데, 실패 코드와는 다른 부분이 있다.

바로 url.absoluteString == 이 아닌 url.absoluteString.contains를 통해 url을 비교하고 있다는 점이다.

성공 url에는 쿼리에 txId 정보를 담아서 보내주기 때문에 contains를 통해 전체 url에 "inisisAuth/success" 부분이 포함되어 있는지를 체크했다.

 

그리고 이 쿼리의 txId 정보를 캐치하기 위해

let txIdRange = url.absoluteString.range(of: "txId=")

let txId = url.absoluteString[txIdRange.upperBound...]

코드가 추가되었다.

 

이와 같은 형태로 url이 구성되어 있을 경우 "txId=" 자리에 txId 대신 다른 변수명을 넣으면 되겠다.

 

 

 

3. 그 외...

        else {
            decisionHandler(.allow)
        }

 

그 외 성공/실패가 아닌 일반적인 url의 경우에는 아무 동작도 넣지 않고, decisionHandler(.allow) 를 통해 탐색을 계속한다.

 

 

 

이렇게 언뜻 보면 어려워보이는 동작도 아주 간단하게 구현할 수 있다!