이전에 했던 프로젝트를 provider에서 riverpod으로 리팩토링중이다.
다른 프로젝트들을 차차 하다보니 코드가 얼마나 구린지 알 수 있었다.. 전부 다 내 코드는 아니였지만 내 코드마저 매우 구린것을 알 수 있었음
이전에는 한 페이지에 한 프로바이더로 모든 값을 한 프로바이더에서 관리했는데 정말 말도 안되는 코드..ㅋ
한 프로바이더 안에서 주는 값이 10개가 넘었다.
대부분은 리팩토링하는 과정에서 어려움을 겪지 않았다. (사실 나 천재? 라고 생각했엇음) 하지만! 지금 하고있는 라이딩과 네비게이션 부분은 값이 너~무 많아서 관리하기가 너무 어렵다.
정말 프로바이더가 몇개가 생기는지 모르겠다. 심지어 연결된 부분도 많아 프로바이더 결합도 굉장히 많음.
현재는 사용자 라이딩 트래킹을 위한 위치 스트림을 만들어야하는데 정말 애먹는 중이다. 이 위치로 처리하는게 정말 많아서 연결짓는 데에도 애먹는즁,,
먼저 위치 스트림을 제공해주는 LocationService. locationSetting도 이 서비스에서 한다.
class PositionService {
static final PositionService _instance =
PositionService._internal();
late LocationSettings _locationSettings;
static const int DISTANCE = 30;
static const int DURATION_SECNOD = 2;
factory PositionService() {
return _instance;
}
PositionService._internal() {
if (defaultTargetPlatform == TargetPlatform.android) {
_locationSettings = AndroidSettings(
accuracy: LocationAccuracy.high,
distanceFilter: DISTANCE,
forceLocationManager: true,
intervalDuration: const Duration(seconds: DURATION_SECNOD),
//(Optional) Set foreground notification config to keep the app alive
//when going to the background
foregroundNotificationConfig: const ForegroundNotificationConfig(
notificationText: "백그라운드에서 사용자의 위치를 수집중입니다.",
notificationTitle: "Riding-partner Running in Background",
enableWakeLock: true,
));
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
_locationSettings = AppleSettings(
accuracy: LocationAccuracy.high,
activityType: ActivityType.fitness,
distanceFilter: DISTANCE,
pauseLocationUpdatesAutomatically: true,
// Only set to true if our app will be started up in the background.
showBackgroundLocationIndicator: false,
);
} else {
_locationSettings = const LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: DISTANCE,
);
}
}
Stream<Position> position() {
return Geolocator.getPositionStream();
}
}
맨 아랫줄 보면 position 스트림을 제공한다
그리고 그 스트림을 받아 position 값을 제공하는 PositionProvider
class PositionProvider extends StateNotifier<Position?> {
PositionProvider() : super(null);
set state(Position? value) {
// TODO: implement state
super.state = value;
}
void getPosition() {
BackgroundLocationService().position().listen((event) {
state = event;
});
}
}
스트림에서 값을 받아 position 값을 제공해주고 있다
참고로 사용해주는 곳을 보면 나는 position값과 다른 state값을 받아 사용자가 이동중에 서비스를 이용할때, polyline으로 지도에 라인을 그려주는 작업을 하는데, 그 라인은 LatLng 리스트로 이루어진다
// 위치 provider
final positionProvider = StateNotifierProvider<PositionProvider, Position?>(
(ref) => PositionProvider());
//polyline provider
final polylineCoordinatesProvider = StateProvider<List<LatLng>>((ref) => []);
// 주행 상태 provider
final ridingStateProvider = StateProvider((ref) => RidingState.before);
// polyline 생성 provider
final **provider = Provider((ref) {
final state = ref.watch(ridingStateProvider);
final position = ref.watch(positionProvider);
if (state == RidingState.riding && position != null) {
var polylist = ref.read(polylineCoordinatesProvider);
polylist.add(LatLng(position.latitude, position.longitude));
ref.read(polylineCoordinatesProvider.notifier).state = polylist;
}
});
이것만 봐도.... 프로바이더가 4개가 생성된다 사실 실제 프로젝트에서는 position이 이 부분 말고도 많이 쓰이지만 polyline을 중심으로 보기만 해도 4개가 필요한 상황이다.
riverpod을 공부하다보면 riverpod 결합을 굉장히 많이 쓰게돼서 효율적으로 provider를 결합하고 관리하는 법에 대해 공부가 많이 필요한 것 같다.
굉장히 느리게 가고 화질도 안좋아서 구불구불 별로지만,,,, 이런 느낌이다
타이머를 걸어서 일정 시간에 한번만 값을 추가해 polyline을 그리면 더 깔끔한 라인이 나올듯 싶다 position이 변할때마다 하니 쉽지 않은듯 싶다