ssap_app/node_modules/expo-location/ios/LocationUtils.swift

119 lines
3.6 KiB
Swift

// Copyright 2023-present 650 Industries. All rights reserved.
import ExpoModulesCore
/**
Converts iOS heading accuracy to Android system.
3: high accuracy, 2: medium, 1: low, 0: none
*/
internal func normalizeAccuracy(_ accuracy: CLLocationDirection) -> Int {
if accuracy > 50 || accuracy < 0 {
return 0
}
if accuracy > 35 {
return 1
}
if accuracy > 20 {
return 2
}
return 3
}
internal func exportLocation(_ location: CLLocation) -> [String: Any] {
return [
"coords": [
"latitude": location.coordinate.latitude,
"longitude": location.coordinate.longitude,
"altitude": location.altitude,
"accuracy": location.horizontalAccuracy,
"altitudeAccuracy": location.verticalAccuracy,
"heading": location.course,
"speed": location.speed
],
"timestamp": location.timestamp.timeIntervalSince1970 * 1000
]
}
internal func handleCLError<ReturnType>(error: NSError, defaultValue: ReturnType) throws -> ReturnType {
switch CLError.Code(rawValue: error.code) {
case CLError.geocodeFoundNoResult, CLError.geocodeFoundPartialResult:
return defaultValue
case CLError.network:
throw Exceptions.GeocodingNetwork()
default:
throw Exceptions.GeocodingFailed().causedBy(error)
}
}
internal func ensureLocationServicesEnabled() throws {
guard CLLocationManager.locationServicesEnabled() else {
throw Exceptions.LocationServicesDisabled()
}
}
// MARK: - Permissions
internal func getPermissionUsingRequester<Requester: EXPermissionsRequester>(
_ requester: Requester.Type,
appContext: AppContext?,
promise: Promise
) throws {
guard let permissionsManager = appContext?.permissions else {
throw Exceptions.PermissionsModuleNotFound()
}
EXPermissionsMethodsDelegate.getPermissionWithPermissionsManager(
permissionsManager,
withRequester: Requester.self,
resolve: promise.resolver,
reject: promise.legacyRejecter
)
}
internal func askForPermissionUsingRequester<Requester: EXPermissionsRequester>(
_ requester: Requester.Type,
appContext: AppContext?,
promise: Promise
) throws {
guard let permissionsManager = appContext?.permissions else {
throw Exceptions.PermissionsModuleNotFound()
}
EXPermissionsMethodsDelegate.askForPermission(
withPermissionsManager: permissionsManager,
withRequester: Requester.self,
resolve: promise.resolver,
reject: promise.legacyRejecter
)
}
internal func checkPermissionWithRequester<Requester: EXPermissionsRequester>(
_ requester: Requester.Type,
appContext: AppContext?
) throws -> Bool {
guard let permissionsManager = appContext?.permissions else {
throw Exceptions.PermissionsModuleNotFound()
}
return permissionsManager.hasGrantedPermission(usingRequesterClass: Requester.self)
}
func ensureForegroundLocationPermissions(_ appContext: AppContext?) throws {
guard try checkPermissionWithRequester(EXForegroundPermissionRequester.self, appContext: appContext) else {
throw Exceptions.DeniedForegroundLocationPermission()
}
}
func ensureBackgroundLocationPermissions(_ appContext: AppContext?) throws {
guard try checkPermissionWithRequester(EXBackgroundLocationPermissionRequester.self, appContext: appContext) else {
throw Exceptions.DeniedBackgroundLocationPermission()
}
}
// MARK: - Other utils
func isLocation(_ location: CLLocation?, valid requirements: LastKnownLocationRequirements) -> Bool {
guard let location else {
return false
}
let timeDiff = -location.timestamp.timeIntervalSinceNow
return timeDiff * 1000 <= requirements.maxAge && location.horizontalAccuracy <= requirements.requiredAccuracy
}