[Flutter] Flutter Web Naver Maps JavaScript API v3 연동

Parrottkim·2023년 3월 9일
3
post-thumbnail

시작하기에 앞서

네이버 지도 API v3는 Flutter에서 IOS와 Android는 플러그인과 WebView를 이용해 사용할 수 있지만, 플러그인이 웹 환경을 지원하지 않아 네이버 지도를 띄울 수 없습니다.
Web Dynamic Map 서비스가 있지만, JavaScript로만 작동해서 Flutter에서 바로 사용할 수가 없습니다.
하지만 IFrameElement를 이용하면 웹 환경에서도 네이버 지도를 사용할 수 있게 됩니다.
이번 포스트에서는 API 사용 설정부터 웹 환경에서 네이버 지도 사용하는 방법까지 작성해보겠습니다.

API 사용 설정

https://www.ncloud.com/product/applicationService/maps
네이버 지도 API

이용 신청하기 및 결제 수단 등록이 끝나면 콘솔 창으로 넘어가게 됩니다.우측 화면 하단 Application 등록 버튼을 눌러줍니다.
Application 이름과 사용할 API인 Web Dynamic Map을 선택해줍니다.

서비스 환경 등록 부분은 반드시 웹서버 URL일 필요는 없습니다. Flutter Web 빌드 시의 #을 제외한 localhost와 포트 번호를 적어주면 됩니다.
(이 말은 빌드할 때마다 설정에서 URL을 변경해주셔야 한다는 말이기도 합니다.)

저장 버튼을 누르면 API 설정은 끝났습니다.

설정 후, 콘솔 화면에서 인증 정보 버튼을 클릭해줍니다.인증 정보의 Client ID가 있어야 지도 API를 사용할 수 있습니다. 나중에 사용할 정보이기 때문에 일단 저장해두도록 하겠습니다.

구현

pubspec.yaml

  assets:
    - assets/

pubspec.yaml 파일에서 에셋 경로를 추가해주고, Flutter 프로젝트 Root 폴더에도 assets 폴더를 생성해줍니다.

다음, assets/map.html 파일을 생성해준 다음, 아래와 같이 작성해줍니다.

assets/map.html

<script type="text/javascript" src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId=CLIENT_ID"></script>
<div id="map" style="width:100%;height:400px;"></div>
<script>
    var mapOptions = {
        center: new naver.maps.LatLng(35.855746, 128.489024),
        zoom: 16
    };
    var map = new naver.maps.Map('map', mapOptions);

    var marker = new naver.maps.Marker({
        position: new naver.maps.LatLng(35.855746, 128.489024),
        title: '계명대학교',
        map: map
    });

    var contentString = [
        '<div class="iw_inner" style="padding: 0px 20px 0px 20px">',
        '   <h3>계명대학교</h3>',
        '   <p>대구 달서구 신당동 산40-1<br>053-580-5114',
        '   </p>',
        '</div>'
    ].join('');

    var infowindow = new naver.maps.InfoWindow({
        content: contentString
    });

    naver.maps.Event.addListener(marker, "click", function (e) {
        if (infowindow.getMap()) {
            infowindow.close();
        } else {
            infowindow.open(map, marker);
        }
    });

    infowindow.open(map, marker);
</script>

필자는 계명대학교 출신이 아닐겁니다.

src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId=CLIENT_ID"
이 부분의 CLIENT_ID에 아까 네이버 API 콘솔에서 저장해 둔 Client ID를 입력해줍니다.

자세한 API 사용법은 NAVER Maps JavaScript API v3를 참고해주세요.

lib/main.dart

import 'dart:ui' as ui;
import 'dart:html';

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    // assets/map.html에서 작성한 네이버 지도 API 호출 후 
    // 응답받은 iframe을 IFrameElement라는 Flutter Widget으로 등록
    // ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
      'naver-map',
      (int viewId) => IFrameElement()
        ..style.width = '100%'
        ..style.height = '100%'
        ..src = 'assets/map.html'
        ..style.border = 'none',
    );

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('네이버 지도 API'),
      ),
      body: Center(
        child: SizedBox(
          height: MediaQuery.of(context).size.height,
          width: double.infinity,
          // 등록된 IFrameElement Widget들 중 
          //'naver-map'라는 이름을 가진 개체를 Widget으로 임베딩
          child: HtmlElementView(viewType: 'naver-map'),
        ),
      ),
    );
  }
}

간단하게 다음과 같이 구현한 뒤, 실행해보면...


정상적으로 지도를 불러왔고, 확대 및 축소와 같은 기능도 정상적으로 작동합니다.

배포를 하고 싶다면 배포하기 전 web/assets/map.html 경로로 넣어두고 빌드해야 누락되지 않고 함께 배포됩니다.

LIVE DEMO

Github Repository

profile
Flutter developer

8개의 댓글

comment-user-thumbnail
2023년 3월 9일

👍🏻👍🏻

답글 달기
comment-user-thumbnail
2023년 3월 9일

🙋‍♂️🙋‍♂️

답글 달기
comment-user-thumbnail
2023년 3월 29일

사랑해요 감사합니다

답글 달기
comment-user-thumbnail
2024년 1월 30일

dart에서 받은 좌표를 사용해서 표시할수도 있나요 ?

1개의 답글
comment-user-thumbnail
2024년 8월 14일

안녕하세요 flutter 로 naver map api 를 활용해서 실시간 사용자 위치 좌표를 받아와서 표시하는 기능이 있는 프로젝트를 개발중에 있습니다. 혹시 실시간으로 interaction이 가능할지 문의드리고 싶습니다. 혹은 위의 프로젝트의 깃허브 주소를 알 수 있을까요?

1개의 답글