본문 바로가기
PROGRAMMING CODE/SWIFT

[SwiftUI] 다음(kakao) 주소찾기 part.1 (WKWebView, 웹 통신)

by daye_ 2023. 10. 19.

 

스윽 보기엔 웹사이트 배포도 하고 첫 웹통신이라 꽤 어려워보였는데, 생각보다 하고나니 진종일 붙들고 있을 정도는 아니었다

아주 좋은 자료가 있는 줄 알았지만

... 사람들이 극찬한 아래의 꼼꼼한 블로그는 UIkit 기반이라 좀 다름 ㅜ,ㅜ

 

 

https://kasroid.github.io/posts/ios/20200916-webkit-search-address-with-kakao-with-uikit/

 

WebKit - 카카오 우편번호 서비스 구현하기 with UIKit

본 포스팅은 Swift 5.3 기준으로 작성되었습니다. Intro 저는 요새 Market Kurly 앱을 클론하는 프로젝트를 진행하고 있는데요. 회원가입 부분에서 Kakao 우편변호 찾기 기능을 지원하더라고요. 사용자로

kasroid.github.io

 

 

 

[배포 참고자료]

 

Github Pages - 깃허브로 사이트 배포하기 ( Github Deploy )

제목 그대로 오늘은 깃허브를 이용해 사이트를 배포하는 법을 설명하겠다😎이미 많은 개발자 블로그에 소개가 되어 있는 내용이지만 깃허브 UI도 조금씩 변화가 있기 때문에 예전 UI 기반의 글

fe-paradise.tistory.com

 

 

 

1. 주소 검색 웹사이트 배포하기

1. index.html 파일 생성 후 아래 코드를 싹 긁어서 붙여넣고 저장 (지번, 도로명주소, 우편번호 만 필요한 경우)

2. 깃허브 레포지토리 판 후

3. 아래와 같이 하나만 띡 올림

4. 구글에 깃허브 웹사이트 배포 검색해서 해당 레포지토리 배포 하고 오기

 

 

index.html 파일은 웹사이트가 실행될 때 시작점을 알리는 파일.

swfitUI의 WindowGroup가 들어있는 App파일과 같다고 보면 됨!

 


index.html

<!DOCTYPE html>

<html lang="ko">
  <head>
    <title>주소 찾기</title>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width,height=device-height,initial-scale=1.0"
    />
  </head>
  <body onload="execDaumPostcode()">
    <div
      id="layer"
      style="display:block; position:absolute; overflow:hidden; z-index:1; -webkit-overflow-scrolling:touch; "
    ></div>
    <script src="https://spi.maps.daum.net/imap/map_js_init/postcode.v2.js"></script>
    <script>
      window.addEventListener("message", onReceivedPostMessage, false);

      function onReceivedPostMessage(event) {
        //..ex deconstruct event into action & params
        var action = event.data.action;
        var params = event.data.params;
        console.log("onReceivedPostMessage " + event);
      }

      function onReceivedActivityMessageViaJavascriptInterface(json) {
        //..ex deconstruct data into action & params
        var data = JSON.parse(json);
        var action = data.action;
        var params = data.params;
        console.log("onReceivedActivityMessageViaJavascriptInterface " + event);
      }

      function postMessageToiOS(postData) {
        window.webkit.messageHandlers.callBackHandler.postMessage(postData);
      }

      var element_layer = document.getElementById("layer");
      function execDaumPostcode() {
        new daum.Postcode({
          oncomplete: function (data) {
            var jibunAddress = "";

            if (data.jibunAddress == "") {
              jibunAddress = data.autoJibunAddress;
            } else if (data.autoJibunAddress == "") {
              jibunAddress = data.jibunAddress;
            }

            var postData = {
              roadAddress: data.roadAddress,
              jibunAddress: jibunAddress,
              zonecode: data.zonecode,
            };
            window.postMessageToiOS(postData);
          },
          width: "100%",
          height: "100%",
        }).embed(element_layer);
        element_layer.style.display = "block";
        initLayerPosition();
      }

      function initLayerPosition() {
        var width = window.innerWidth || document.documentElement.clientWidth;
        var height =
          window.innerHeight || document.documentElement.clientHeight;
        element_layer.style.width = width + "px";
        element_layer.style.height = height + "px";
        element_layer.style.left =
          ((window.innerWidth || document.documentElement.clientWidth) -
            width) /
            2 +
          "px";
        element_layer.style.top =
          ((window.innerHeight || document.documentElement.clientHeight) -
            height) /
            2 +
          "px";
      }
    </script>
  </body>
