Skip to content

Commit 7c1d48d

Browse files
authored
feat(ios): add location activity type support
## Pull request --- ### Before submitting - [x] This PR targets the `dev` branch (not `main`) - [x] Commit messages follow the semantic-release format - [x] No debug logs or sensitive data included --- ### Summary Add location activity type support --- ### Type of change - [x] Feature - [ ] Fix - [ ] Refactor - [ ] Internal / CI - [ ] Documentation --- ### Scope - [ ] Android - [x] iOS - [ ] Core - [x] Example App - [ ] Docs ---
2 parents c682200 + 5b1926e commit 7c1d48d

File tree

7 files changed

+118
-32
lines changed

7 files changed

+118
-32
lines changed

example/src/components/MapWrapper.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ import type {
1313
RNMapUiSettings,
1414
RNMapZoomConfig,
1515
RNRegion,
16+
RNIndoorBuilding,
17+
RNIndoorLevel,
1618
} from 'react-native-google-maps-plus';
1719
import {
1820
GoogleMapsView,
1921
RNAndroidLocationPriority,
20-
type RNIndoorBuilding,
21-
type RNIndoorLevel,
2222
RNIOSLocationAccuracy,
23+
RNIOSLocationActivityType,
2324
RNLocationErrorCode,
2425
RNMapErrorCode,
2526
} from 'react-native-google-maps-plus';
@@ -103,6 +104,7 @@ export default function MapWrapper(props: Props) {
103104
ios: {
104105
desiredAccuracy: RNIOSLocationAccuracy.ACCURACY_BEST,
105106
distanceFilterMeters: 10,
107+
activityType: RNIOSLocationActivityType.NAVIGATION,
106108
},
107109
}),
108110
[]

