@thelacanians/vue-native-cli 0.4.3 → 0.4.4

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.
Files changed (172) hide show
  1. package/dist/cli.js +34 -17
  2. package/native/android/README.md +205 -0
  3. package/native/android/VueNativeCore/build.gradle.kts +100 -0
  4. package/native/android/VueNativeCore/consumer-rules.pro +12 -0
  5. package/native/android/VueNativeCore/proguard-rules.pro +33 -0
  6. package/native/android/VueNativeCore/src/main/AndroidManifest.xml +17 -0
  7. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/ErrorOverlayView.kt +94 -0
  8. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/HotReloadManager.kt +105 -0
  9. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSPolyfills.kt +652 -0
  10. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSRuntime.kt +207 -0
  11. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/NativeBridge.kt +417 -0
  12. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/ComponentRegistry.kt +76 -0
  13. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActionSheetFactory.kt +78 -0
  14. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActivityIndicatorFactory.kt +46 -0
  15. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VAlertDialogFactory.kt +84 -0
  16. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VButtonFactory.kt +73 -0
  17. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VCheckboxFactory.kt +93 -0
  18. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VDropdownFactory.kt +125 -0
  19. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VImageFactory.kt +75 -0
  20. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VInputFactory.kt +210 -0
  21. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VKeyboardAvoidingFactory.kt +31 -0
  22. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VListFactory.kt +183 -0
  23. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VModalFactory.kt +105 -0
  24. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPickerFactory.kt +57 -0
  25. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPressableFactory.kt +109 -0
  26. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VProgressBarFactory.kt +43 -0
  27. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRadioFactory.kt +103 -0
  28. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRefreshControlFactory.kt +73 -0
  29. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRootFactory.kt +39 -0
  30. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSafeAreaFactory.kt +48 -0
  31. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VScrollViewFactory.kt +105 -0
  32. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSectionListFactory.kt +144 -0
  33. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSegmentedControlFactory.kt +77 -0
  34. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSliderFactory.kt +74 -0
  35. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VStatusBarFactory.kt +52 -0
  36. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSwitchFactory.kt +62 -0
  37. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VTextFactory.kt +53 -0
  38. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VVideoFactory.kt +191 -0
  39. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VViewFactory.kt +48 -0
  40. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VWebViewFactory.kt +90 -0
  41. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/NativeComponentFactory.kt +40 -0
  42. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/VTextNodeView.kt +23 -0
  43. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/GestureHelper.kt +16 -0
  44. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/TouchableView.kt +105 -0
  45. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AnimationModule.kt +292 -0
  46. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AppStateModule.kt +41 -0
  47. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AsyncStorageModule.kt +59 -0
  48. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AudioModule.kt +331 -0
  49. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BackgroundTaskModule.kt +166 -0
  50. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BiometryModule.kt +56 -0
  51. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BluetoothModule.kt +302 -0
  52. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CalendarModule.kt +198 -0
  53. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CameraModule.kt +64 -0
  54. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ClipboardModule.kt +36 -0
  55. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ContactsModule.kt +288 -0
  56. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DatabaseModule.kt +229 -0
  57. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DeviceInfoModule.kt +39 -0
  58. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/FileSystemModule.kt +193 -0
  59. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/GeolocationModule.kt +68 -0
  60. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HapticsModule.kt +61 -0
  61. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HttpModule.kt +111 -0
  62. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/IAPModule.kt +302 -0
  63. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/KeyboardModule.kt +26 -0
  64. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/LinkingModule.kt +43 -0
  65. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModule.kt +27 -0
  66. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModuleRegistry.kt +92 -0
  67. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NetworkModule.kt +75 -0
  68. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NotificationsModule.kt +181 -0
  69. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/OTAModule.kt +255 -0
  70. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PerformanceModule.kt +147 -0
  71. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PermissionsModule.kt +126 -0
  72. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SecureStorageModule.kt +51 -0
  73. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SensorsModule.kt +134 -0
  74. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ShareModule.kt +36 -0
  75. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SocialAuthModule.kt +160 -0
  76. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/WebSocketModule.kt +155 -0
  77. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Styling/StyleEngine.kt +802 -0
  78. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Tags.kt +43 -0
  79. package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/VueNativeActivity.kt +169 -0
  80. package/native/android/VueNativeCore/src/main/res/values/ids.xml +8 -0
  81. package/native/android/app/build.gradle.kts +45 -0
  82. package/native/android/app/proguard-rules.pro +5 -0
  83. package/native/android/app/src/main/AndroidManifest.xml +25 -0
  84. package/native/android/app/src/main/assets/.gitkeep +0 -0
  85. package/native/android/app/src/main/kotlin/com/vuenative/example/counter/MainActivity.kt +14 -0
  86. package/native/android/app/src/main/res/layout/activity_main.xml +6 -0
  87. package/native/android/app/src/main/res/values/strings.xml +3 -0
  88. package/native/android/app/src/main/res/values/themes.xml +9 -0
  89. package/native/android/app/src/main/res/xml/network_security_config.xml +8 -0
  90. package/native/android/build.gradle.kts +6 -0
  91. package/native/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  92. package/native/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  93. package/native/android/gradle.properties +4 -0
  94. package/native/android/gradlew +87 -0
  95. package/native/android/gradlew.bat +48 -0
  96. package/native/android/settings.gradle.kts +20 -0
  97. package/native/ios/VueNativeCore/Package.resolved +23 -0
  98. package/native/ios/VueNativeCore/Package.swift +32 -0
  99. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/CertificatePinning.swift +132 -0
  100. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/ErrorOverlayView.swift +92 -0
  101. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/HotReloadManager.swift +147 -0
  102. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSPolyfills.swift +711 -0
  103. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSRuntime.swift +421 -0
  104. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/NativeBridge.swift +891 -0
  105. package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/VueNativeViewController.swift +88 -0
  106. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/ComponentRegistry.swift +193 -0
  107. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActionSheetFactory.swift +91 -0
  108. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActivityIndicatorFactory.swift +74 -0
  109. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VAlertDialogFactory.swift +150 -0
  110. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VButtonFactory.swift +93 -0
  111. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VCheckboxFactory.swift +114 -0
  112. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VDropdownFactory.swift +112 -0
  113. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VImageFactory.swift +172 -0
  114. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VInputFactory.swift +357 -0
  115. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VKeyboardAvoidingFactory.swift +99 -0
  116. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VListFactory.swift +250 -0
  117. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VModalFactory.swift +112 -0
  118. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPickerFactory.swift +96 -0
  119. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPressableFactory.swift +168 -0
  120. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VProgressBarFactory.swift +39 -0
  121. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRadioFactory.swift +167 -0
  122. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRefreshControlFactory.swift +153 -0
  123. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSafeAreaFactory.swift +56 -0
  124. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VScrollViewFactory.swift +240 -0
  125. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSectionListFactory.swift +248 -0
  126. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSegmentedControlFactory.swift +73 -0
  127. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSliderFactory.swift +63 -0
  128. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VStatusBarFactory.swift +50 -0
  129. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSwitchFactory.swift +108 -0
  130. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VTextFactory.swift +290 -0
  131. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VVideoFactory.swift +246 -0
  132. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VViewFactory.swift +157 -0
  133. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VWebViewFactory.swift +172 -0
  134. package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/NativeComponentFactory.swift +53 -0
  135. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/GestureWrapper.swift +107 -0
  136. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/TouchableView.swift +136 -0
  137. package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/UIColor+Hex.swift +80 -0
  138. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AnimationModule.swift +291 -0
  139. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AppStateModule.swift +65 -0
  140. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AsyncStorageModule.swift +68 -0
  141. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AudioModule.swift +366 -0
  142. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BackgroundTaskModule.swift +135 -0
  143. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BiometryModule.swift +61 -0
  144. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BluetoothModule.swift +387 -0
  145. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CalendarModule.swift +161 -0
  146. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CameraModule.swift +318 -0
  147. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ClipboardModule.swift +33 -0
  148. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ContactsModule.swift +173 -0
  149. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DatabaseModule.swift +259 -0
  150. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DeviceInfoModule.swift +34 -0
  151. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/FileSystemModule.swift +233 -0
  152. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/GeolocationModule.swift +147 -0
  153. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/HapticsModule.swift +50 -0
  154. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/IAPModule.swift +194 -0
  155. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/KeyboardModule.swift +31 -0
  156. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/LinkingModule.swift +42 -0
  157. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModule.swift +28 -0
  158. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModuleRegistry.swift +78 -0
  159. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NetworkModule.swift +62 -0
  160. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NotificationsModule.swift +215 -0
  161. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/OTAModule.swift +281 -0
  162. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PerformanceModule.swift +138 -0
  163. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PermissionsModule.swift +190 -0
  164. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SecureStorageModule.swift +118 -0
  165. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SensorsModule.swift +103 -0
  166. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ShareModule.swift +49 -0
  167. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SocialAuthModule.swift +240 -0
  168. package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/WebSocketModule.swift +213 -0
  169. package/native/ios/VueNativeCore/Sources/VueNativeCore/Resources/vue-native-placeholder.js +8 -0
  170. package/native/ios/VueNativeCore/Sources/VueNativeCore/Styling/StyleEngine.swift +885 -0
  171. package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/JSRuntimeTests.swift +362 -0
  172. package/package.json +3 -2
