react-native-pointr 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,581 @@
1
+ //
2
+ // PointrApp.swift
3
+ // Pods-PointrSample
4
+ //
5
+ // Created by Furkan Erdem Perşembe on 15.04.2020.
6
+ //
7
+
8
+ import UIKit
9
+ import PointrKit
10
+
11
+ @objc public protocol PTREventManagerDelegate {
12
+ func onPositionManagerCalculatedLocation(location: [String: Any])
13
+ func onBuildingClicked(_ building: [String: Any])
14
+ func onSiteClicked(_ site: [String: Any])
15
+ }
16
+
17
+ // Class responsible of bridging UI and Pointr SDK with outside world. This class is being used by PTRNativeLibrary.
18
+ @objc public class PointrApp: NSObject {
19
+
20
+ @objc public weak var eventManagerDelegate: PTREventManagerDelegate?
21
+
22
+ @objc public static let sharedApp = PointrApp()
23
+
24
+ let params = PTRParams()
25
+
26
+ let dispatchGroup = DispatchGroup()
27
+
28
+ var viewController: PTRMapWidgetViewController? = nil
29
+
30
+ var configuration: Dictionary<String,Any>? = nil
31
+
32
+ private var mapDispatchGroupDataManager = [Int32: [DispatchGroup]]()
33
+ private var dispatchGroupSiteManager = [DispatchGroup]()
34
+
35
+ var rootViewController: UIViewController? = nil
36
+
37
+ // TODO: remove the code below when we have widget configuration to remove pathFindingViewController
38
+ var isRouteFooterViewEnabled = true
39
+
40
+ private override init () {
41
+ super.init()
42
+ }
43
+ }
44
+
45
+ // MARK: - PTRNativeLibrary methods
46
+
47
+ @objc public extension PointrApp {
48
+
49
+
50
+ func covertToDictionary(_ location: PTRCalculatedLocation) -> [String: Any] {
51
+ var dictionary = [String: Any]()
52
+ if let siteInternalIdentifier = location.site?.internalIdentifier {
53
+ dictionary.updateValue(siteInternalIdentifier, forKey: "siteInternalIdentifier")
54
+ }
55
+ if let buildingInternalIdentifier = location.building?.internalIdentifier {
56
+ dictionary.updateValue(buildingInternalIdentifier, forKey: "buildingInternalIdentifier")
57
+ }
58
+ if let siteExternalIdentifier = location.site?.externalIdentifier {
59
+ dictionary.updateValue(siteExternalIdentifier, forKey: "siteExternalIdentifier")
60
+ }
61
+ if let buildingExternalIdentifier = location.building?.externalIdentifier {
62
+ dictionary.updateValue(buildingExternalIdentifier, forKey: "buildingExternalIdentifier")
63
+ }
64
+ if let levelIndex = location.level?.index {
65
+ dictionary.updateValue(levelIndex, forKey: "levelIndex")
66
+ }
67
+ if location.coordinate.latitude != CLLocationDegrees(PTRPositioningTypes.invalidFloat()) && location.coordinate.longitude != CLLocationDegrees(PTRPositioningTypes.invalidFloat()) {
68
+ dictionary.updateValue(location.coordinate.latitude, forKey: "latitude")
69
+ dictionary.updateValue(location.coordinate.longitude, forKey: "longitude")
70
+ }
71
+ if location.accuracy != Double(PTRPositioningTypes.invalidFloat()) {
72
+ dictionary.updateValue(location.accuracy, forKey: "accuracy")
73
+ }
74
+ if (location.headingAccuracyClass == .high) {
75
+ dictionary.updateValue(location.heading, forKey: "heading")
76
+ }
77
+ return dictionary
78
+ }
79
+
80
+ func initialize(licenseKey: String, baseUrl: String, clientIdentifier: String, environment: String = "prod", logLevel: Int = 4, rootViewController: UIViewController) {
81
+ self.rootViewController = rootViewController
82
+ self.params.mode = PointrDebugMode()
83
+ // No need to set environment
84
+ // self.params.environment = self.getEnvironmentFromString(env: environment)
85
+ self.params.loggerLevel = PTRLoggerLevel.init(rawValue: Int32(logLevel)) ?? .error
86
+
87
+ // Enter you license key
88
+ self.params.licenseKey = licenseKey
89
+ self.params.baseUrl = baseUrl
90
+ self.params.clientIdentifier = clientIdentifier
91
+ }
92
+
93
+ func getEnvironmentFromString(env: String) -> PTREnvironment {
94
+ if env == "prod" {
95
+ return .production
96
+ } else if env == "preprod" {
97
+ return .preProduction
98
+ } else if env == "qa" {
99
+ return .QA
100
+ } else if env == "dev" {
101
+ return .development
102
+ } else {
103
+ return .production
104
+ }
105
+ }
106
+
107
+ func setPointrMapWidgetConfiguration(string: String) {
108
+ guard let data = string.data(using: .utf8) else {
109
+ Ploge("String does not have valid data")
110
+ return
111
+ }
112
+ do {
113
+ guard let jsonObject = try JSONSerialization.jsonObject(with: data) as? Dictionary<String,Any> else {
114
+ Ploge("Bad json")
115
+ return
116
+ }
117
+ configuration = jsonObject
118
+ } catch let error as NSError {
119
+ Ploge("Error parsing json: \(string)\n\(error)")
120
+ }
121
+ }
122
+
123
+ func getMapWidgetConfiguration() -> PTRMapWidgetConfiguration {
124
+ let mapWidgetConfiguration = PTRMapWidgetConfiguration.defaultConfiguration()
125
+ guard let configuration else {
126
+ return mapWidgetConfiguration
127
+ }
128
+ let mirror = Mirror(reflecting: mapWidgetConfiguration)
129
+ for attr in mirror.children {
130
+ guard let key = attr.label else {
131
+ continue
132
+ }
133
+ // only set boolean values
134
+ guard let value = configuration[key] as? Bool, attr.value is Bool else {
135
+ continue
136
+ }
137
+ mapWidgetConfiguration.setValue(value, forKey: key)
138
+ }
139
+ // TODO: remove the code below when we have widget configuration to hide pathFindingViewController
140
+ // check if navigation footer view needs to be disabled as well.
141
+ if let isRouteFooterViewEnabled = configuration["isRouteFooterViewEnabled"] as? Bool {
142
+ self.isRouteFooterViewEnabled = isRouteFooterViewEnabled
143
+ }
144
+ // for exit button configuration check for isExitButtonEnabled key to make the api same with android
145
+ if let value = configuration["isExitButtonShown"] as? Bool {
146
+ if value {
147
+ mapWidgetConfiguration.exitButtonConfiguration = PTRMapwidgetExitButtonConfiguration(preferredPosition: .topRight, visibility: .alwaysVisible)
148
+ } else {
149
+ mapWidgetConfiguration.exitButtonConfiguration = PTRMapwidgetExitButtonConfiguration(preferredPosition: .topRight, visibility: .notVisible)
150
+ }
151
+ } else {
152
+ mapWidgetConfiguration.exitButtonConfiguration = PTRMapwidgetExitButtonConfiguration(preferredPosition: .topRight, visibility: .automatic)
153
+ }
154
+ return mapWidgetConfiguration
155
+ }
156
+
157
+ func start(completion: @escaping (String) -> Void) {
158
+ dispatchGroup.enter()
159
+ Pointr.shared.addListener(self)
160
+ Pointr.shared.start(with: params) {_ in }
161
+ dispatchGroup.wait()
162
+
163
+ if Pointr.shared.state == .running {
164
+ Pointr.shared.positionManager?.addListener(self)
165
+ }
166
+
167
+ completion(getPointrStateStringFromPointrState(state: Pointr.shared.state))
168
+ }
169
+
170
+ func stop() {
171
+ Pointr.shared.positionManager?.removeListener(self)
172
+ Pointr.shared.stop()
173
+ }
174
+
175
+ func showSite(siteExternalIdentifier id: String, animationType:Int, completion: @escaping (String?) -> Void) {
176
+ func showSiteWithCompletion(completion: @escaping (String?) -> Void) {
177
+ self.initializeMapWidget()
178
+ self.viewController!.showSite(siteExternalIdentifier: id, animationType: self.getAnimationTypeFromInt(value: animationType)) { error in
179
+ completion(self.getErrorStringFromMapWidgetError(error: error))
180
+ }
181
+ self.presentMapWidgetIfNotPresented()
182
+ }
183
+
184
+ if Pointr.shared.state != .running {
185
+ start() { state in
186
+ if state == "running" {
187
+ showSiteWithCompletion(completion: completion)
188
+ } else {
189
+ completion("starting Pointr resulted in \(state) state")
190
+ }
191
+ }
192
+ } else {
193
+ showSiteWithCompletion(completion: completion)
194
+ }
195
+ }
196
+
197
+ func showBuilding(siteExternalIdentifier: String, buildingExternalIdentifier: String, animationType:Int, completion: @escaping (String?) -> Void) {
198
+ func showBuildingWithCompletion(completion: @escaping (String?) -> Void) {
199
+ self.initializeMapWidget()
200
+ self.viewController!.showBuilding(siteExternalIdentifier: siteExternalIdentifier, buildingExternalIdentifier: buildingExternalIdentifier, animationType: self.getAnimationTypeFromInt(value: animationType)) { error in
201
+ completion(self.getErrorStringFromMapWidgetError(error: error))
202
+ }
203
+ self.presentMapWidgetIfNotPresented()
204
+ }
205
+
206
+ if Pointr.shared.state != .running {
207
+ start() { state in
208
+ if state == "running" {
209
+ showBuildingWithCompletion(completion: completion)
210
+ } else {
211
+ completion("starting Pointr resulted in \(state) state")
212
+ }
213
+ }
214
+ } else {
215
+ showBuildingWithCompletion(completion: completion)
216
+ }
217
+ }
218
+
219
+ func showLevel(siteExternalIdentifier: String, buildingExternalIdentifier: String, levelIndex: Int, animationType:Int, completion: @escaping (String?) -> Void) {
220
+ func showLevelWithCompletion(completion: @escaping (String?) -> Void) {
221
+ self.initializeMapWidget()
222
+ self.viewController!.showLevel(siteExternalIdentifier: siteExternalIdentifier, buildingExternalIdentifier: buildingExternalIdentifier, levelIndex: levelIndex, animationType: self.getAnimationTypeFromInt(value: animationType)) { error in
223
+ completion(self.getErrorStringFromMapWidgetError(error: error))
224
+ }
225
+ self.presentMapWidgetIfNotPresented()
226
+ }
227
+
228
+ if Pointr.shared.state != .running {
229
+ start() { state in
230
+ if state == "running" {
231
+ showLevelWithCompletion(completion: completion)
232
+ } else {
233
+ completion("starting Pointr resulted in \(state) state")
234
+ }
235
+ }
236
+ } else {
237
+ showLevelWithCompletion(completion: completion)
238
+ }
239
+ }
240
+
241
+ func showPoiDetails(siteExternalIdentifier id: String, poiExternalIdentifier: String, animationType:Int, completion: @escaping (String?) -> Void) {
242
+ func showPoiDetailsWithCompletion(completion: @escaping (String?) -> Void) {
243
+ self.initializeMapWidget()
244
+ self.viewController!.showPoiDetails(siteExternalIdentifier: id, poiExternalIdentifier: poiExternalIdentifier, animationType: self.getAnimationTypeFromInt(value: animationType)) { error in
245
+ completion(self.getErrorStringFromMapWidgetError(error: error))
246
+ }
247
+ self.presentMapWidgetIfNotPresented()
248
+ }
249
+
250
+ if Pointr.shared.state != .running {
251
+ start() { state in
252
+ if state == "running" {
253
+ showPoiDetailsWithCompletion(completion: completion)
254
+ } else {
255
+ completion("starting Pointr resulted in \(state) state")
256
+ }
257
+ }
258
+ } else {
259
+ showPoiDetailsWithCompletion(completion: completion)
260
+ }
261
+ }
262
+
263
+ func showPathFindingToPoi(siteExternalIdentifier id: String, poiExternalIdentifier: String, animationType:Int, completion: @escaping (String?) -> Void) {
264
+ func showPathFindingToPoiWithCompletion(completion: @escaping (String?) -> Void) {
265
+ self.initializeMapWidget()
266
+ self.viewController!.showPathFinding(siteExternalIdentifier: id, poiExternalIdentifier: poiExternalIdentifier, animationType: self.getAnimationTypeFromInt(value: animationType)) { error in
267
+ completion(self.getErrorStringFromMapWidgetError(error: error))
268
+ }
269
+ self.presentMapWidgetIfNotPresented()
270
+ }
271
+
272
+ if Pointr.shared.state != .running {
273
+ start() { state in
274
+ if state == "running" {
275
+ showPathFindingToPoiWithCompletion(completion: completion)
276
+ } else {
277
+ completion("starting Pointr resulted in \(state) state")
278
+ }
279
+ }
280
+ } else {
281
+ showPathFindingToPoiWithCompletion(completion: completion)
282
+ }
283
+ }
284
+
285
+
286
+ func showPathFindingBetweenPOIs(siteExternalIdentifier: String, sourcePoiExternalIdentifier: String, destinationPoiExternalIdentifier: String, animationType:Int, completion: @escaping (String?) -> Void) {
287
+ if Pointr.shared.state != .running {
288
+ start() { state in
289
+ if state != "running" {
290
+ completion("starting Pointr resulted in \(state) state")
291
+ return
292
+ }
293
+ }
294
+ }
295
+
296
+ DispatchQueue.global().async {
297
+ guard let dataManager = Pointr.shared.dataManager,
298
+ let siteManager = Pointr.shared.siteManager,
299
+ let poiManager = Pointr.shared.poiManager,
300
+ let pathManager = Pointr.shared.pathManager else {
301
+ completion("Managers are not ready")
302
+ return
303
+ }
304
+
305
+ guard let site = self.getSite(with: siteExternalIdentifier, siteManager: siteManager) else {
306
+ completion("Could not find site \(siteExternalIdentifier)")
307
+ return
308
+ }
309
+
310
+ if !self.loadData(for: site, dataManager: dataManager) {
311
+ completion("Data are not ready for site: \(siteExternalIdentifier)")
312
+ return
313
+ }
314
+
315
+ guard let from = poiManager.pois(for: site, withExternalIdentifier: sourcePoiExternalIdentifier) else {
316
+ completion("Could not find poi: \(sourcePoiExternalIdentifier) within site: \(siteExternalIdentifier)")
317
+ return
318
+ }
319
+
320
+ guard let to = poiManager.pois(for: site, withExternalIdentifier: destinationPoiExternalIdentifier) else {
321
+ completion("Could not find poi: \(destinationPoiExternalIdentifier) within site: \(siteExternalIdentifier)")
322
+ return
323
+ }
324
+
325
+ guard let path = pathManager.calculatePath(fromLocation: from.location, toNearestLocationIn: [to.location]) else {
326
+ completion("Unable to calculate path between locations")
327
+ return
328
+ }
329
+
330
+ guard let fromLevel = from.location.level else {
331
+ completion("Starting poi is not within any level")
332
+ return
333
+ }
334
+ DispatchQueue.main.async {
335
+ self.initializeMapWidget()
336
+ self.presentMapWidgetIfNotPresented()
337
+ self.viewController!.showLevel(fromLevel, animationType: self.getAnimationTypeFromInt(value: animationType)) { error in
338
+ if let e = error {
339
+ completion(self.getErrorStringFromMapWidgetError(error: e))
340
+ return
341
+ }
342
+ let layer = PTRMapSymbolLayer(identifier: UUID().uuidString)
343
+ self.viewController?.mapViewController.addLayer(layer)
344
+ self.viewController?.mapViewController.addFeatures([to, from], toLayer: layer.identifier)
345
+ self.viewController?.mapViewController.zoomToCoordinate(to.coordinate)
346
+ self.viewController?.mapViewController.currentPath = path
347
+ completion(nil)
348
+ }
349
+ }
350
+ }
351
+ }
352
+
353
+ func getSite(with siteExternalIdentifier: String, siteManager: PTRSiteManagerInterface, timeoutInSeconds: Int = 15) -> PTRSite? {
354
+ if let site = siteManager.site(withExternalIdentifier: siteExternalIdentifier) {
355
+ return site
356
+ } else {
357
+ let dispatchGroup = DispatchGroup()
358
+ self.dispatchGroupSiteManager.append(dispatchGroup)
359
+ dispatchGroup.enter()
360
+ siteManager.addListener(self)
361
+ _ = dispatchGroup.wait(wallTimeout: .now() + DispatchTimeInterval.seconds(timeoutInSeconds))
362
+ siteManager.removeListener(self)
363
+ }
364
+ return siteManager.site(withExternalIdentifier: siteExternalIdentifier)
365
+ }
366
+
367
+ func loadData(for site: PTRSite, dataManager: PTRDataManagerInterface, timeoutInSeconds: Int = 30) -> Bool {
368
+ if(dataManager.isContentReady(forSite: site.internalIdentifier)) {
369
+ return true
370
+ }
371
+ let dispatchGroup = DispatchGroup()
372
+ self.mapDispatchGroupDataManager[site.internalIdentifier] = self.mapDispatchGroupDataManager[site.internalIdentifier] ?? [DispatchGroup]()
373
+ self.mapDispatchGroupDataManager[site.internalIdentifier]?.append(dispatchGroup)
374
+ dataManager.addListener(self)
375
+ dispatchGroup.enter()
376
+ dataManager.loadData(forSite: site.internalIdentifier, shouldRespectCachePolicy: false)
377
+ _ = dispatchGroup.wait(wallTimeout: .now() + DispatchTimeInterval.seconds(timeoutInSeconds))
378
+ dataManager.removeListener(self)
379
+ return dataManager.isContentReady(forSite: site.internalIdentifier)
380
+ }
381
+
382
+ func getAnimationTypeFromInt(value: Int) -> PTRMapAnimationType {
383
+ if value == 0 {
384
+ return .none
385
+ } else if value == 1 {
386
+ return .standard
387
+ } else if value == 2 {
388
+ return .flyOver
389
+ } else {
390
+ return .none
391
+ }
392
+ }
393
+
394
+ func initializeMapWidget() {
395
+ if self.viewController != nil { return }
396
+ self.viewController = PTRMapWidgetViewController(configuration: getMapWidgetConfiguration())
397
+ self.viewController?.exitButton?.addListener(self)
398
+ self.viewController?.mapViewController.addListener(self)
399
+ }
400
+
401
+ func presentMapWidgetIfNotPresented() {
402
+ guard let viewController = viewController else {
403
+ return
404
+ }
405
+ if viewController.view.window != nil {
406
+ return
407
+ }
408
+ viewController.modalPresentationStyle = .fullScreen
409
+ rootViewController?.view.addSubview(viewController.view)
410
+ // rootViewController?.present(viewController, animated: true)
411
+ // TODO: remove code below when we have widget configuration to hide whole pathFindingViewController
412
+ viewController.addListener(self)
413
+ }
414
+
415
+ func getCurrentLocation(completion: @escaping ([String: Any]?, String?) -> Void) {
416
+ func getLocationWithCompletion(completion: @escaping ([String: Any]?, String?) -> Void) {
417
+ if let location = Pointr.shared.positionManager?.currentCalculatedLocation {
418
+ completion(covertToDictionary(location), nil)
419
+ } else {
420
+ completion([:], nil)
421
+ }
422
+ }
423
+
424
+ if Pointr.shared.state != .running {
425
+ start() { s in
426
+ let state = self.getPointrStateFromPointrStateString(string: s)
427
+ if state == .running {
428
+ getLocationWithCompletion(completion: completion)
429
+ } else {
430
+ completion(nil, "starting Pointr resulted in \(state) state")
431
+ }
432
+ }
433
+ } else {
434
+ getLocationWithCompletion(completion: completion)
435
+ }
436
+ }
437
+
438
+ func getErrorStringFromMapWidgetError(error: PTRMapWidgetError?) -> String {
439
+ guard let error = error else {
440
+ return ""
441
+ }
442
+ switch error.type {
443
+ case .unknownMapLoading:
444
+ return "An unknown error occured when loading map"
445
+ case .invalidMapUrl:
446
+ return "Map Url is invalid"
447
+ case .unknownDataLoading:
448
+ return "An unknown error occured when loading data"
449
+ case .noSite:
450
+ return "There is no site with given id"
451
+ case .noBuilding:
452
+ return "There is no building with given id"
453
+ case .noLevel:
454
+ return "There is no level with given index"
455
+ case .noPoi:
456
+ return "There is no poi with given id"
457
+ case .noPosition:
458
+ return "Position could not be acquired for path calculation"
459
+ case .pathManagerTimeout:
460
+ return "Path manager is not ready for site"
461
+ case .noPathExist:
462
+ return "Path does not exist for poi"
463
+ case .noBuildingBounds:
464
+ return "No bounds for Building"
465
+ case .noSiteBounds:
466
+ return "No bounds for Site"
467
+ case .invalidCoordinate:
468
+ return "Invalid coordinate"
469
+ case .pointrNotRunning:
470
+ return "Pointr SDK not running when Map Wigdet was initialised"
471
+ case .noPoiCategory:
472
+ return "There is no poi category with given title"
473
+ default:
474
+ return "An unknown error occured"
475
+ }
476
+ }
477
+
478
+ func getPointrStateStringFromPointrState(state: PointrState) -> String {
479
+ switch state {
480
+ case .running:
481
+ return "running"
482
+ case .failedRegistration:
483
+ return "failed registration"
484
+ case .failedValidation:
485
+ return "failed validation"
486
+ case .failedInvalidDeepLinkUrl:
487
+ return "failed invalid deep link url"
488
+ case .failedNoInternet:
489
+ return "failed no internet"
490
+ case .off:
491
+ return "off"
492
+ default:
493
+ return ""
494
+ }
495
+ }
496
+
497
+ func getPointrStateFromPointrStateString(string: String) -> PointrState {
498
+ switch (string) {
499
+ case "running":
500
+ return .running
501
+ case "failed registration":
502
+ return .failedRegistration
503
+ case "failed validation":
504
+ return .failedValidation
505
+ case "failed invalid deep link url":
506
+ return .failedInvalidDeepLinkUrl
507
+ case "failed no internet":
508
+ return .failedNoInternet
509
+ default:
510
+ return .off
511
+ }
512
+ }
513
+ }
514
+
515
+ extension PointrApp: PTRPositionManagerDelegate {
516
+ public func onPositionManagerCalculatedLocation(_ calculatedLocation: PTRCalculatedLocation) {
517
+ eventManagerDelegate?.onPositionManagerCalculatedLocation(location: self.covertToDictionary(calculatedLocation))
518
+ }
519
+ }
520
+
521
+ extension PointrApp: PointrStateChangeListener {
522
+ public func pointrStateDidChange(to state: PointrState) {
523
+ if state.rawValue <= 0 || state == .running {
524
+ Pointr.shared.removeListener(self)
525
+ dispatchGroup.leave()
526
+ }
527
+ }
528
+ }
529
+
530
+ extension PointrApp: PTRExitButtonEventsListener {
531
+ public func exitButtonDidTap(_ exitbutton: PointrKit.PTRMapWidgetExitButton) {
532
+ self.viewController?.view.removeFromSuperview()
533
+ self.viewController = nil
534
+ }
535
+ }
536
+
537
+ extension PointrApp: PTRMapEventsListener {
538
+ public func map(_ map: PTRMapViewController, didReceiveTapOnBuilding building: PTRBuilding) {
539
+ eventManagerDelegate?.onBuildingClicked([
540
+ "internalIdentifier": building.internalIdentifier,
541
+ "externalIdentifier": building.externalIdentifier,
542
+ "title": building.title
543
+ ])
544
+ }
545
+ public func map(_ map: PTRMapViewController, didReceiveTapOnSite site: PTRSite) {
546
+ eventManagerDelegate?.onSiteClicked([
547
+ "internalIdentifier": site.internalIdentifier,
548
+ "externalIdentifier": site.externalIdentifier,
549
+ "title": site.title
550
+ ])
551
+ }
552
+ }
553
+
554
+ extension PointrApp: PTRSiteManagerDelegate {
555
+ public func onSiteManagerDataChanged() {
556
+ while(!dispatchGroupSiteManager.isEmpty) {
557
+ let dispatchGroup = dispatchGroupSiteManager.removeLast()
558
+ dispatchGroup.leave()
559
+ }
560
+ }
561
+ }
562
+
563
+ extension PointrApp: PTRDataManagerDelegate {
564
+ public func onDataManagerCompleteAll(for site: PTRSite, isSuccessful: Bool, dataFromOnline isOnlineData: Bool, errorMessages: [NSNumber : String]) {
565
+ if (!isOnlineData) {
566
+ return
567
+ }
568
+ while(self.mapDispatchGroupDataManager[site.internalIdentifier]?.isEmpty == false) {
569
+ if let dispatchGroup = self.mapDispatchGroupDataManager[site.internalIdentifier]?.removeLast() {
570
+ dispatchGroup.leave()
571
+ }
572
+ }
573
+ }
574
+ }
575
+
576
+ // TODO: remove below code when we have parameter to hide whole pathFindingViewController
577
+ extension PointrApp: PTRMapWidgetEventsListener {
578
+ public func mapWidgetWillPresentPathFinding(_ mapWidget: PTRMapWidgetViewController, pathFinding: PTRPathFindingViewController) {
579
+ pathFinding.view.isHidden = !isRouteFooterViewEnabled && !mapWidget.configuration.isRouteHeaderViewEnabled
580
+ }
581
+ }
@@ -0,0 +1,6 @@
1
+ //
2
+ // Use this file to import your target's public headers that you would like to expose to Swift.
3
+ //
4
+
5
+ #import <React/RCTBridgeModule.h>
6
+ #import <React/RCTViewManager.h>
package/package.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "react-native-pointr",
3
+ "version": "0.0.0",
4
+ "description": "Pointr React-Native Module",
5
+ "main": "src/index",
6
+ "author": " <> ()",
7
+ "license": "UNLICENSED",
8
+ "homepage": "#readme",
9
+ "create-react-native-library": {
10
+ "type": "module-legacy",
11
+ "languages": "kotlin-swift",
12
+ "version": "0.41.0"
13
+ }
14
+ }
@@ -0,0 +1,43 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+ folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
5
+
6
+ Pod::Spec.new do |s|
7
+ s.name = "react-native-pointr"
8
+ s.version = package["version"]
9
+ s.summary = package["description"]
10
+ s.homepage = package["homepage"]
11
+ s.license = package["license"]
12
+ s.authors = package["author"]
13
+
14
+ s.platforms = { :ios => min_ios_version_supported }
15
+ s.source = { :git => ".git", :tag => "#{s.version}" }
16
+
17
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
18
+
19
+ s.dependency "PointrKit", "8.13.0"
20
+
21
+ # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
22
+ # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
23
+ if respond_to?(:install_modules_dependencies, true)
24
+ install_modules_dependencies(s)
25
+ else
26
+ s.dependency "React/Core"
27
+
28
+ # Don't install the dependencies when we run `pod install` in the old architecture.
29
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
30
+ s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
31
+ s.pod_target_xcconfig = {
32
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
33
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
34
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
35
+ }
36
+ s.dependency "React-Codegen"
37
+ s.dependency "RCT-Folly"
38
+ s.dependency "RCTRequired"
39
+ s.dependency "RCTTypeSafety"
40
+ s.dependency "ReactCommon/turbomodule/core"
41
+ end
42
+ end
43
+ end
package/src/index.tsx ADDED
@@ -0,0 +1,20 @@
1
+ import { NativeModules, Platform } from 'react-native';
2
+
3
+ const LINKING_ERROR =
4
+ `The package 'react-native-pointr' doesn't seem to be linked. Make sure: \n\n` +
5
+ Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
6
+ '- You rebuilt the app after installing the package\n' +
7
+ '- You are not using Expo Go\n';
8
+
9
+ const PTRNativePointrLibrary = NativeModules.PTRNativePointrLibrary
10
+ ? NativeModules.PTRNativePointrLibrary
11
+ : new Proxy(
12
+ {},
13
+ {
14
+ get() {
15
+ throw new Error(LINKING_ERROR);
16
+ },
17
+ }
18
+ );
19
+
20
+ module.exports = PTRNativePointrLibrary;