capacitor-google-navigation 0.0.1

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,110 @@
1
+ import Foundation
2
+ import GoogleNavigation
3
+
4
+ @objc public class GoogleNavigation: NSObject {
5
+ private weak var plugin: CAPPlugin?
6
+ private var navViewController: GMSNavigationViewController?
7
+ private var navigator: GMSNavigator?
8
+
9
+ init(plugin: CAPPlugin) {
10
+ self.plugin = plugin
11
+ super.init()
12
+ }
13
+
14
+ func initialize(apiKey: String, completion: @escaping (Bool, String?) -> Void) {
15
+ DispatchQueue.main.async {
16
+ GMSServices.provideAPIKey(apiKey)
17
+ completion(true, nil)
18
+ }
19
+ }
20
+
21
+ func presentNavigationViewController(
22
+ from viewController: UIViewController?,
23
+ completion: @escaping (Bool, String?) -> Void
24
+ ) {
25
+ guard let presentingVC = viewController else {
26
+ completion(false, "No presenting view controller available")
27
+ return
28
+ }
29
+
30
+ let navVC = GMSNavigationViewController()
31
+ navVC.modalPresentationStyle = .fullScreen
32
+ navVC.delegate = self
33
+ self.navViewController = navVC
34
+ self.navigator = navVC.mapView.navigator
35
+
36
+ presentingVC.present(navVC, animated: true) {
37
+ self.plugin?.notifyListeners("onNavigationReady", data: [:])
38
+ completion(true, nil)
39
+ }
40
+ }
41
+
42
+ func dismissNavigationViewController(completion: @escaping () -> Void) {
43
+ navViewController?.dismiss(animated: true) {
44
+ self.navViewController = nil
45
+ self.navigator = nil
46
+ completion()
47
+ }
48
+ }
49
+
50
+ func startNavigation(
51
+ lat: Double,
52
+ lng: Double,
53
+ travelMode: String,
54
+ completion: @escaping (Bool, String?) -> Void
55
+ ) {
56
+ guard let navigator = self.navigator else {
57
+ completion(false, "Navigation view must be shown before starting navigation")
58
+ return
59
+ }
60
+
61
+ let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lng)
62
+ guard let waypoint = try? GMSNavigationWaypoint(location: coordinate, title: "Destination") else {
63
+ completion(false, "Failed to create waypoint")
64
+ return
65
+ }
66
+
67
+ let mode: GMSNavigationTravelMode
68
+ switch travelMode {
69
+ case "WALKING": mode = .walking
70
+ case "CYCLING": mode = .cycling
71
+ case "TWO_WHEELER": mode = .twoWheeler
72
+ default: mode = .driving
73
+ }
74
+ navViewController?.mapView.travelMode = mode
75
+
76
+ navigator.setDestinations([waypoint]) { routeStatus in
77
+ if routeStatus == .OK {
78
+ navigator.isGuidanceActive = true
79
+ self.navViewController?.mapView.cameraMode = .following
80
+ completion(true, nil)
81
+ } else {
82
+ completion(false, "Route calculation failed: \(routeStatus.rawValue)")
83
+ }
84
+ }
85
+ }
86
+
87
+ func stopNavigation() {
88
+ navigator?.isGuidanceActive = false
89
+ navigator?.clearDestinations()
90
+ }
91
+ }
92
+
93
+ extension GoogleNavigation: GMSNavigationViewControllerDelegate {
94
+ public func navigationViewController(
95
+ _ navigationViewController: GMSNavigationViewController,
96
+ didArriveAtWaypoint waypoint: GMSNavigationWaypoint
97
+ ) {
98
+ plugin?.notifyListeners("onArrival", data: [
99
+ "latitude": waypoint.coordinate.latitude,
100
+ "longitude": waypoint.coordinate.longitude,
101
+ "title": waypoint.title ?? ""
102
+ ])
103
+ }
104
+
105
+ public func navigationViewControllerDidChangeRoute(
106
+ _ navigationViewController: GMSNavigationViewController
107
+ ) {
108
+ plugin?.notifyListeners("onRouteChanged", data: [:])
109
+ }
110
+ }
@@ -0,0 +1,69 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ @objc(GoogleNavigationPlugin)
5
+ public class GoogleNavigationPlugin: CAPPlugin, CAPBridgedPlugin {
6
+ public let identifier = "GoogleNavigationPlugin"
7
+ public let jsName = "GoogleNavigation"
8
+ public let pluginMethods: [CAPPluginMethod] = [
9
+ CAPPluginMethod(name: "initialize", returnType: CAPPluginReturnPromise),
10
+ CAPPluginMethod(name: "startNavigation", returnType: CAPPluginReturnPromise),
11
+ CAPPluginMethod(name: "stopNavigation", returnType: CAPPluginReturnPromise),
12
+ CAPPluginMethod(name: "showNavigationView", returnType: CAPPluginReturnPromise),
13
+ ]
14
+ private lazy var implementation = GoogleNavigation(plugin: self)
15
+
16
+ @objc func initialize(_ call: CAPPluginCall) {
17
+ guard let apiKey = call.getString("apiKey"), !apiKey.isEmpty else {
18
+ call.reject("apiKey is required")
19
+ return
20
+ }
21
+ implementation.initialize(apiKey: apiKey) { success, error in
22
+ if let error = error {
23
+ call.reject(error)
24
+ } else {
25
+ call.resolve(["success": success])
26
+ }
27
+ }
28
+ }
29
+
30
+ @objc func startNavigation(_ call: CAPPluginCall) {
31
+ guard let lat = call.getDouble("destinationLatitude"),
32
+ let lng = call.getDouble("destinationLongitude") else {
33
+ call.reject("destinationLatitude and destinationLongitude are required")
34
+ return
35
+ }
36
+ let travelMode = call.getString("travelMode") ?? "DRIVING"
37
+ implementation.startNavigation(lat: lat, lng: lng, travelMode: travelMode) { success, error in
38
+ if let error = error {
39
+ call.reject(error)
40
+ } else {
41
+ call.resolve(["success": success])
42
+ }
43
+ }
44
+ }
45
+
46
+ @objc func stopNavigation(_ call: CAPPluginCall) {
47
+ implementation.stopNavigation()
48
+ call.resolve(["success": true])
49
+ }
50
+
51
+ @objc func showNavigationView(_ call: CAPPluginCall) {
52
+ let show = call.getBool("show") ?? true
53
+ DispatchQueue.main.async {
54
+ if show {
55
+ self.implementation.presentNavigationViewController(from: self.bridge?.viewController) { success, error in
56
+ if let error = error {
57
+ call.reject(error)
58
+ } else {
59
+ call.resolve(["success": success])
60
+ }
61
+ }
62
+ } else {
63
+ self.implementation.dismissNavigationViewController {
64
+ call.resolve(["success": true])
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,15 @@
1
+ import XCTest
2
+ @testable import GoogleNavigationPlugin
3
+
4
+ class GoogleNavigationTests: XCTestCase {
5
+ func testEcho() {
6
+ // This is an example of a functional test case for a plugin.
7
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
8
+
9
+ let implementation = GoogleNavigation()
10
+ let value = "Hello, World!"
11
+ let result = implementation.echo(value)
12
+
13
+ XCTAssertEqual(value, result)
14
+ }
15
+ }
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "capacitor-google-navigation",
3
+ "version": "0.0.1",
4
+ "description": "Google maps turn by turn navigation for capcitor",
5
+ "main": "dist/plugin.cjs.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/esm/index.d.ts",
8
+ "unpkg": "dist/plugin.js",
9
+ "files": [
10
+ "android/src/main/",
11
+ "android/build.gradle",
12
+ "dist/",
13
+ "ios/Sources",
14
+ "ios/Tests",
15
+ "Package.swift",
16
+ "CapacitorGoogleNavigation.podspec"
17
+ ],
18
+ "author": "Zayne Komichi",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/Aurora-Systems/capacitor-google-navigation.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/Aurora-Systems/capacitor-google-navigation/issues"
26
+ },
27
+ "keywords": [
28
+ "capacitor",
29
+ "plugin",
30
+ "native"
31
+ ],
32
+ "scripts": {
33
+ "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
34
+ "verify:ios": "xcodebuild -scheme CapacitorGoogleNavigation -destination generic/platform=iOS",
35
+ "verify:android": "cd android && ./gradlew clean build test && cd ..",
36
+ "verify:web": "npm run build",
37
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
38
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
39
+ "eslint": "eslint . --ext ts",
40
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
41
+ "swiftlint": "node-swiftlint",
42
+ "docgen": "docgen --api GoogleNavigationPlugin --output-readme README.md --output-json dist/docs.json",
43
+ "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
44
+ "clean": "rimraf ./dist",
45
+ "watch": "tsc --watch",
46
+ "prepublishOnly": "npm run build"
47
+ },
48
+ "devDependencies": {
49
+ "@capacitor/android": "^8.0.0",
50
+ "@capacitor/core": "^8.0.0",
51
+ "@capacitor/docgen": "^0.3.1",
52
+ "@capacitor/ios": "^8.0.0",
53
+ "@ionic/eslint-config": "^0.4.0",
54
+ "@ionic/prettier-config": "^4.0.0",
55
+ "@ionic/swiftlint-config": "^2.0.0",
56
+ "eslint": "^8.57.1",
57
+ "prettier": "^3.6.2",
58
+ "prettier-plugin-java": "^2.7.7",
59
+ "rimraf": "^6.1.0",
60
+ "rollup": "^4.53.2",
61
+ "swiftlint": "^2.0.0",
62
+ "typescript": "^5.9.3"
63
+ },
64
+ "peerDependencies": {
65
+ "@capacitor/core": ">=8.0.0"
66
+ },
67
+ "prettier": "@ionic/prettier-config",
68
+ "swiftlint": "@ionic/swiftlint-config",
69
+ "eslintConfig": {
70
+ "extends": "@ionic/eslint-config/recommended"
71
+ },
72
+ "capacitor": {
73
+ "ios": {
74
+ "src": "ios"
75
+ },
76
+ "android": {
77
+ "src": "android"
78
+ }
79
+ }
80
+ }