</html>

 

나머지는 웹 뷰 내용이니 , 대충 요 부분만 훑어봐도 됨

 

function postMessageToiOS(postData) {
        window.webkit.messageHandlers.callBackHandler.postMessage(postData);
 }

function execDaumPostcode() {
        new daum.Postcode({
          oncomplete: function (data) {
            var jibunAddress = "";

            if (data.jibunAddress == "") {
              jibunAddress = data.autoJibunAddress;
            } else if (data.autoJibunAddress == "") {
              jibunAddress = data.jibunAddress;
            }

            var postData = {
              roadAddress: data.roadAddress,
              jibunAddress: jibunAddress,
              zonecode: data.zonecode,
            };
            window.postMessageToiOS(postData);
       }

 

 

 

2. SwiftUI 내 통신 코드 작성

 

짱 중요

***userContentController가 들어있는 class의 이름

WebView의 init에서 호출되는 add(함수(), name "콜백") 함수의 이름이 같아야함****

 


KakaoWebController.swft

import SwiftUI
import WebKit

class KakaoWebController: NSObject, WKScriptMessageHandler {
    
    // didReceive, 데이터 받아오는 부분
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        
        if message.name == "callBackHandler", let data = message.body as? [String: Any] {
          if message.name == "callBackHandler" {
            print("message name : \(message.name)")
            print("post Message : \(message.body)")
        }
    }
}

struct WebView: UIViewRepresentable {
    let request: URLRequest
    private var webView: WKWebView?
    
    init(request: URLRequest) {
        self.webView = WKWebView()
        self.request = request
        self.webView?.configuration.userContentController.add(KakaoWebController(), name: "callBackHandler")
    
    }
    
    func makeUIView(context: Context) -> WKWebView {
        return webView!
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(request)
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    class Coordinator: NSObject, WKNavigationDelegate {
        let parent: WebView
        
        init(parent: WebView) {
            self.parent = parent
        }
    }
}

extension WebView {
    func callJS(_ args: Any = "") {
        webView?.evaluateJavaScript("postMessageToiOS('\(args)')") { result, error in
            if let error {
                print("Error \(error.localizedDescription)")
                return
            }
            
            if result == nil {
                print("It's void function")
                return
            }
            
            print("Received Data \(result ?? "")")
        }
    }
}

 

 

 

 

그리고 마지막으로 띄워야 할 UI뷰에

WebView(request: URLRequest(url: URL(string: "https://~~~~~.github.io/Kakao-Postcode/")!)

이렇게 호출해주면 끗!

 

 

 

 

 

이렇게 잘 불러와짐 !

 

 

이렇게 아무거나 검색해서 젤 위에 있는 우편번호 28562를 누르면

userContentController내부에서 print()해주었던 receive data들을 출력하게 됨!

 

 

 

 

 

(중간에 다른 데이터를 추가해서 이렇게 뜨는데, jinuAddress, roadAddress, zonecode 이렇게 세 가지가 뜰 것임!)

 

 

 

 

 

 

[참고자료]

https://nsios.tistory.com/158

 

[Swift] 다음(Kakao) 우편번호서비스

https://postcode.map.daum.net/guide#usage Daum 우편번호 서비스 우편번호 검색과 도로명 주소 입력 기능을 너무 간단하게 적용할 수 있는 방법. Daum 우편번호 서비스를 이용해보세요. 어느 사이트에서나 무

nsios.tistory.com

https://phillip5094.tistory.com/133

 

SwiftUI에서 WKWebView <-> JavaScript 상호작용

안녕하세요. 이번에는 SwiftUI 환경에서 WKWebView가 JavaScript의 함수를 호출하고, JavaScript가 WKWebView의 함수를 호출하는 방법에 대해 알아볼게요. iOS 전체 코드: https://github.com/phillip5094/SwiftUI-WebView-JS J

phillip5094.tistory.com

 

 

 

 

 

 

 

[다음 블로그]

https://da-ye.tistory.com/222

 

[SwiftUI] 다음(kakao) 주소찾기 (WKWebView, Sheet사용하기, Binding)

[전 블로그] https://da-ye.tistory.com/221 [SwiftUI] 다음(kakao) 주소찾기 (WKWebView, 웹 통신) 스윽 보기엔 웹사이트 배포도 하고 첫 웹통신이라 꽤 어려워보였는데, 생각보다 하고나니 진종일 붙들고 있을

da-ye.tistory.com