Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions example/src/components/MapWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import type {
RNMapUiSettings,
RNMapZoomConfig,
RNRegion,
RNIndoorBuilding,
RNIndoorLevel,
} from 'react-native-google-maps-plus';
import {
GoogleMapsView,
RNAndroidLocationPriority,
type RNIndoorBuilding,
type RNIndoorLevel,
RNIOSLocationAccuracy,
RNIOSLocationActivityType,
RNLocationErrorCode,
RNMapErrorCode,
} from 'react-native-google-maps-plus';
Expand Down Expand Up @@ -103,6 +104,7 @@ export default function MapWrapper(props: Props) {
ios: {
desiredAccuracy: RNIOSLocationAccuracy.ACCURACY_BEST,
distanceFilterMeters: 10,
activityType: RNIOSLocationActivityType.NAVIGATION,
},
}),
[]
Expand Down
2 changes: 2 additions & 0 deletions example/src/components/maptConfigDialog/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
RNAndroidLocationPermissionResult,
RNAndroidLocationPriority,
RNIOSLocationAccuracy,
RNIOSLocationActivityType,
RNIOSPermissionResult,
RNLocationErrorCode,
RNMapErrorCode,
Expand Down Expand Up @@ -272,6 +273,7 @@ const RNAndroidLocationConfigValidator = object({
export const RNIOSLocationConfigValidator = object({
desiredAccuracy: optional(enums(enumValues(RNIOSLocationAccuracy))),
distanceFilterMeters: optional(number()),
activityType: optional(enums(enumValues(RNIOSLocationActivityType))),
});

export const RNLocationConfigValidator = object({
Expand Down
51 changes: 46 additions & 5 deletions example/src/screens/LocationScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,55 @@
import React, { useRef } from 'react';
import React, { useRef, useState } from 'react';
import MapWrapper from '../components/MapWrapper';
import ControlPanel from '../components/ControlPanel';
import type { GoogleMapsViewRef } from 'react-native-google-maps-plus';
import {
type GoogleMapsViewRef,
RNAndroidLocationPriority,
RNIOSLocationAccuracy,
RNIOSLocationActivityType,
type RNLocationConfig,
} from 'react-native-google-maps-plus';
import { RNLocationConfigValidator } from '../components/maptConfigDialog/validator';
import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog';
import { useHeaderButton } from '../hooks/useHeaderButton';
import { useNavigation } from '@react-navigation/native';

export default function LocationScreen() {
const mapRef = useRef<GoogleMapsViewRef | null>(null);
const navigation = useNavigation();
const [locationConfig, setLocationConfig] = useState<RNLocationConfig>({
android: {
priority: RNAndroidLocationPriority.PRIORITY_HIGH_ACCURACY,
interval: 5000,
minUpdateInterval: 5000,
},
ios: {
desiredAccuracy: RNIOSLocationAccuracy.ACCURACY_BEST,
distanceFilterMeters: 10,
activityType: RNIOSLocationActivityType.NAVIGATION,
},
});
const [dialogVisible, setDialogVisible] = useState(true);

useHeaderButton(navigation, 'Edit', () => setDialogVisible(true));

return (
<MapWrapper mapRef={mapRef} myLocationEnabled>
<ControlPanel mapRef={mapRef} buttons={[]} />
</MapWrapper>
<>
<MapWrapper
mapRef={mapRef}
myLocationEnabled
locationConfig={locationConfig}
>
<ControlPanel mapRef={mapRef} buttons={[]} />
</MapWrapper>

<MapConfigDialog<RNLocationConfig>
visible={dialogVisible}
title="Edit marker"
initialData={locationConfig}
validator={RNLocationConfigValidator}
onClose={() => setDialogVisible(false)}
onSave={(c) => setLocationConfig(c)}
/>
</>
);
}
12 changes: 7 additions & 5 deletions ios/GoogleMapViewImpl.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import CoreLocation
import GoogleMaps
import GoogleMapsUtils
import UIKit
import NitroModules
import UIKit

final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate,
GMSIndoorDisplayDelegate {
Expand Down Expand Up @@ -273,10 +273,12 @@ GMSIndoorDisplayDelegate {
@MainActor
var locationConfig: RNLocationConfig? {
didSet {
locationHandler.desiredAccuracy =
locationConfig?.ios?.desiredAccuracy?.toCLLocationAccuracy
locationHandler.distanceFilterMeters =
locationConfig?.ios?.distanceFilterMeters
locationHandler.updateConfig(
desiredAccuracy: locationConfig?.ios?.desiredAccuracy?
.toCLLocationAccuracy,
distanceFilterMeters: locationConfig?.ios?.distanceFilterMeters,
activityType: locationConfig?.ios?.activityType?.toCLActivityType,
)
}
}

Expand Down
52 changes: 32 additions & 20 deletions ios/LocationHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,19 @@ private let kCLLocationAccuracyDefault: CLLocationAccuracy =
kCLLocationAccuracyBest
private let kCLDistanceFilterNoneDefault: CLLocationDistance =
kCLDistanceFilterNone
private let kCLActivityTypeDefault: CLActivityType = .other

final class LocationHandler: NSObject, CLLocationManagerDelegate {

private let manager = CLLocationManager()

var desiredAccuracy: CLLocationAccuracy? = kCLLocationAccuracyDefault {
didSet {
manager.desiredAccuracy = desiredAccuracy ?? kCLLocationAccuracyBest
}
}
private var isActive = false

var distanceFilterMeters: CLLocationDistance? = kCLDistanceFilterNoneDefault {
didSet {
manager.distanceFilter = distanceFilterMeters ?? kCLDistanceFilterNone
}
}
private var currentDesiredAccuracy: CLLocationAccuracy =
kCLLocationAccuracyDefault
private var currentDistanceFilter: CLLocationDistance =
kCLDistanceFilterNoneDefault
private var currentActivityType: CLActivityType = kCLActivityTypeDefault

var onUpdate: ((CLLocation) -> Void)?
var onError: ((_ error: RNLocationErrorCode) -> Void)?
Expand All @@ -30,7 +27,21 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
super.init()
manager.delegate = self
manager.pausesLocationUpdatesAutomatically = true
manager.activityType = .other
}

func updateConfig(
desiredAccuracy: CLLocationAccuracy?,
distanceFilterMeters: CLLocationDistance?,
activityType: CLActivityType?
) {
currentDesiredAccuracy = desiredAccuracy ?? kCLLocationAccuracyDefault
manager.desiredAccuracy = currentDesiredAccuracy

currentDistanceFilter = distanceFilterMeters ?? kCLDistanceFilterNoneDefault
manager.distanceFilter = currentDistanceFilter

currentActivityType = activityType ?? kCLActivityTypeDefault
manager.activityType = currentActivityType
}

func showLocationDialog() {
Expand Down Expand Up @@ -71,11 +82,19 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
}

func start() {
stop()
startUpdates()
guard !isActive else { return }
isActive = true

manager.location.map {
onUpdate?($0)
}

manager.startUpdatingLocation()
}

func stop() {
guard isActive else { return }
isActive = false
manager.stopUpdatingLocation()
}

Expand Down Expand Up @@ -104,13 +123,6 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
}
}

private func startUpdates() {
manager.desiredAccuracy = desiredAccuracy ?? kCLLocationAccuracyDefault
manager.distanceFilter =
distanceFilterMeters ?? kCLDistanceFilterNoneDefault
manager.startUpdatingLocation()
}

func locationManager(
_ manager: CLLocationManager,
didFailWithError error: Error
Expand Down
18 changes: 18 additions & 0 deletions ios/extensions/RNIOSLocationActivityType+Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import CoreLocation

extension RNIOSLocationActivityType {
var toCLActivityType: CLActivityType {
switch self {
case .other:
return .other
case .navigation:
return .otherNavigation
case .automotive:
return .automotiveNavigation
case .fitness:
return .fitness
case .airborne:
return .airborne
}
}
}
9 changes: 9 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ export enum RNAndroidLocationPriority {
export type RNIOSLocationConfig = {
desiredAccuracy?: RNIOSLocationAccuracy;
distanceFilterMeters?: number;
activityType?: RNIOSLocationActivityType;
};

export enum RNIOSLocationAccuracy {
Expand All @@ -306,6 +307,14 @@ export enum RNIOSLocationAccuracy {
ACCURACY_KILOMETER = 3,
}

export enum RNIOSLocationActivityType {
OTHER = 0,
NAVIGATION = 1,
AUTOMOTIVE = 2,
FITNESS = 3,
AIRBORNE = 4,
}

export type RNLocationPermissionResult = {
android?: RNAndroidLocationPermissionResult;
ios?: RNIOSPermissionResult;
Expand Down
Loading