example/src/components/maptConfigDialog/validator.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
RNAndroidLocationPermissionResult,
1616
RNAndroidLocationPriority,
1717
RNIOSLocationAccuracy,
18+
RNIOSLocationActivityType,
1819
RNIOSPermissionResult,
1920
RNLocationErrorCode,
2021
RNMapErrorCode,
@@ -272,6 +273,7 @@ const RNAndroidLocationConfigValidator = object({
272273
export const RNIOSLocationConfigValidator = object({
273274
desiredAccuracy: optional(enums(enumValues(RNIOSLocationAccuracy))),
274275
distanceFilterMeters: optional(number()),
276+
activityType: optional(enums(enumValues(RNIOSLocationActivityType))),
275277
});
276278

277279
export const RNLocationConfigValidator = object({
Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,55 @@
1-
import React, { useRef } from 'react';
1+
import React, { useRef, useState } from 'react';
22
import MapWrapper from '../components/MapWrapper';
33
import ControlPanel from '../components/ControlPanel';
4-
import type { GoogleMapsViewRef } from 'react-native-google-maps-plus';
4+
import {
5+
type GoogleMapsViewRef,
6+
RNAndroidLocationPriority,
7+
RNIOSLocationAccuracy,
8+
RNIOSLocationActivityType,
9+
type RNLocationConfig,
10+
} from 'react-native-google-maps-plus';
11+
import { RNLocationConfigValidator } from '../components/maptConfigDialog/validator';
12+
import MapConfigDialog from '../components/maptConfigDialog/MapConfigDialog';
13+
import { useHeaderButton } from '../hooks/useHeaderButton';
14+
import { useNavigation } from '@react-navigation/native';
515

616
export default function LocationScreen() {
717
const mapRef = useRef<GoogleMapsViewRef | null>(null);
18+
const navigation = useNavigation();
19+
const [locationConfig, setLocationConfig] = useState<RNLocationConfig>({
20+
android: {
21+
priority: RNAndroidLocationPriority.PRIORITY_HIGH_ACCURACY,
22+
interval: 5000,
23+
minUpdateInterval: 5000,
24+
},
25+
ios: {
26+
desiredAccuracy: RNIOSLocationAccuracy.ACCURACY_BEST,
27+
distanceFilterMeters: 10,
28+
activityType: RNIOSLocationActivityType.NAVIGATION,
29+
},
30+
});
31+
const [dialogVisible, setDialogVisible] = useState(true);
32+
33+
useHeaderButton(navigation, 'Edit', () => setDialogVisible(true));
834

935
return (
10-
<MapWrapper mapRef={mapRef} myLocationEnabled>
11-
<ControlPanel mapRef={mapRef} buttons={[]} />
12-
</MapWrapper>
36+
<>
37+
<MapWrapper
38+
mapRef={mapRef}
39+
myLocationEnabled
40+
locationConfig={locationConfig}
41+
>
42+
<ControlPanel mapRef={mapRef} buttons={[]} />
43+
</MapWrapper>
44+
45+
<MapConfigDialog<RNLocationConfig>
46+
visible={dialogVisible}
47+
title="Edit marker"
48+
initialData={locationConfig}
49+
validator={RNLocationConfigValidator}
50+
onClose={() => setDialogVisible(false)}
51+
onSave={(c) => setLocationConfig(c)}
52+
/>
53+
</>
1354
);
1455
}

ios/GoogleMapViewImpl.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import CoreLocation
22
import GoogleMaps
33
import GoogleMapsUtils
4-
import UIKit
54
import NitroModules
5+
import UIKit
66

77
final class GoogleMapsViewImpl: UIView, GMSMapViewDelegate,
88
GMSIndoorDisplayDelegate {
@@ -273,10 +273,12 @@ GMSIndoorDisplayDelegate {
273273
@MainActor
274274
var locationConfig: RNLocationConfig? {
275275
didSet {
276-
locationHandler.desiredAccuracy =
277-
locationConfig?.ios?.desiredAccuracy?.toCLLocationAccuracy
278-
locationHandler.distanceFilterMeters =
279-
locationConfig?.ios?.distanceFilterMeters
276+
locationHandler.updateConfig(
277+
desiredAccuracy: locationConfig?.ios?.desiredAccuracy?
278+
.toCLLocationAccuracy,
279+
distanceFilterMeters: locationConfig?.ios?.distanceFilterMeters,
280+
activityType: locationConfig?.ios?.activityType?.toCLActivityType,
281+
)
280282
}
281283
}
282284

ios/LocationHandler.swift

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,19 @@ private let kCLLocationAccuracyDefault: CLLocationAccuracy =
66
kCLLocationAccuracyBest
77
private let kCLDistanceFilterNoneDefault: CLLocationDistance =
88
kCLDistanceFilterNone
9+
private let kCLActivityTypeDefault: CLActivityType = .other
910

1011
final class LocationHandler: NSObject, CLLocationManagerDelegate {
1112

1213
private let manager = CLLocationManager()
1314

14-
var desiredAccuracy: CLLocationAccuracy? = kCLLocationAccuracyDefault {
15-
didSet {
16-
manager.desiredAccuracy = desiredAccuracy ?? kCLLocationAccuracyBest
17-
}
18-
}
15+
private var isActive = false
1916

20-
var distanceFilterMeters: CLLocationDistance? = kCLDistanceFilterNoneDefault {
21-
didSet {
22-
manager.distanceFilter = distanceFilterMeters ?? kCLDistanceFilterNone
23-
}
24-
}
17+
private var currentDesiredAccuracy: CLLocationAccuracy =
18+
kCLLocationAccuracyDefault
19+
private var currentDistanceFilter: CLLocationDistance =
20+
kCLDistanceFilterNoneDefault
21+
private var currentActivityType: CLActivityType = kCLActivityTypeDefault
2522

2623
var onUpdate: ((CLLocation) -> Void)?
2724
var onError: ((_ error: RNLocationErrorCode) -> Void)?
@@ -30,7 +27,21 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
3027
super.init()
3128
manager.delegate = self
3229
manager.pausesLocationUpdatesAutomatically = true
33-
manager.activityType = .other
30+
}
31+
32+
func updateConfig(
33+
desiredAccuracy: CLLocationAccuracy?,
34+
distanceFilterMeters: CLLocationDistance?,
35+
activityType: CLActivityType?
36+
) {
37+
currentDesiredAccuracy = desiredAccuracy ?? kCLLocationAccuracyDefault
38+
manager.desiredAccuracy = currentDesiredAccuracy
39+
40+
currentDistanceFilter = distanceFilterMeters ?? kCLDistanceFilterNoneDefault
41+
manager.distanceFilter = currentDistanceFilter
42+
43+
currentActivityType = activityType ?? kCLActivityTypeDefault
44+
manager.activityType = currentActivityType
3445
}
3546

3647
func showLocationDialog() {
@@ -71,11 +82,19 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
7182
}
7283

7384
func start() {
74-
stop()
75-
startUpdates()
85+
guard !isActive else { return }
86+
isActive = true
87+
88+
manager.location.map {
89+
onUpdate?($0)
90+
}
91+
92+
manager.startUpdatingLocation()
7693
}
7794

7895
func stop() {
96+
guard isActive else { return }
97+
isActive = false
7998
manager.stopUpdatingLocation()
8099
}
81100

@@ -104,13 +123,6 @@ final class LocationHandler: NSObject, CLLocationManagerDelegate {
104123
}
105124
}
106125

107-
private func startUpdates() {
108-
manager.desiredAccuracy = desiredAccuracy ?? kCLLocationAccuracyDefault
109-
manager.distanceFilter =
110-
distanceFilterMeters ?? kCLDistanceFilterNoneDefault
111-
manager.startUpdatingLocation()
112-
}
113-
114126
func locationManager(
115127
_ manager: CLLocationManager,
116128
didFailWithError error: Error
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import CoreLocation
2+
3+
extension RNIOSLocationActivityType {
4+
var toCLActivityType: CLActivityType {
5+
switch self {
6+
case .other:
7+
return .other
8+
case .navigation:
9+
return .otherNavigation
10+
case .automotive:
11+
return .automotiveNavigation
12+
case .fitness:
13+
return .fitness
14+
case .airborne:
15+
return .airborne
16+
}
17+
}
18+
}

src/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ export enum RNAndroidLocationPriority {
297297
export type RNIOSLocationConfig = {
298298
desiredAccuracy?: RNIOSLocationAccuracy;
299299
distanceFilterMeters?: number;
300+
activityType?: RNIOSLocationActivityType;
300301
};
301302

302303
export enum RNIOSLocationAccuracy {
@@ -306,6 +307,14 @@ export enum RNIOSLocationAccuracy {
306307
ACCURACY_KILOMETER = 3,
307308
}
308309

310+
export enum RNIOSLocationActivityType {
311+
OTHER = 0,
312+
NAVIGATION = 1,
313+
AUTOMOTIVE = 2,
314+
FITNESS = 3,
315+
AIRBORNE = 4,
316+
}
317+
309318
export type RNLocationPermissionResult = {
310319
android?: RNAndroidLocationPermissionResult;
311320
ios?: RNIOSPermissionResult;

0 commit comments

Comments
 (0)