카테고리 없음

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

냄수 2021. 7. 10. 18:41
반응형


https://postcode.map.daum.net/guide#usage

 

Daum 우편번호 서비스

우편번호 검색과 도로명 주소 입력 기능을 너무 간단하게 적용할 수 있는 방법. Daum 우편번호 서비스를 이용해보세요. 어느 사이트에서나 무료로 제약없이 사용 가능하답니다.

postcode.map.daum.net

회원가입할때 많이보던 기능이죠
주소를 검색해서 넣을 수 있어요!!

하 지 만
그냥 텍스트로도 할 수 있지만 그러면 정확도가 좋지않으니... 유효성 문제가 있을 수 있어요
클라이언트 입장에서 이 작업을 하기엔 쉽지않기 때문에 다른 API를 가져다 쓰거나 노가다.. 코딩을 통해 구현하죠

카카오 우편번호 서비스는
무료이고
key같은것을 발급 받지않아도되고
사용량 제한도 없어요!
그렇기 때문에 많이 사용하고 있는것같아요

문서를 보면
스크립트...
html..
iOS개발을 하는 사람에겐 익숙치않은 언어에 문법이죠 ㅎㅎ

클라이언트에 추가하는게아니라
웹으로 구현후!
웹뷰로 가져다가 클라이언트에 사용할 수 있는 그런 방식이더라구요!!

전 Xcode내에서 html파일을 넣어서 했는데
화면도 잘뜨고 검색도 잘돼는데 클릭하면 주소가 왜 전달이 안돼나 삽질을 좀오래했던... ㅠ

이슈에 보니 file:// 도메인은 작동이 안됀다하더라구요 (주소클릭시 어떤주소인지 이벤트를 받아야 하는데 그 이벤트가 처리가안돼요ㅠ)
그래서 웹페이지를 꼭 만들어야 해요

참조하려고했더니 많은 사이트들이 웹구현이라서 찾기가힘들더라구요
문서보면서 따라했는데... 구현은 됬지만 실행이안됬어요

<script src="http://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
    daum.postcode.load(function() {
        new daum.Postcode({
            oncomplete: function(data) {

            }
        }).embed();
    });


    const daum__layer_2 = document.getElementById('__daum__layer_1');
    daum__layer_2.style.width = "100%";

    const daum__layer_1 = document.getElementById('__daum__layer_2');
    daum__layer_1.style.width = "100%";

</script>

기본적으로 위의코드처럼 구현을 하라고 하는데
여기서 문제인게 우선 주소가 이상하더라구요
내부적으로 구현할땐 잘됬는데
웹페이지를 만들어서 저 주소를쓰면 빈화면이뜨고
참고한 블로그에는

https://spi.maps.daum.net/imap/map_js_init/postcode.v2.js

문서와 다르게 이 주소를 사용하고 있었어요
이주소를 사용하면 화면이 잘보였어요 (왜지...)

문서최신화가 안된건가..
문서를 보고하면 구현 실패할 확률이 높아요 ㅎㅎ

아무튼!!
전 웹페이지를 올릴 서버를 또 생성하는게 귀찮았기때문에
깃페이지를 이용했구요
깃이 아니여도 웹사이트 만들듯이 하나 만드시면돼요!!

깃페이지를 만드는 법은 간단하게
레포를 하나 생성하고!
Setting메뉴에서 아래로 가다보면
GitHub Pages메뉴가 보이고
check it out here을 눌러보세요!

그러면 아래같이 Source창에 브렌치선택하는 란이있는데
main root save!
하면 주소가나와요
그주소가이제 웹페이지 주소가됩니다

다음으로 html파일을 만들건데
add file -> create new file클릭

이 html이
우편번호 서비스가 보여질 화면이에요

index.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 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>

전 html을 잘모르기때문에..
필요없는 것은 지우고 가져왔어요...

바로적용이 안돼요 조금기다려야해서
30초인가 그쯤 여유롭게 기다렸다가 새로고침하면
드디어..!


깃허브 웹사이트의 주소를 사용해서 웹뷰로 띄우면 끝이에요!

웹뷰를 만들어주는데
주의해야할게 이벤트명을 맞춰줘야해요

import UIKit
import WebKit

class ViewController: UIViewController {

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

    func webView() {
        guard let htmlFileURL = Bundle.main.path(forResource: "postcode", ofType: "html") else {
            return
        }
        let gitURL = URL(string: "https://namsoo5.github.io/pracPostcode")!
        let url = gitURL
        let request = URLRequest(url: url)
        let configure = WKWebViewConfiguration()
        let contentController = WKUserContentController()
        contentController.add(self, name: "callBackHandler")
        configure.userContentController = contentController
        
        let webview = WKWebView(frame: UIScreen.main.bounds, configuration: configure)
        webview.uiDelegate = self
        webview.navigationDelegate = self
        webview.load(request)
        view.addSubview(webview)
    }
}

extension ViewController: WKNavigationDelegate {
    
}
extension ViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        print("✅✅✅✅✅")
        print(message.name)
        if let data = message.body as? [String: Any] {
            print(data["address"])
            print(data["bcode"])
        }
        
    }
}


contentController.add(self, name: "callBackHandler")
하는 부분이 있는데
callBackHandler이벤트가 날라오면
userContentController가 실행되는것을 등록시킨거에요

callBackHandler은 js에서 (js -> swift)

window.webkit.messageHandlers.callBackHandler.postMessage(postData);

이렇게보내죠
messageHandlers.callBackHandler.postMessage(postData);
이 이름을 꼭 맞춰줘야 이벤트를 잘 전달받을수 있어요 보내는 데이터는 postData!

제일위에 있는 리스트를 클릭하면

이벤트가 잘 전달되네요!!
이제 이값으로 클라이언트에서 원하는 작업을 진행하면 됩니다!




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

반응형