@@ -0,0 +1,190 @@
1
+ #if canImport(UIKit)
2
+ import UIKit
3
+ import AVFoundation
4
+ import Photos
5
+ import CoreLocation
6
+ import UserNotifications
7
+
8
+ /// Native module for checking and requesting system permissions.
9
+ ///
10
+ /// Supported permissions: "camera", "microphone", "photos", "location",
11
+ /// "locationAlways", "notifications"
12
+ ///
13
+ /// Status strings: "granted", "denied", "restricted", "limited", "notDetermined"
14
+ final class PermissionsModule: NativeModule {
15
+ var moduleName: String { "Permissions" }
16
+
17
+ func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
18
+ switch method {
19
+ case "check":
20
+ guard let permission = args.first as? String else {
21
+ callback(nil, "PermissionsModule: missing permission name"); return
22
+ }
23
+ checkPermission(permission, callback: callback)
24
+ case "request":
25
+ guard let permission = args.first as? String else {
26
+ callback(nil, "PermissionsModule: missing permission name"); return
27
+ }
28
+ requestPermission(permission, callback: callback)
29
+ default:
30
+ callback(nil, "PermissionsModule: Unknown method '\(method)'")
31
+ }
32
+ }
33
+
34
+ // MARK: - Check
35
+
36
+ private func checkPermission(_ permission: String, callback: @escaping (Any?, String?) -> Void) {
37
+ switch permission {
38
+ case "camera":
39
+ callback(statusString(avStatus: AVCaptureDevice.authorizationStatus(for: .video)), nil)
40
+ case "microphone":
41
+ callback(statusString(avStatus: AVCaptureDevice.authorizationStatus(for: .audio)), nil)
42
+ case "photos":
43
+ callback(statusString(photoStatus: PHPhotoLibrary.authorizationStatus(for: .readWrite)), nil)
44
+ case "location", "locationAlways":
45
+ // CLLocationManager.authorizationStatus() instance method must be called on main thread.
46
+ DispatchQueue.main.async {
47
+ let mgr = CLLocationManager()
48
+ callback(self.statusString(locationStatus: mgr.authorizationStatus), nil)
49
+ }
50
+ case "notifications":
51
+ UNUserNotificationCenter.current().getNotificationSettings { settings in
52
+ callback(self.statusString(notifStatus: settings.authorizationStatus), nil)
53
+ }
54
+ default:
55
+ callback("notDetermined", nil)
56
+ }
57
+ }
58
+
59
+ // MARK: - Request
60
+
61
+ private func requestPermission(_ permission: String, callback: @escaping (Any?, String?) -> Void) {
62
+ switch permission {
63
+ case "camera":
64
+ AVCaptureDevice.requestAccess(for: .video) { granted in
65
+ callback(granted ? "granted" : "denied", nil)
66
+ }
67
+ case "microphone":
68
+ AVCaptureDevice.requestAccess(for: .audio) { granted in
69
+ callback(granted ? "granted" : "denied", nil)
70
+ }
71
+ case "photos":
72
+ PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
73
+ callback(self.statusString(photoStatus: status), nil)
74
+ }
75
+ case "location":
76
+ // LocationPermissionRequester is @MainActor — must dispatch to main.
77
+ DispatchQueue.main.async {
78
+ LocationPermissionRequester.shared.request(always: false, callback: callback)
79
+ }
80
+ case "locationAlways":
81
+ DispatchQueue.main.async {
82
+ LocationPermissionRequester.shared.request(always: true, callback: callback)
83
+ }
84
+ case "notifications":
85
+ UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in
86
+ callback(granted ? "granted" : "denied", nil)
87
+ }
88
+ default:
89
+ callback("notDetermined", nil)
90
+ }
91
+ }
92
+
93
+ // MARK: - Status helpers
94
+
95
+ private func statusString(avStatus: AVAuthorizationStatus) -> String {
96
+ switch avStatus {
97
+ case .authorized: return "granted"
98
+ case .denied: return "denied"
99
+ case .restricted: return "restricted"
100
+ case .notDetermined: return "notDetermined"
101
+ @unknown default: return "notDetermined"
102
+ }
103
+ }
104
+
105
+ private func statusString(photoStatus: PHAuthorizationStatus) -> String {
106
+ switch photoStatus {
107
+ case .authorized: return "granted"
108
+ case .denied: return "denied"
109
+ case .restricted: return "restricted"
110
+ case .notDetermined: return "notDetermined"
111
+ case .limited: return "limited"
112
+ @unknown default: return "notDetermined"
113
+ }
114
+ }
115
+
116
+ private func statusString(locationStatus: CLAuthorizationStatus) -> String {
117
+ switch locationStatus {
118
+ case .authorizedWhenInUse, .authorizedAlways: return "granted"
119
+ case .denied: return "denied"
120
+ case .restricted: return "restricted"
121
+ case .notDetermined: return "notDetermined"
122
+ @unknown default: return "notDetermined"
123
+ }
124
+ }
125
+
126
+ private func statusString(notifStatus: UNAuthorizationStatus) -> String {
127
+ switch notifStatus {
128
+ case .authorized, .provisional, .ephemeral: return "granted"
129
+ case .denied: return "denied"
130
+ case .notDetermined: return "notDetermined"
131
+ @unknown default: return "notDetermined"
132
+ }
133
+ }
134
+
135
+ func invokeSync(method: String, args: [Any]) -> Any? { nil }
136
+ }
137
+
138
+ // MARK: - Location permission helper
139
+
140
+ /// CLLocationManager must be created and used on the main thread.
141
+ /// This helper lives on @MainActor and drives the one-shot request flow.
142
+ @MainActor
143
+ private final class LocationPermissionRequester: NSObject, CLLocationManagerDelegate {
144
+ static let shared = LocationPermissionRequester()
145
+
146
+ private var manager: CLLocationManager?
147
+ private var pendingCallback: ((Any?, String?) -> Void)?
148
+
149
+ func request(always: Bool, callback: @escaping (Any?, String?) -> Void) {
150
+ // If already determined, return immediately without showing the system dialog.
151
+ let probe = CLLocationManager()
152
+ let current = probe.authorizationStatus
153
+ if current != .notDetermined {
154
+ callback(statusString(current), nil)
155
+ return
156
+ }
157
+ pendingCallback = callback
158
+ let mgr = CLLocationManager()
159
+ mgr.delegate = self
160
+ manager = mgr
161
+ if always {
162
+ mgr.requestAlwaysAuthorization()
163
+ } else {
164
+ mgr.requestWhenInUseAuthorization()
165
+ }
166
+ }
167
+
168
+ private func statusString(_ status: CLAuthorizationStatus) -> String {
169
+ switch status {
170
+ case .authorizedWhenInUse, .authorizedAlways: return "granted"
171
+ case .denied: return "denied"
172
+ case .restricted: return "restricted"
173
+ case .notDetermined: return "notDetermined"
174
+ @unknown default: return "notDetermined"
175
+ }
176
+ }
177
+
178
+ // nonisolated because CLLocationManagerDelegate methods arrive on arbitrary threads;
179
+ // we hop back to @MainActor via Task for state access.
180
+ nonisolated func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
181
+ Task { @MainActor in
182
+ let status = manager.authorizationStatus
183
+ guard let cb = self.pendingCallback else { return }
184
+ self.pendingCallback = nil
185
+ self.manager = nil
186
+ cb(self.statusString(status), nil)
187
+ }
188
+ }
189
+ }
190
+ #endif
@@ -0,0 +1,118 @@
1
+ #if canImport(UIKit)
2
+ import Foundation
3
+ import Security
4
+
5
+ /// Native module providing secure key-value storage backed by iOS Keychain.
6
+ ///
7
+ /// Methods:
8
+ /// - get(key: String) -> String?
9
+ /// - set(key: String, value: String)
10
+ /// - remove(key: String)
11
+ /// - clear()
12
+ final class SecureStorageModule: NativeModule {
13
+ let moduleName = "SecureStorage"
14
+
15
+ private let service = "com.vuenative.securestorage"
16
+
17
+ func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
18
+ DispatchQueue.global(qos: .userInitiated).async { [weak self] in
19
+ guard let self = self else { return }
20
+ switch method {
21
+ case "get":
22
+ guard let key = args.first as? String else {
23
+ callback(nil, "get: missing key")
24
+ return
25
+ }
26
+ let query: [String: Any] = [
27
+ kSecClass as String: kSecClassGenericPassword,
28
+ kSecAttrService as String: self.service,
29
+ kSecAttrAccount as String: key,
30
+ kSecReturnData as String: true,
31
+ kSecMatchLimit as String: kSecMatchLimitOne,
32
+ ]
33
+ var result: AnyObject?
34
+ let status = SecItemCopyMatching(query as CFDictionary, &result)
35
+ if status == errSecSuccess, let data = result as? Data,
36
+ let value = String(data: data, encoding: .utf8) {
37
+ callback(value, nil)
38
+ } else if status == errSecItemNotFound {
39
+ callback(nil, nil)
40
+ } else {
41
+ callback(nil, "get: Keychain error \(status)")
42
+ }
43
+
44
+ case "set":
45
+ guard args.count >= 2,
46
+ let key = args[0] as? String,
47
+ let value = args[1] as? String else {
48
+ callback(nil, "set: missing key or value")
49
+ return
50
+ }
51
+ guard let data = value.data(using: .utf8) else {
52
+ callback(nil, "set: failed to encode value")
53
+ return
54
+ }
55
+
56
+ // Try to update first
57
+ let searchQuery: [String: Any] = [
58
+ kSecClass as String: kSecClassGenericPassword,
59
+ kSecAttrService as String: self.service,
60
+ kSecAttrAccount as String: key,
61
+ ]
62
+ let updateAttributes: [String: Any] = [
63
+ kSecValueData as String: data,
64
+ ]
65
+ let updateStatus = SecItemUpdate(searchQuery as CFDictionary, updateAttributes as CFDictionary)
66
+
67
+ if updateStatus == errSecItemNotFound {
68
+ // Item doesn't exist yet, add it
69
+ var addQuery = searchQuery
70
+ addQuery[kSecValueData as String] = data
71
+ let addStatus = SecItemAdd(addQuery as CFDictionary, nil)
72
+ if addStatus == errSecSuccess {
73
+ callback(nil, nil)
74
+ } else {
75
+ callback(nil, "set: Keychain add error \(addStatus)")
76
+ }
77
+ } else if updateStatus == errSecSuccess {
78
+ callback(nil, nil)
79
+ } else {
80
+ callback(nil, "set: Keychain update error \(updateStatus)")
81
+ }
82
+
83
+ case "remove":
84
+ guard let key = args.first as? String else {
85
+ callback(nil, "remove: missing key")
86
+ return
87
+ }
88
+ let query: [String: Any] = [
89
+ kSecClass as String: kSecClassGenericPassword,
90
+ kSecAttrService as String: self.service,
91
+ kSecAttrAccount as String: key,
92
+ ]
93
+ let status = SecItemDelete(query as CFDictionary)
94
+ if status == errSecSuccess || status == errSecItemNotFound {
95
+ callback(nil, nil)
96
+ } else {
97
+ callback(nil, "remove: Keychain error \(status)")
98
+ }
99
+
100
+ case "clear":
101
+ let query: [String: Any] = [
102
+ kSecClass as String: kSecClassGenericPassword,
103
+ kSecAttrService as String: self.service,
104
+ ]
105
+ let status = SecItemDelete(query as CFDictionary)
106
+ if status == errSecSuccess || status == errSecItemNotFound {
107
+ callback(nil, nil)
108
+ } else {
109
+ callback(nil, "clear: Keychain error \(status)")
110
+ }
111
+
112
+ default:
113
+ callback(nil, "SecureStorageModule: Unknown method '\(method)'")
114
+ }
115
+ }
116
+ }
117
+ }
118
+ #endif
@@ -0,0 +1,103 @@
1
+ #if canImport(UIKit)
2
+ import CoreMotion
3
+ import Foundation
4
+
5
+ /// Native module for accelerometer and gyroscope sensor data.
6
+ /// Dispatches continuous events via bridge.dispatchGlobalEvent.
7
+ final class SensorsModule: NativeModule {
8
+ let moduleName = "Sensors"
9
+
10
+ private let motionManager = CMMotionManager()
11
+ private weak var bridge: NativeBridge?
12
+ private let queue = OperationQueue()
13
+
14
+ init(bridge: NativeBridge) {
15
+ self.bridge = bridge
16
+ queue.name = "vue-native.sensors"
17
+ queue.maxConcurrentOperationCount = 1
18
+ }
19
+
20
+ func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
21
+ switch method {
22
+ case "startAccelerometer":
23
+ let interval = (args.first as? Double ?? 100) / 1000.0
24
+ startAccelerometer(interval: interval, callback: callback)
25
+ case "stopAccelerometer":
26
+ stopAccelerometer(callback: callback)
27
+ case "startGyroscope":
28
+ let interval = (args.first as? Double ?? 100) / 1000.0
29
+ startGyroscope(interval: interval, callback: callback)
30
+ case "stopGyroscope":
31
+ stopGyroscope(callback: callback)
32
+ case "isAvailable":
33
+ let sensorType = args.first as? String ?? "accelerometer"
34
+ let available: Bool
35
+ switch sensorType {
36
+ case "gyroscope":
37
+ available = motionManager.isGyroAvailable
38
+ default:
39
+ available = motionManager.isAccelerometerAvailable
40
+ }
41
+ callback(["available": available], nil)
42
+ default:
43
+ callback(nil, "SensorsModule: unknown method '\(method)'")
44
+ }
45
+ }
46
+
47
+ // MARK: - Accelerometer
48
+
49
+ private func startAccelerometer(interval: TimeInterval, callback: @escaping (Any?, String?) -> Void) {
50
+ guard motionManager.isAccelerometerAvailable else {
51
+ callback(nil, "Accelerometer not available on this device")
52
+ return
53
+ }
54
+ motionManager.accelerometerUpdateInterval = interval
55
+ motionManager.startAccelerometerUpdates(to: queue) { [weak self] data, error in
56
+ guard let data = data, let bridge = self?.bridge else { return }
57
+ if error != nil { return }
58
+ DispatchQueue.main.async {
59
+ bridge.dispatchGlobalEvent("sensor:accelerometer", payload: [
60
+ "x": data.acceleration.x,
61
+ "y": data.acceleration.y,
62
+ "z": data.acceleration.z,
63
+ "timestamp": data.timestamp,
64
+ ])
65
+ }
66
+ }
67
+ callback(nil, nil)
68
+ }
69
+
70
+ private func stopAccelerometer(callback: @escaping (Any?, String?) -> Void) {
71
+ motionManager.stopAccelerometerUpdates()
72
+ callback(nil, nil)
73
+ }
74
+
75
+ // MARK: - Gyroscope
76
+
77
+ private func startGyroscope(interval: TimeInterval, callback: @escaping (Any?, String?) -> Void) {
78
+ guard motionManager.isGyroAvailable else {
79
+ callback(nil, "Gyroscope not available on this device")
80
+ return
81
+ }
82
+ motionManager.gyroUpdateInterval = interval
83
+ motionManager.startGyroUpdates(to: queue) { [weak self] data, error in
84
+ guard let data = data, let bridge = self?.bridge else { return }
85
+ if error != nil { return }
86
+ DispatchQueue.main.async {
87
+ bridge.dispatchGlobalEvent("sensor:gyroscope", payload: [
88
+ "x": data.rotationRate.x,
89
+ "y": data.rotationRate.y,
90
+ "z": data.rotationRate.z,
91
+ "timestamp": data.timestamp,
92
+ ])
93
+ }
94
+ }
95
+ callback(nil, nil)
96
+ }
97
+
98
+ private func stopGyroscope(callback: @escaping (Any?, String?) -> Void) {
99
+ motionManager.stopGyroUpdates()
100
+ callback(nil, nil)
101
+ }
102
+ }
103
+ #endif
@@ -0,0 +1,49 @@
1
+ #if canImport(UIKit)
2
+ import UIKit
3
+
4
+ final class ShareModule: NativeModule {
5
+ var moduleName: String { "Share" }
6
+
7
+ func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
8
+ switch method {
9
+ case "share":
10
+ guard let content = args.first as? [String: Any] else {
11
+ callback(nil, "Invalid content")
12
+ return
13
+ }
14
+ var items: [Any] = []
15
+ if let message = content["message"] as? String { items.append(message) }
16
+ if let urlStr = content["url"] as? String, let u = URL(string: urlStr) { items.append(u) }
17
+ if items.isEmpty { callback(nil, "No shareable content"); return }
18
+
19
+ DispatchQueue.main.async {
20
+ let vc = UIActivityViewController(activityItems: items, applicationActivities: nil)
21
+ if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
22
+ let rootVC = windowScene.windows.first?.rootViewController {
23
+ // iPad popover support
24
+ if let popover = vc.popoverPresentationController {
25
+ popover.sourceView = rootVC.view
26
+ popover.sourceRect = CGRect(
27
+ x: rootVC.view.bounds.midX,
28
+ y: rootVC.view.bounds.midY,
29
+ width: 0,
30
+ height: 0
31
+ )
32
+ popover.permittedArrowDirections = []
33
+ }
34
+ rootVC.present(vc, animated: true)
35
+ vc.completionWithItemsHandler = { _, completed, _, _ in
36
+ callback(["shared": completed], nil)
37
+ }
38
+ } else {
39
+ callback(nil, "No root view controller")
40
+ }
41
+ }
42
+ default:
43
+ callback(nil, "Unknown method: \(method)")
44
+ }
45
+ }
46
+
47
+ func invokeSync(method: String, args: [Any]) -> Any? { nil }
48
+ }
49
+ #endif