I’m researching on creating library for react native new arch. For the time being, I’m coping with create-react-native-library
to create a location monitoring lib for iOS for higher customization.
I’m new to each Goal-C and Swift, so really want your helps.
My present model:
- create-react-native-library: 0.48.3
- react-native: 0.78.0
My iOS challenge already has:
- background location monitoring allow
- information.plist with:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription
On simulator, app settings:
- Location monitoring set to
All the time enable
- Checked on Maps app and the blue dot is transferring.
Please discover code under
MyLocationTracking.h
#import "generated/RNMyLocationTrackingSpec/RNMyLocationTrackingSpec.h"
@interface MyLocationTracking : NativeMyLocationTrackingSpecBase
@finish
MyLocationTracking.mm
#import
#import "MyLocationTracking.h"
#import "MyLocationTracking-Swift.h"
@implementation MyLocationTracking
RCT_EXPORT_MODULE()
- (void)setInfo:(nonnull NSString *)baseURL token:(nonnull NSString *)token pushGPSInterval:(double)pushGPSInterval pushGPSDistance:(double)pushGPSDistance integrationId:(nonnull NSString *)integrationId {
MyLocationTrackingImpl *swiftInstance = [MyLocationTrackingImpl shared];
[swiftInstance setInfo:baseURL
rnToken:token
rnPushGPSInterval:pushGPSInterval
rnPushGPSDistance:pushGPSDistance
rnIntegrationId:integrationId
callback:^(NSDictionary *locationData) {
[self emitOnLocationChanged:locationData];
}];
}
- (nonnull NSNumber *)isProviderEnabled {
return @1;
}
- (nonnull NSNumber *)isServiceRunning {
return @1;
}
- (void)startWatchLocation {
[[MyLocationTrackingImpl shared] startWatchLocation];
}
- (void)stopWatchLocation {
[[MyLocationTrackingImpl shared] stopWatchLocation];
}
- (void)updateIntegrationId:(nonnull NSString *)integrationId {
[[MyLocationTrackingImpl shared] updateIntegrationId:integrationId];
}
- (std::shared_ptr<:react::turbomodule>)getTurboModule:
(const fb::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<:react::nativemylocationtrackingspecjsi>(params);
}
@finish
MyLocationTrackingImpl.swift: That is working as a bridge to attach the core Location Monitoring with the Goal C
import Basis
@objc
public class MyLocationTrackingImpl: NSObject {
personal let myLocationTrackingCore = MyLocationTrackingCore()
// Singleton occasion
@objc public static let shared = MyLocationTrackingImpl()
// Personal initializer to implement singleton
personal override init() {
tremendous.init()
print("=== MySingleton initialized! ===")
}
@objc public func setInfo(_ baseURL: String, rnToken token: String, rnPushGPSInterval pushGPSInterval: Double, rnPushGPSDistance pushGPSDistance: Double, rnIntegrationId integrationId: String, callback: @escaping ([String: Any]) -> Void) {
myLocationTrackingCore.setInfo(baseURL, rnToken: token, rnPushGPSInterval: pushGPSInterval, rnPushGPSDistance: pushGPSDistance, rnIntegrationId: integrationId, callback: callback)
}
@objc public func startWatchLocation() {
myLocationTrackingCore.startWatchLocation()
}
@objc public func stopWatchLocation() {
myLocationTrackingCore.stopWatchLocation()
}
@objc public func updateIntegrationId(_ integrationId: String) {
print("Up to date Integration ID: (integrationId)");
}
}
MyLocationTrackingCore.swift
import Basis
import CoreLocation
class MyLocationTrackingCore: NSObject, CLLocationManagerDelegate {
var locationManager : CLLocationManager = CLLocationManager()
var BASE_URL : String = ""
var token : String = ""
var pushGPSInterval : Double = 10_000
var pushGPSDistance : Double = 0
var integrationId : String = "{}"
var pushGPSTimer: Date = Date()
var locationCallback: (([String: Any]) -> Void)?
func setInfo(_ baseURL: String, rnToken token: String, rnPushGPSInterval pushGPSInterval: Double, rnPushGPSDistance pushGPSDistance: Double, rnIntegrationId integrationId: String, callback: @escaping ([String: Any]) -> Void) {
print("= Initializing....");
self.BASE_URL = baseURL
self.token = token
self.integrationId = integrationId
// The minTime is in millisecond, right here we'd like second
self.pushGPSInterval = (pushGPSInterval == 0 ? 10_000 : pushGPSInterval) / 1_000
self.pushGPSDistance = pushGPSDistance < 0 ? 0 : pushGPSDistance
// Callback
self.locationCallback = callback
print("Base url : (self.BASE_URL)");
print("token : (self.token)");
print("integrationId : (self.integrationId)");
print("pushGPSInterval : (self.pushGPSInterval)");
print("pushGPSDistance : (self.pushGPSDistance)");
print("set off callback :");
// Callback: strive ship information
if let locationCallback = self.locationCallback {
let newLocationData: [String: Any] = [
"lat": 37.7859,
"lng": -122.4364,
"alt": 15.0,
"spd": 6.0,
"course": 45.0
]
locationCallback(newLocationData)
print("- Location Callback triggered")
} else {
print("= Location Callback is nil")
}
// Init Location Supervisor
self.locationManager.delegate = self
self.locationManager.distanceFilter = self.pushGPSDistance
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.requestAlwaysAuthorization()
self.locationManager.allowsBackgroundLocationUpdates = true
self.locationManager.pausesLocationUpdatesAutomatically = false
self.locationManager.activityType = .automotiveNavigation
print("= Initialized");
}
func startWatchLocation() {
if CLLocationManager.locationServicesEnabled() {
self.pushGPSTimer = Date().addingTimeInterval(0)
self.locationManager.startUpdatingLocation()
print("Begin location Location");
}
}
func stopWatchLocation() {
if CLLocationManager.locationServicesEnabled() {
self.locationManager.stopUpdatingLocation()
self.locationManager.delegate = nil
print("Cease location monitoring")
}
}
func locationManager(
_ supervisor: CLLocationManager,
didUpdateLocations areas: [CLLocation]
) {
if let userLocation = areas.final {
let latitude = String(userLocation.coordinate.latitude)
let longitude = String(userLocation.coordinate.longitude)
let altitude = String(userLocation.altitude)
let pace = String(userLocation.pace)
let course = String(userLocation.course)
print("===============")
print("consumer latitude = (latitude)")
print("consumer longitude = (longitude)")
print("consumer altitude = (altitude)")
print("consumer pace = (pace)")
print("consumer course = (course)")
} else {
print("===============")
print("No legitimate location information acquired")
}
}
func locationManager(
_ supervisor: CLLocationManager,
didFailWithError error: Error
) {
print("===============")
print("Error = (error)")
}
}
For the time being, the lib can:
- Name Swift’s methodology from Goal-C appropriately.
- when startWatchLocation in MyLocationTrackingCore.swift execute, there’s a location monitoring icon on the highest left of iOS simulator
- when stopWatchLocation in MyLocationTrackingCore.swift execute, the icon is gone
The problem is:
- func locationManager:
didUpdateLocations
anddidFailWithError
usually are not triggered, noprint
methodology is executed.
Please let me know if in case you have any concepts about why the didUpdateLocations
and didFailWithError
usually are not triggered.
For those who want any data, please additionally let me know.
Many thanks, guys!