https://github.com/cjk09083/ftweather
이전 포스트에서 Provider 라이브러리 추가 및 빌드를 성공하였다.
이번엔 Flutter 앱에 Naver maps를 추가하고 현재위치를 마커로 나타내보자.
기존에 사용하면 naver map 라이브러리 (https://github.com/LBSTECH/naver_map_plugin) 가 지원이 중단돼 새로운 라이브러리를 찾아보니 https://pub.dev/packages/flutter_naver_map 라이브러리가 개발중이였다.
다만 아직 베타버전이기 때문에 1.0 버전이 정식 출시되면 이전하도록 하고 이번 포스팅에선 기존 라이브러리 (LBSTECH)를 사용하였다.
1. 먼저 pubspec.yaml에 Dependencies 를 추가해준다.
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
provider: ^6.0.5
naver_map_plugin:
git: https://github.com/LBSTECH/naver_map_plugin.git
2. Naver Cloud (https://console.ncloud.com/naver-service/application) 에서 앱 등록후 Client ID 생성
3. AndroidManifest.xml에 권한, client ID 추가
<manifest>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application>
<meta-data
android:name="com.naver.maps.map.CLIENT_ID"
android:value="YOUR_CLIENT_ID_HERE" />
</application>
</manifest>
(https://wikidocs.net/168854 를 참고하여 client id가 github에 올라가지 않도록 조치)
4. iOS 설정
# info.plist 추가
<key>NMFClientId</key>
<string>$(NAVER_MAP_KEY)</string>
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>The app needs location permission</string>
위치권한을 얻어오기 위해 geolocator 패키지 사용
# pubspec.yaml
dependencies:
geolocator: ^9.0.2
# main.dart
import 'package:geolocator/geolocator.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await requestLocationPermission();
runApp(MyApp());
}
/* MyApp 정의 이후*/
// 위치 서비스 권한 요청 함수
Future<void> requestLocationPermission() async {
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// 사용자가 위치 권한을 거부한 경우 처리
return;
}
}
if (permission == LocationPermission.deniedForever) {
// 사용자가 위치 권한을 영구적으로 거부한 경우 처리
return;
}
// 권한이 허용된 경우 처리
}
(https://ggasoon2.tistory.com/18 를 참고하여 client id가 github에 올라가지 않도록 조치
-> .xcconfig 파일을 생성후 기존 ios/Flutter 폴더내에 있는 Debug.xcconfig 에 include 추가)
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
#include "secret.xcconfig"
5. Home.dart 수정
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:naver_map_plugin/naver_map_plugin.dart';
import 'MyModel.dart';
class Home extends StatelessWidget {
const Home({super.key});
final CameraPosition _mapPosition = const CameraPosition(
target: LatLng(37.5666805, 126.9784147),
zoom: 15,
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Weather App'),
),
body: Center(
child: NaverMap(
mapType: MapType.Hybrid,
initialCameraPosition: _mapPosition,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<MyModel>(context, listen: false).addMarker();
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
6. floatingButton을 누르면 현재 위치에 마커 추가가 되도록 수정
#Home.dart
import 'package:flutter/foundation.dart';
import 'package:naver_map_plugin/naver_map_plugin.dart';
import 'dart:developer';
class MyModel extends ChangeNotifier {
final TAG = "ftweather";
final CameraPosition _mapPosition = const CameraPosition(
target: LatLng(37.5666805, 126.9784147),
zoom: 15,
);
CameraPosition get mapPosition => _mapPosition;
NaverMapController? _controller;
final List<Marker> _markers = [];
List<Marker> get markers => _markers;
// NaverMapController 초기화
void setController(NaverMapController controller) {
_controller = controller;
}
Future<void> addMarker() async {
log("$TAG : addMarker");
if (_controller != null) {
CameraPosition currentCameraPosition = await _controller!.getCameraPosition();
log("$TAG : Pos $currentCameraPosition");
// 현재 위치에 마커 추가
final marker = Marker(
markerId: _markers.length.toString(),
position: currentCameraPosition.target,
);
_markers.add(marker);
}
notifyListeners();
}
}
#MyModel.dart
import 'package:flutter/foundation.dart';
import 'package:naver_map_plugin/naver_map_plugin.dart';
import 'dart:developer';
class MyModel extends ChangeNotifier {
final TAG = "ftweather"; // 로그 태그
// 초기 카메라 위치 설정
final CameraPosition _mapPosition = const CameraPosition(
target: LatLng(37.5666805, 126.9784147),
zoom: 15,
);
// 카메라 위치를 가져오는 getter
CameraPosition get mapPosition => _mapPosition;
// NaverMapController 변수
NaverMapController? _controller;
// 마커 목록 관리
final List<Marker> _markers = [];
List<Marker> get markers => _markers;
// NaverMapController 초기화 메서드
void setController(NaverMapController controller) {
_controller = controller;
}
// 현재 위치에 마커를 추가하는 메서드
Future<void> addMarker() async {
// 로그 출력
log("$TAG : addMarker");
// NaverMapController가 초기화되었는지 확인
if (_controller != null) {
// 현재 카메라 위치 가져오기
CameraPosition currentCameraPosition = await _controller!.getCameraPosition();
// 로그 출력
log("$TAG : Pos $currentCameraPosition");
// 현재 위치에 마커 추가
final marker = Marker(
markerId: _markers.length.toString(),
position: currentCameraPosition.target,
);
// 마커 목록에 추가
_markers.add(marker);
}
// 마커가 추가되었음을 알림
notifyListeners();
}
}
7. 빌드시 아래와 같이 앱이 동작되고, 버튼을 누르면 지도 중심에 마커가 추가된다.
'프로젝트들 > 날씨앱' 카테고리의 다른 글
[날씨앱] P5. Flutter file, func 분류 (0) | 2023.04.07 |
---|---|
[날씨앱] P4. Flutter fcm 알림 기능 추가 (iOS) (0) | 2023.04.06 |
[날씨앱] P3. Flutter fcm 알림 기능 추가 (Android) (0) | 2023.04.04 |
[날씨앱] P1. Flutter Provider 앱 생성 (0) | 2023.03.13 |
[날씨앱] Flutter 상태관리 프로젝트 (Provider / Bloc / GetX) (0) | 2023.03.13 |