@doorstepai/dropoff-sdk-capacitor 1.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.
- package/DoorstepaiDropoffSdkCapacitor.podspec +22 -0
- package/LICENSE +20 -0
- package/README.md +401 -0
- package/android/build.gradle +48 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/ai/doorstep/dropoffsdk/capacitor/DoorstepAIDropoffSDKPlugin.kt +291 -0
- package/dist/docs.json +705 -0
- package/dist/esm/definitions.d.ts +115 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +27 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +23 -0
- package/dist/esm/web.js +51 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +87 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +90 -0
- package/dist/plugin.js.map +1 -0
- package/ios/DoorstepDropoffSDK.xcframework/Info.plist +48 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/DoorstepDropoffSDK +0 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Headers/DoorstepDropoffSDK.h +19 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Headers/RateReducer.h +117 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Info.plist +0 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.abi.json +5281 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +117 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios.swiftinterface +117 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/Modules/module.modulemap +6 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/PrivacyInfo.xcprivacy +39 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/DoorstepDropoffSDK.framework/_CodeSignature/CodeResources +201 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Info.plist +20 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/DWARF/DoorstepDropoffSDK +0 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/DoorstepDropoffSDK.yml +2108 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/DoorstepDropoffSDK +0 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Headers/DoorstepDropoffSDK.h +19 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Headers/RateReducer.h +117 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Info.plist +0 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +5281 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +117 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +117 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +5281 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +117 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/DoorstepDropoffSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +117 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/Modules/module.modulemap +6 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/PrivacyInfo.xcprivacy +39 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/DoorstepDropoffSDK.framework/_CodeSignature/CodeResources +256 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Info.plist +20 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/DWARF/DoorstepDropoffSDK +0 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/DoorstepDropoffSDK.yml +2108 -0
- package/ios/DoorstepDropoffSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/DoorstepDropoffSDK.framework.dSYM/Contents/Resources/Relocations/x86_64/DoorstepDropoffSDK.yml +2098 -0
- package/ios/Plugin/DoorstepAIDropoffSDKPlugin.m +22 -0
- package/ios/Plugin/DoorstepAIDropoffSDKPlugin.swift +313 -0
- package/package.json +78 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import <Capacitor/Capacitor.h>
|
|
3
|
+
|
|
4
|
+
// Defines the plugin and its methods to the Capacitor runtime.
|
|
5
|
+
// Method names here MUST match the @objc func names in
|
|
6
|
+
// DoorstepAIDropoffSDKPlugin.swift, which in turn must match the keys used
|
|
7
|
+
// from JS via Capacitor.Plugins.DoorstepAIDropoffSDK.<method>.
|
|
8
|
+
CAP_PLUGIN(DoorstepAIDropoffSDKPlugin, "DoorstepAIDropoffSDK",
|
|
9
|
+
CAP_PLUGIN_METHOD(init, CAPPluginReturnPromise);
|
|
10
|
+
CAP_PLUGIN_METHOD(setApiKey, CAPPluginReturnPromise);
|
|
11
|
+
CAP_PLUGIN_METHOD(startDeliveryByPlaceID, CAPPluginReturnPromise);
|
|
12
|
+
CAP_PLUGIN_METHOD(startDeliveryByPlusCode, CAPPluginReturnPromise);
|
|
13
|
+
CAP_PLUGIN_METHOD(startDeliveryByAddress, CAPPluginReturnPromise);
|
|
14
|
+
CAP_PLUGIN_METHOD(startDeliveryByAddressType, CAPPluginReturnPromise);
|
|
15
|
+
CAP_PLUGIN_METHOD(startDeliveryByAddressString, CAPPluginReturnPromise);
|
|
16
|
+
CAP_PLUGIN_METHOD(startDeliveryByLatLng, CAPPluginReturnPromise);
|
|
17
|
+
CAP_PLUGIN_METHOD(markDropoff, CAPPluginReturnPromise);
|
|
18
|
+
CAP_PLUGIN_METHOD(newEvent, CAPPluginReturnPromise);
|
|
19
|
+
CAP_PLUGIN_METHOD(stopDelivery, CAPPluginReturnPromise);
|
|
20
|
+
CAP_PLUGIN_METHOD(checkPermissions, CAPPluginReturnPromise);
|
|
21
|
+
CAP_PLUGIN_METHOD(requestPermissions, CAPPluginReturnPromise);
|
|
22
|
+
)
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
import UIKit
|
|
4
|
+
import SwiftUI
|
|
5
|
+
import CoreLocation
|
|
6
|
+
import CoreMotion
|
|
7
|
+
import DoorstepDropoffSDK
|
|
8
|
+
|
|
9
|
+
@objc(DoorstepAIDropoffSDKPlugin)
|
|
10
|
+
public class DoorstepAIDropoffSDKPlugin: CAPPlugin, CLLocationManagerDelegate {
|
|
11
|
+
private var hostingController: UIHostingController<DoorstepAIRoot>?
|
|
12
|
+
|
|
13
|
+
private lazy var clManager: CLLocationManager = {
|
|
14
|
+
let m = CLLocationManager()
|
|
15
|
+
m.delegate = self
|
|
16
|
+
return m
|
|
17
|
+
}()
|
|
18
|
+
private var pendingLocationContinuation: CheckedContinuation<Void, Never>?
|
|
19
|
+
|
|
20
|
+
/// Mounts `DoorstepAIRoot` as a 0pt invisible subview of the webview's
|
|
21
|
+
/// view controller, mirroring the Flutter wrapper's zero-height `UiKitView`.
|
|
22
|
+
/// The SDK relies on SwiftUI lifecycle (onAppear / @StateObject) to start
|
|
23
|
+
/// its background machinery, so the host must be in the view hierarchy.
|
|
24
|
+
///
|
|
25
|
+
/// Idempotent. Safe to call from any thread; hops to main internally.
|
|
26
|
+
/// Called lazily on `setApiKey` (matches the Flutter widget's order:
|
|
27
|
+
/// init → setApiKey → host mounts).
|
|
28
|
+
private func ensureHiddenRootViewMounted() {
|
|
29
|
+
if Thread.isMainThread {
|
|
30
|
+
mountHiddenRootViewOnMain()
|
|
31
|
+
} else {
|
|
32
|
+
DispatchQueue.main.async { [weak self] in
|
|
33
|
+
self?.mountHiddenRootViewOnMain()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private func mountHiddenRootViewOnMain() {
|
|
39
|
+
guard hostingController == nil, let viewController = self.bridge?.viewController else { return }
|
|
40
|
+
viewController.loadViewIfNeeded()
|
|
41
|
+
let host = UIHostingController(rootView: DoorstepAIRoot())
|
|
42
|
+
host.view.frame = .zero
|
|
43
|
+
host.view.isHidden = true
|
|
44
|
+
host.view.isUserInteractionEnabled = false
|
|
45
|
+
viewController.view.addSubview(host.view)
|
|
46
|
+
hostingController = host
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@objc func `init`(_ call: CAPPluginCall) {
|
|
50
|
+
// iOS no-op: the Android foreground-service init has no iOS analogue.
|
|
51
|
+
call.resolve()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@objc func setApiKey(_ call: CAPPluginCall) {
|
|
55
|
+
guard let key = call.getString("key") else {
|
|
56
|
+
return call.reject("INVALID_ARGUMENTS: key missing")
|
|
57
|
+
}
|
|
58
|
+
DoorstepAI.setApiKey(key: key)
|
|
59
|
+
ensureHiddenRootViewMounted()
|
|
60
|
+
call.resolve()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@objc func startDeliveryByPlaceID(_ call: CAPPluginCall) {
|
|
64
|
+
guard let placeID = call.getString("placeID"),
|
|
65
|
+
let deliveryId = call.getString("deliveryId") else {
|
|
66
|
+
return call.reject("INVALID_ARGUMENTS: placeID or deliveryId missing")
|
|
67
|
+
}
|
|
68
|
+
let timeout = call.getDouble("timeoutSeconds")
|
|
69
|
+
Task {
|
|
70
|
+
do {
|
|
71
|
+
try await DoorstepAI.startDeliveryByPlaceID(placeID: placeID, deliveryId: deliveryId, timeoutSeconds: timeout)
|
|
72
|
+
call.resolve()
|
|
73
|
+
} catch {
|
|
74
|
+
call.reject("Failed to start delivery by Place ID: \(error.localizedDescription)", "E_START_DELIVERY")
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@objc func startDeliveryByPlusCode(_ call: CAPPluginCall) {
|
|
80
|
+
guard let plusCode = call.getString("plusCode"),
|
|
81
|
+
let deliveryId = call.getString("deliveryId") else {
|
|
82
|
+
return call.reject("INVALID_ARGUMENTS: plusCode or deliveryId missing")
|
|
83
|
+
}
|
|
84
|
+
let timeout = call.getDouble("timeoutSeconds")
|
|
85
|
+
Task {
|
|
86
|
+
do {
|
|
87
|
+
try await DoorstepAI.startDeliveryByPlusCode(plusCode: plusCode, deliveryId: deliveryId, timeoutSeconds: timeout)
|
|
88
|
+
call.resolve()
|
|
89
|
+
} catch {
|
|
90
|
+
call.reject("Failed to start delivery by Plus Code: \(error.localizedDescription)", "E_START_DELIVERY")
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@objc func startDeliveryByAddress(_ call: CAPPluginCall) {
|
|
96
|
+
startDeliveryByAddressTypeImpl(call)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@objc func startDeliveryByAddressType(_ call: CAPPluginCall) {
|
|
100
|
+
startDeliveryByAddressTypeImpl(call)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private func startDeliveryByAddressTypeImpl(_ call: CAPPluginCall) {
|
|
104
|
+
guard let addr = call.getObject("address") as? [String: String],
|
|
105
|
+
let deliveryId = call.getString("deliveryId"),
|
|
106
|
+
let street = addr["streetNumber"],
|
|
107
|
+
let route = addr["route"],
|
|
108
|
+
let locality = addr["locality"],
|
|
109
|
+
let admin1 = addr["administrativeAreaLevel1"],
|
|
110
|
+
let postal = addr["postalCode"] else {
|
|
111
|
+
return call.reject("Missing or invalid fields in address dictionary or deliveryId missing", "E_INVALID_ADDRESS")
|
|
112
|
+
}
|
|
113
|
+
let timeout = call.getDouble("timeoutSeconds")
|
|
114
|
+
let coordinates = parseCoordinates(call.getObject("coordinates"))
|
|
115
|
+
Task {
|
|
116
|
+
do {
|
|
117
|
+
let address = AddressType(
|
|
118
|
+
streetNumber: street,
|
|
119
|
+
route: route,
|
|
120
|
+
subPremise: addr["subPremise"] ?? "",
|
|
121
|
+
locality: locality,
|
|
122
|
+
administrativeAreaLevel1: admin1,
|
|
123
|
+
postalCode: postal
|
|
124
|
+
)
|
|
125
|
+
try await DoorstepAI.startDeliveryByAddressType(
|
|
126
|
+
address: address,
|
|
127
|
+
deliveryId: deliveryId,
|
|
128
|
+
coordinates: coordinates,
|
|
129
|
+
timeoutSeconds: timeout
|
|
130
|
+
)
|
|
131
|
+
call.resolve()
|
|
132
|
+
} catch let error as DoorstepAIError {
|
|
133
|
+
call.reject("Failed to start delivery by address: \(error.localizedDescription)", "E_START_DELIVERY")
|
|
134
|
+
} catch {
|
|
135
|
+
call.reject("An unexpected error occurred: \(error.localizedDescription)", "E_UNKNOWN")
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@objc func startDeliveryByAddressString(_ call: CAPPluginCall) {
|
|
141
|
+
guard let address = call.getString("address"),
|
|
142
|
+
let deliveryId = call.getString("deliveryId") else {
|
|
143
|
+
return call.reject("INVALID_ARGUMENTS: address or deliveryId missing")
|
|
144
|
+
}
|
|
145
|
+
let timeout = call.getDouble("timeoutSeconds")
|
|
146
|
+
let coordinates = parseCoordinates(call.getObject("coordinates"))
|
|
147
|
+
Task {
|
|
148
|
+
do {
|
|
149
|
+
try await DoorstepAI.startDeliveryByAddressString(
|
|
150
|
+
address: address,
|
|
151
|
+
deliveryId: deliveryId,
|
|
152
|
+
coordinates: coordinates,
|
|
153
|
+
timeoutSeconds: timeout
|
|
154
|
+
)
|
|
155
|
+
call.resolve()
|
|
156
|
+
} catch {
|
|
157
|
+
call.reject("Failed to start delivery by address string: \(error.localizedDescription)", "E_START_DELIVERY")
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@objc func startDeliveryByLatLng(_ call: CAPPluginCall) {
|
|
163
|
+
guard let latitude = call.getDouble("latitude"),
|
|
164
|
+
let longitude = call.getDouble("longitude"),
|
|
165
|
+
let deliveryId = call.getString("deliveryId") else {
|
|
166
|
+
return call.reject("INVALID_ARGUMENTS: latitude, longitude or deliveryId missing")
|
|
167
|
+
}
|
|
168
|
+
let subUnit = call.getString("subUnit") ?? ""
|
|
169
|
+
let timeout = call.getDouble("timeoutSeconds")
|
|
170
|
+
Task {
|
|
171
|
+
do {
|
|
172
|
+
try await DoorstepAI.startDeliveryByLatLng(latitude: latitude, longitude: longitude, subUnit: subUnit, deliveryId: deliveryId, timeoutSeconds: timeout)
|
|
173
|
+
call.resolve()
|
|
174
|
+
} catch {
|
|
175
|
+
call.reject("Failed to start delivery by LatLng: \(error.localizedDescription)", "E_START_DELIVERY")
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@objc func markDropoff(_ call: CAPPluginCall) {
|
|
181
|
+
guard let deliveryId = call.getString("deliveryId"),
|
|
182
|
+
let dropoffTypeStr = call.getString("dropoffType") else {
|
|
183
|
+
return call.reject("INVALID_ARGUMENTS: deliveryId or dropoffType missing")
|
|
184
|
+
}
|
|
185
|
+
let dropoffType: DropoffType = dropoffTypeStr == "pod" ? .pod : .non_pod
|
|
186
|
+
Task {
|
|
187
|
+
do {
|
|
188
|
+
try await DoorstepAI.markDropoff(deliveryId: deliveryId, dropoffType: dropoffType)
|
|
189
|
+
call.resolve()
|
|
190
|
+
} catch {
|
|
191
|
+
call.reject("Failed to mark dropoff: \(error.localizedDescription)", "E_MARK_DROPOFF")
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
@objc func newEvent(_ call: CAPPluginCall) {
|
|
197
|
+
guard let eventName = call.getString("eventName"),
|
|
198
|
+
let deliveryId = call.getString("deliveryId") else {
|
|
199
|
+
return call.reject("INVALID_ARGUMENTS: eventName or deliveryId missing")
|
|
200
|
+
}
|
|
201
|
+
Task {
|
|
202
|
+
do {
|
|
203
|
+
try await DoorstepAI.newEvent(eventName: eventName, deliveryId: deliveryId)
|
|
204
|
+
call.resolve()
|
|
205
|
+
} catch {
|
|
206
|
+
call.reject("Failed to send event: \(error.localizedDescription)", "E_NEW_EVENT")
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@objc func stopDelivery(_ call: CAPPluginCall) {
|
|
212
|
+
guard let deliveryId = call.getString("deliveryId") else {
|
|
213
|
+
return call.reject("INVALID_ARGUMENTS: deliveryId missing")
|
|
214
|
+
}
|
|
215
|
+
Task {
|
|
216
|
+
await DoorstepAI.stopDelivery(deliveryId: deliveryId)
|
|
217
|
+
call.resolve()
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// MARK: - Permissions
|
|
222
|
+
|
|
223
|
+
private static let allPermissionAliases = ["location", "activity"]
|
|
224
|
+
|
|
225
|
+
@objc override public func checkPermissions(_ call: CAPPluginCall) {
|
|
226
|
+
Task {
|
|
227
|
+
let status = await currentPermissionStatus()
|
|
228
|
+
call.resolve(status)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@objc override public func requestPermissions(_ call: CAPPluginCall) {
|
|
233
|
+
let requested = call.getArray("permissions", String.self) ?? Self.allPermissionAliases
|
|
234
|
+
Task {
|
|
235
|
+
for alias in requested {
|
|
236
|
+
await requestPermission(alias)
|
|
237
|
+
}
|
|
238
|
+
let status = await currentPermissionStatus()
|
|
239
|
+
call.resolve(status)
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
private func currentPermissionStatus() async -> [String: String] {
|
|
244
|
+
let location: String
|
|
245
|
+
switch clManager.authorizationStatus {
|
|
246
|
+
case .notDetermined: location = "prompt"
|
|
247
|
+
case .restricted, .denied: location = "denied"
|
|
248
|
+
case .authorizedWhenInUse, .authorizedAlways: location = "granted"
|
|
249
|
+
@unknown default: location = "denied"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
let activity: String
|
|
253
|
+
switch CMMotionActivityManager.authorizationStatus() {
|
|
254
|
+
case .notDetermined: activity = "prompt"
|
|
255
|
+
case .restricted, .denied: activity = "denied"
|
|
256
|
+
case .authorized: activity = "granted"
|
|
257
|
+
@unknown default: activity = "denied"
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return [
|
|
261
|
+
"location": location,
|
|
262
|
+
"activity": activity,
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private func requestPermission(_ alias: String) async {
|
|
267
|
+
switch alias {
|
|
268
|
+
case "location":
|
|
269
|
+
await requestLocationAuthorization()
|
|
270
|
+
case "activity":
|
|
271
|
+
await requestActivityAuthorization()
|
|
272
|
+
default:
|
|
273
|
+
break
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private func requestLocationAuthorization() async {
|
|
278
|
+
guard clManager.authorizationStatus == .notDetermined else { return }
|
|
279
|
+
await withCheckedContinuation { (cont: CheckedContinuation<Void, Never>) in
|
|
280
|
+
DispatchQueue.main.async { [weak self] in
|
|
281
|
+
guard let self = self else { cont.resume(); return }
|
|
282
|
+
self.pendingLocationContinuation = cont
|
|
283
|
+
self.clManager.requestWhenInUseAuthorization()
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
public func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
|
|
289
|
+
let cont = pendingLocationContinuation
|
|
290
|
+
pendingLocationContinuation = nil
|
|
291
|
+
cont?.resume()
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
private func requestActivityAuthorization() async {
|
|
295
|
+
// CMMotionActivityManager prompts the user the first time data is
|
|
296
|
+
// queried. We trigger that with a no-op query.
|
|
297
|
+
await withCheckedContinuation { (cont: CheckedContinuation<Void, Never>) in
|
|
298
|
+
let mgr = CMMotionActivityManager()
|
|
299
|
+
mgr.queryActivityStarting(from: Date(timeIntervalSinceNow: -60), to: Date(), to: .main) { _, _ in
|
|
300
|
+
cont.resume()
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
private func parseCoordinates(_ raw: [AnyHashable: Any]?) -> LatLngObject? {
|
|
306
|
+
guard let coordinates = raw,
|
|
307
|
+
let lat = coordinates["lat"] as? Double,
|
|
308
|
+
let lng = coordinates["lng"] as? Double else {
|
|
309
|
+
return nil
|
|
310
|
+
}
|
|
311
|
+
return LatLngObject(lat: lat, lng: lng)
|
|
312
|
+
}
|
|
313
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@doorstepai/dropoff-sdk-capacitor",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Capacitor plugin for DoorstepAI's Dropoff SDK",
|
|
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/Plugin/",
|
|
14
|
+
"ios/DoorstepDropoffSDK.xcframework/",
|
|
15
|
+
"DoorstepaiDropoffSdkCapacitor.podspec"
|
|
16
|
+
],
|
|
17
|
+
"author": "Doing Doorstep Better, Inc.",
|
|
18
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+ssh://git@gitlab.com/doorstepai/tracking/sdk/capacitor.git"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"capacitor",
|
|
25
|
+
"plugin",
|
|
26
|
+
"native",
|
|
27
|
+
"doorstep",
|
|
28
|
+
"dropoff",
|
|
29
|
+
"delivery"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
33
|
+
"verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin -destination generic/platform=iOS && cd ..",
|
|
34
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
35
|
+
"verify:web": "npm run build",
|
|
36
|
+
"lint": "npm run eslint && npm run prettier -- --check",
|
|
37
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write",
|
|
38
|
+
"eslint": "eslint . --ext ts",
|
|
39
|
+
"prettier": "prettier \"**/*.{css,html,ts,js,java}\"",
|
|
40
|
+
"docgen": "docgen --api DoorstepAIDropoffSDKPlugin --output-readme README.md --output-json dist/docs.json",
|
|
41
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.js",
|
|
42
|
+
"clean": "rimraf ./dist",
|
|
43
|
+
"watch": "tsc --watch",
|
|
44
|
+
"prepublishOnly": "npm run build"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@capacitor/android": "^7.0.0",
|
|
48
|
+
"@capacitor/core": "^7.0.0",
|
|
49
|
+
"@capacitor/docgen": "^0.3.0",
|
|
50
|
+
"@capacitor/ios": "^7.0.0",
|
|
51
|
+
"@ionic/eslint-config": "^0.4.0",
|
|
52
|
+
"@ionic/prettier-config": "^4.0.0",
|
|
53
|
+
"@ionic/swiftlint-config": "^2.0.0",
|
|
54
|
+
"eslint": "^8.57.0",
|
|
55
|
+
"prettier": "~3.3.3",
|
|
56
|
+
"prettier-plugin-java": "~2.6.4",
|
|
57
|
+
"rimraf": "^5.0.5",
|
|
58
|
+
"rollup": "^4.18.0",
|
|
59
|
+
"swiftlint": "^2.0.0",
|
|
60
|
+
"typescript": "~5.4.5"
|
|
61
|
+
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"@capacitor/core": "^7.0.0"
|
|
64
|
+
},
|
|
65
|
+
"prettier": "@ionic/prettier-config",
|
|
66
|
+
"swiftlint": "@ionic/swiftlint-config",
|
|
67
|
+
"eslintConfig": {
|
|
68
|
+
"extends": "@ionic/eslint-config/recommended"
|
|
69
|
+
},
|
|
70
|
+
"capacitor": {
|
|
71
|
+
"ios": {
|
|
72
|
+
"src": "ios"
|
|
73
|
+
},
|
|
74
|
+
"android": {
|
|
75
|
+
"src": "android"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|