flutter 다음 주소 검색 기능 적용

Hoseon Chu·2021년 7월 16일
0

flutter

목록 보기
2/5

플러터에서 kopo라는 좋은 패키지가 있지만
null safety를 지원하지 않아

다른방법을 찾던중...
원초적으로 다음주소 기능 자체가 html과 javascrip로 이루어져 있기 때문에

flutter 내에서 webview를 보여주고 그에 대한 컨트롤만 잘 하면 될거 같다는 생각이 들어 조사중 해당 사례가 있어 응용하여 적용해보기로 했다.

  1. flutter web_view 패키지 설치

Webview 패키지

웹뷰 플러그인은 말자체로 웹사이트를 flutter 내에서 자체적으로 생성하여 보여주는 것이다.

해당 웹사이트에 javascript도 허용이 가능하고
javascript채널을 리스닝 하여
listen 데이터를 처리 할 수 있게 해준다.

WebView buildWebView(BuildContext context) {
    return WebView(
      initialUrl: 'http://plinic.cafe24app.com/api/daumFlutterPost',
      javascriptMode: JavascriptMode.unrestricted,
      onWebViewCreated: (WebViewController webViewController) {
        _webViewController = webViewController;
        // _loadHtmlFromAssets();
      },
      javascriptChannels: <JavascriptChannel>{
        _toasterJavascriptChannel(context),
      },
    );
  }
JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: 'messageHandler',
        onMessageReceived: (JavascriptMessage message) {
          // print('------');
          // print(message.message);
          Get.back(result: message.message);
          // Navigator.pop(context, message.message);
        });
  }

여기서 확인 할 수 있듯이
javascript채널의 name 을 선언한 후 실제 웹사이트에 javascript에서 응답을 여기로 수신 할수 있는 채널명을 생성 할 수 있다.

  1. daum주소 api(html)생성 하기

다음주소가 제공하는 html을 이용하였고
여기서 특징은 일반적으로 이것을 그대로 flutter webview에 가저다 쓰게 되면

모바일 전용 화면에서 보는것이 아니 pc화면에서 보는듯한 비율로 접근하게 된다.(사이즈가 매우 작고 사용자가 컨트롤 하기가 불편해진다)

이를 해결하기 위해서

<html>
<head>
	<meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, 
</head>
<body>
  <div id="wrap" style="border:1px solid;width:100%;height:100%;margin:5px 0;position:relative"></div>

</body>
<script>

라는 내용을 추가해주어야지만 모바일 화면에서의 대응도 가능해진다.

  1. 리스너에 데이터 전달하기
new daum.Postcode({
      oncomplete: function (data) {
        // console.log(data);
        // 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
        messageHandler.postMessage(JSON.stringify(data));

라는 부분을 추가하여 아까 flutter에서 name : 'messageHandler'
라는 것을 추가 하였기 때문에

messageHandler.postMessage(JSON.stringify(data));
를 사용하면 다음 주소의 데이터 리스너에게 값을 전달 할 수 있게 된다.

이런 점을 잘 활용한다면은
webview가 상당히 활용가치가 높은것으로 보여진다.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    
</head>

<body>
  <div id="wrap" style="border:1px solid;width:100%;height:100%;margin:5px 0;position:relative"></div>

  <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>

  <script>
    // 우편번호 찾기 찾기 화면을 넣을 element
    var element_wrap = document.getElementById('wrap');

    function foldDaumPostcode() {
      // iframe을 넣은 element를 안보이게 한다.
      element_wrap.style.display = 'none';
    }

    // 현재 scroll 위치를 저장해놓는다.
    var currentScroll = Math.max(document.body.scrollTop, document.documentElement.scrollTop);
    new daum.Postcode({
      oncomplete: function (data) {
        // console.log(data);
        // 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
        messageHandler.postMessage(JSON.stringify(data));

        // 각 주소의 노출 규칙에 따라 주소를 조합한다.
        // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
        var addr = ''; // 주소 변수
        var extraAddr = ''; // 참고항목 변수

        //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
        if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
          addr = data.roadAddress;
        } else { // 사용자가 지번 주소를 선택했을 경우(J)
          addr = data.jibunAddress;
        }


        // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
        if (data.userSelectedType === 'R') {
          // 법정동명이 있을 경우 추가한다. (법정리는 제외)
          // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
          if (data.bname !== '' && /[동|로|가]$/g.test(data.bname)) {
            extraAddr += data.bname;
          }
          // 건물명이 있고, 공동주택일 경우 추가한다.
          if (data.buildingName !== '' && data.apartment === 'Y') {
            extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
          }
          // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
          if (extraAddr !== '') {
            extraAddr = ' (' + extraAddr + ')';
          }
        }
        element_wrap.style.display = 'none';

        // 우편번호 찾기 화면이 보이기 이전으로 scroll 위치를 되돌린다.
        document.body.scrollTop = currentScroll;
      },
      // 우편번호 찾기 화면 크기가 조정되었을때 실행할 코드를 작성하는 부분. iframe을 넣은 element의 높이값을 조정한다.
      onresize: function (size) {
        element_wrap.style.height = size.height + 'px';
      },
      width: '100%',
      height: '100%'
    }).embed(element_wrap);

  </script>
</body>

</html>
profile
개발자입니다

1개의 댓글

comment-user-thumbnail
2021년 8월 7일

안녕하세요!
제가 플러터로 주소 검색 찾다가 너무 많은 도움이 되어서 감사인사 남겨요!
감사합니다~

답글 달기