react-native-rook-sdk 2.0.3 → 2.1.0-rc.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.
Files changed (88) hide show
  1. package/android/src/main/java/com/rooksdk/RookSdkPackage.kt +3 -1
  2. package/android/src/main/java/com/rooksdk/modules/RookLocalData.kt +247 -0
  3. package/android/src/main/java/com/rooksdk/modules/RookSyncModule.kt +17 -1
  4. package/android/src/main/java/com/rooksdk/utils/serializers/InstantSerializer.kt +19 -0
  5. package/android/src/main/java/com/rooksdk/utils/serializers/LocalDateSerializer.kt +21 -0
  6. package/ios/EncodableDataSource.swift +32 -0
  7. package/ios/EncodableDataSourceAuthorizer.swift +32 -0
  8. package/ios/EncodableRookDataSource.swift +36 -0
  9. package/ios/EncodableStatusDataSources.swift +47 -0
  10. package/ios/RookExternalModule.h +5 -0
  11. package/ios/RookExternalModule.m +27 -0
  12. package/ios/RookLocalData.swift +152 -0
  13. package/ios/RookSdk.mm +1 -0
  14. package/ios/RookSources.swift +148 -0
  15. package/ios/RookSourcesModule.mm +29 -98
  16. package/ios/RookSync.h +5 -0
  17. package/ios/RookSync.m +27 -0
  18. package/ios/RookSync.swift +135 -0
  19. package/ios/RookSyncModule.h +1 -1
  20. package/ios/RookSyncModule.mm +10 -5
  21. package/ios/SwiftTest.swift +18 -0
  22. package/ios/react-native-rook-sdk-Bridging-Header.h +12 -0
  23. package/lib/commonjs/hooks/index.js +7 -0
  24. package/lib/commonjs/hooks/index.js.map +1 -1
  25. package/lib/commonjs/hooks/useRookData.js +100 -0
  26. package/lib/commonjs/hooks/useRookData.js.map +1 -0
  27. package/lib/commonjs/hooks/useRookDataSources.js +17 -6
  28. package/lib/commonjs/hooks/useRookDataSources.js.map +1 -1
  29. package/lib/commonjs/hooks/useRookSync.js +1 -1
  30. package/lib/commonjs/hooks/useRookSync.js.map +1 -1
  31. package/lib/commonjs/types/ActivityEvent.js +6 -0
  32. package/lib/commonjs/types/ActivityEvent.js.map +1 -0
  33. package/lib/commonjs/types/BodySummary.js +6 -0
  34. package/lib/commonjs/types/BodySummary.js.map +1 -0
  35. package/lib/commonjs/types/PhysicalSummary.js +6 -0
  36. package/lib/commonjs/types/PhysicalSummary.js.map +1 -0
  37. package/lib/commonjs/types/SleepSummary.js +6 -0
  38. package/lib/commonjs/types/SleepSummary.js.map +1 -0
  39. package/lib/commonjs/types/SummaryTypes.js +2 -0
  40. package/lib/commonjs/types/SummaryTypes.js.map +1 -0
  41. package/lib/commonjs/utils/getNativeModule.js +1 -1
  42. package/lib/commonjs/utils/getNativeModule.js.map +1 -1
  43. package/lib/commonjs/utils/nativeModules.js +5 -2
  44. package/lib/commonjs/utils/nativeModules.js.map +1 -1
  45. package/lib/module/hooks/index.js +1 -0
  46. package/lib/module/hooks/index.js.map +1 -1
  47. package/lib/module/hooks/useRookData.js +92 -0
  48. package/lib/module/hooks/useRookData.js.map +1 -0
  49. package/lib/module/hooks/useRookDataSources.js +17 -6
  50. package/lib/module/hooks/useRookDataSources.js.map +1 -1
  51. package/lib/module/hooks/useRookSync.js +1 -1
  52. package/lib/module/hooks/useRookSync.js.map +1 -1
  53. package/lib/module/types/ActivityEvent.js +2 -0
  54. package/lib/module/types/ActivityEvent.js.map +1 -0
  55. package/lib/module/types/BodySummary.js +2 -0
  56. package/lib/module/types/BodySummary.js.map +1 -0
  57. package/lib/module/types/PhysicalSummary.js +2 -0
  58. package/lib/module/types/PhysicalSummary.js.map +1 -0
  59. package/lib/module/types/SleepSummary.js +2 -0
  60. package/lib/module/types/SleepSummary.js.map +1 -0
  61. package/lib/module/types/SummaryTypes.js +2 -0
  62. package/lib/module/types/SummaryTypes.js.map +1 -0
  63. package/lib/module/utils/getNativeModule.js +1 -1
  64. package/lib/module/utils/getNativeModule.js.map +1 -1
  65. package/lib/module/utils/nativeModules.js +5 -2
  66. package/lib/module/utils/nativeModules.js.map +1 -1
  67. package/lib/typescript/src/hooks/index.d.ts +1 -0
  68. package/lib/typescript/src/hooks/index.d.ts.map +1 -1
  69. package/lib/typescript/src/hooks/useRookData.d.ts +18 -0
  70. package/lib/typescript/src/hooks/useRookData.d.ts.map +1 -0
  71. package/lib/typescript/src/hooks/useRookDataSources.d.ts +2 -1
  72. package/lib/typescript/src/hooks/useRookDataSources.d.ts.map +1 -1
  73. package/lib/typescript/src/types/ActivityEvent.d.ts +137 -0
  74. package/lib/typescript/src/types/ActivityEvent.d.ts.map +1 -0
  75. package/lib/typescript/src/types/AuthorizedSources.d.ts +5 -0
  76. package/lib/typescript/src/types/AuthorizedSources.d.ts.map +1 -1
  77. package/lib/typescript/src/types/BodySummary.d.ts +99 -0
  78. package/lib/typescript/src/types/BodySummary.d.ts.map +1 -0
  79. package/lib/typescript/src/types/PhysicalSummary.d.ts +70 -0
  80. package/lib/typescript/src/types/PhysicalSummary.d.ts.map +1 -0
  81. package/lib/typescript/src/types/SleepSummary.d.ts +57 -0
  82. package/lib/typescript/src/types/SleepSummary.d.ts.map +1 -0
  83. package/lib/typescript/src/types/SummaryTypes.d.ts +59 -0
  84. package/lib/typescript/src/types/SummaryTypes.d.ts.map +1 -0
  85. package/lib/typescript/src/utils/nativeModules.d.ts +3 -0
  86. package/lib/typescript/src/utils/nativeModules.d.ts.map +1 -1
  87. package/package.json +22 -22
  88. package/react-native-rook-sdk.podspec +5 -3
@@ -8,6 +8,7 @@ import com.facebook.react.uimanager.ViewManager
8
8
  import com.rookmotion.rook.sdk.RookConfigurationManager
9
9
  import com.rooksdk.modules.RookBackgroundSyncModule
10
10
  import com.rooksdk.modules.RookConfigurationModule
11
+ import com.rooksdk.modules.RookLocalData
11
12
  import com.rooksdk.modules.RookPermissionsModule
12
13
  import com.rooksdk.modules.RookStepsModule
13
14
  import io.tryrook.sdk.samsung.RookSamsung
@@ -30,7 +31,8 @@ class RookSdkPackage : ReactPackage {
30
31
  RookConfigurationModule(reactContext, rookConfigurationManager!!, rookSamsung!!),
31
32
  RookSyncModule(reactContext, rookSamsung!!),
32
33
  RookBackgroundSyncModule(reactContext),
33
- RookStepsModule(reactContext)
34
+ RookStepsModule(reactContext),
35
+ RookLocalData(reactContext, rookSamsung!!)
34
36
  )
35
37
  }
36
38
 
@@ -0,0 +1,247 @@
1
+ package com.rooksdk.modules
2
+
3
+ import com.facebook.react.bridge.Promise
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
6
+ import com.facebook.react.bridge.ReactMethod
7
+ import com.google.gson.Gson
8
+ import com.google.gson.GsonBuilder
9
+ import com.rookmotion.rook.sdk.RookSyncManager
10
+ import com.rookmotion.rook.sdk.domain.model.HCActivityEvent
11
+ import com.rookmotion.rook.sdk.domain.model.HCBodySummary
12
+ import com.rookmotion.rook.sdk.domain.model.HCPhysicalSummary
13
+ import com.rookmotion.rook.sdk.domain.model.HCSleepSummary
14
+ import com.rookmotion.rook.sdk.domain.model.SyncStatusWithData
15
+ import com.rooksdk.utils.serializers.InstantSerializer
16
+ import com.rooksdk.utils.RookDateTime
17
+ import com.rooksdk.utils.serializers.LocalDateSerializer
18
+ import io.tryrook.sdk.samsung.RookSamsung
19
+ import io.tryrook.sdk.samsung.domain.model.SHActivityEvent
20
+ import io.tryrook.sdk.samsung.domain.model.SHBodySummary
21
+ import io.tryrook.sdk.samsung.domain.model.SHPhysicalSummary
22
+ import io.tryrook.sdk.samsung.domain.model.SHSleepSummary
23
+ import io.tryrook.sdk.samsung.domain.model.SHSyncStatusWithData
24
+ import kotlinx.coroutines.CoroutineScope
25
+ import kotlinx.coroutines.Dispatchers
26
+ import kotlinx.coroutines.SupervisorJob
27
+ import kotlinx.coroutines.launch
28
+ import java.time.Instant
29
+ import java.time.LocalDate
30
+
31
+ class RookLocalData (
32
+ reactContext: ReactApplicationContext,
33
+ private val rookSamsung: RookSamsung,
34
+ ): ReactContextBaseJavaModule(reactContext){
35
+
36
+ private val scope: CoroutineScope by lazy {
37
+ CoroutineScope(SupervisorJob() + Dispatchers.Main)
38
+ }
39
+
40
+ private val rookHealthConnect by lazy {
41
+ RookSyncManager(reactContext)
42
+ }
43
+
44
+ private val gsonBuilder: Gson by lazy {
45
+ GsonBuilder()
46
+ .registerTypeAdapter(Instant::class.java, InstantSerializer())
47
+ .registerTypeAdapter(LocalDate::class.java, LocalDateSerializer())
48
+ .create()
49
+ }
50
+
51
+ @ReactMethod
52
+ fun getSamsungSleepSummary(date: String, promise: Promise) {
53
+ val localDate = RookDateTime.stringToLocalDate(date)
54
+
55
+ scope.launch {
56
+ rookSamsung.getSleepSummary(localDate).fold(
57
+ {
58
+ when (it) {
59
+ SHSyncStatusWithData.RecordsNotFound -> {
60
+ promise.reject("SamsungSleepSummary", "Records Not Found For Date: $date")
61
+ }
62
+
63
+ is SHSyncStatusWithData.Synced<List<SHSleepSummary>> -> {
64
+ promise.resolve(gsonBuilder.toJson(it.data))
65
+ }
66
+ }
67
+ },
68
+ {
69
+ promise.reject(it)
70
+ },
71
+ )
72
+ }
73
+ }
74
+
75
+ @ReactMethod
76
+ fun getSamsungPhysicalSummary(date: String, promise: Promise) {
77
+ val localDate = RookDateTime.stringToLocalDate(date)
78
+
79
+ scope.launch {
80
+ rookSamsung.getPhysicalSummary(localDate).fold(
81
+ {
82
+ when (it) {
83
+ SHSyncStatusWithData.RecordsNotFound -> {
84
+ promise.reject("SamsungPhysicalSummary", "Records Not Found For Date: $date")
85
+ }
86
+
87
+ is SHSyncStatusWithData.Synced<SHPhysicalSummary> -> {
88
+ promise.resolve(gsonBuilder.toJson(it.data))
89
+ }
90
+ }
91
+ },
92
+ {
93
+ promise.reject(it)
94
+ },
95
+ )
96
+ }
97
+ }
98
+
99
+ @ReactMethod
100
+ fun getSamsungBodySummary(date: String, promise: Promise) {
101
+ val localDate = RookDateTime.stringToLocalDate(date)
102
+
103
+ scope.launch {
104
+ rookSamsung.getBodySummary(localDate).fold(
105
+ {
106
+ when (it) {
107
+ SHSyncStatusWithData.RecordsNotFound -> {
108
+ promise.reject("SamsungBodySummary", "Records Not Found For Date: $date")
109
+ }
110
+
111
+ is SHSyncStatusWithData.Synced<SHBodySummary> -> {
112
+ promise.resolve(gsonBuilder.toJson(it.data))
113
+ }
114
+ }
115
+ },
116
+ {
117
+ promise.reject(it)
118
+ },
119
+ )
120
+ }
121
+ }
122
+
123
+ @ReactMethod
124
+ fun getSamsungActivityEvents(date: String, promise: Promise) {
125
+ val localDate = RookDateTime.stringToLocalDate(date)
126
+
127
+ scope.launch {
128
+ rookSamsung.getActivityEvents(localDate).fold(
129
+ {
130
+ when (it) {
131
+ SHSyncStatusWithData.RecordsNotFound -> {
132
+ promise.reject("SamsungBodySummary", "Records Not Found For Date: $date")
133
+ }
134
+
135
+ is SHSyncStatusWithData.Synced<List<SHActivityEvent>> -> {
136
+ promise.resolve(gsonBuilder.toJson(it.data))
137
+ }
138
+ }
139
+ },
140
+ {
141
+ promise.reject(it)
142
+ },
143
+ )
144
+ }
145
+ }
146
+
147
+ // Health Connect
148
+ @ReactMethod
149
+ fun getHealthConnectSleepSummary(date: String, promise: Promise) {
150
+ val localDate = RookDateTime.stringToLocalDate(date)
151
+
152
+ scope.launch {
153
+ rookHealthConnect.getSleepSummary(localDate).fold(
154
+ {
155
+ when (it) {
156
+ SyncStatusWithData.RecordsNotFound -> {
157
+ promise.reject("HealthConnectSleepSummary", "Records Not Found For Date: $date")
158
+ }
159
+
160
+ is SyncStatusWithData.Synced<List<HCSleepSummary>> -> {
161
+ promise.resolve(gsonBuilder.toJson(it.data))
162
+ }
163
+ }
164
+ },
165
+ {
166
+ promise.reject(it)
167
+ },
168
+ )
169
+ }
170
+ }
171
+
172
+ @ReactMethod
173
+ fun getHealthConnectPhysicalSummary(date: String, promise: Promise) {
174
+ val localDate = RookDateTime.stringToLocalDate(date)
175
+
176
+ scope.launch {
177
+ rookHealthConnect.getPhysicalSummary(localDate).fold(
178
+ {
179
+ when (it) {
180
+ SyncStatusWithData.RecordsNotFound -> {
181
+ promise.reject("HealthConnectSleepSummary", "Records Not Found For Date: $date")
182
+ }
183
+
184
+ is SyncStatusWithData.Synced<HCPhysicalSummary> -> {
185
+ promise.resolve(gsonBuilder.toJson(it.data))
186
+ }
187
+ }
188
+ },
189
+ {
190
+ promise.reject(it)
191
+ },
192
+ )
193
+ }
194
+ }
195
+
196
+ @ReactMethod
197
+ fun getHealthConnectBodySummary(date: String, promise: Promise) {
198
+ val localDate = RookDateTime.stringToLocalDate(date)
199
+
200
+ scope.launch {
201
+ rookHealthConnect.getBodySummary(localDate).fold(
202
+ {
203
+ when (it) {
204
+ SyncStatusWithData.RecordsNotFound -> {
205
+ promise.reject("HealthConnectBodySummary", "Records Not Found For Date: $date")
206
+ }
207
+
208
+ is SyncStatusWithData.Synced<HCBodySummary> -> {
209
+ promise.resolve(gsonBuilder.toJson(it.data))
210
+ }
211
+ }
212
+ },
213
+ {
214
+ promise.reject(it)
215
+ },
216
+ )
217
+ }
218
+ }
219
+
220
+ @ReactMethod
221
+ fun getHealthConnectActivityEvents(date: String, promise: Promise) {
222
+ val localDate = RookDateTime.stringToLocalDate(date)
223
+
224
+ scope.launch {
225
+ rookHealthConnect.getActivityEvents(localDate).fold(
226
+ {
227
+ when (it) {
228
+ SyncStatusWithData.RecordsNotFound -> {
229
+ promise.reject("HealthConnectActivityEvents", "Records Not Found For Date: $date")
230
+ }
231
+
232
+ is SyncStatusWithData.Synced<List<HCActivityEvent>> -> {
233
+ promise.resolve(gsonBuilder.toJson(it.data))
234
+ }
235
+ }
236
+ },
237
+ {
238
+ promise.reject(it)
239
+ },
240
+ )
241
+ }
242
+ }
243
+
244
+ override fun getName(): String {
245
+ return "RookLocalData"
246
+ }
247
+ }
@@ -22,6 +22,7 @@ import kotlinx.coroutines.CoroutineScope
22
22
  import kotlinx.coroutines.Dispatchers
23
23
  import kotlinx.coroutines.SupervisorJob
24
24
  import kotlinx.coroutines.launch
25
+ import org.jetbrains.annotations.Debug
25
26
 
26
27
  class RookSyncModule(
27
28
  reactContext: ReactApplicationContext,
@@ -145,6 +146,7 @@ class RookSyncModule(
145
146
 
146
147
 
147
148
  /**
149
+ * @deprecated
148
150
  * Retrieves the available data sources that can be connected to the app.
149
151
  * This method fetches data sources such as Garmin, Fitbit, Oura, etc.,
150
152
  * that the user can authorize to sync their health data.
@@ -233,7 +235,21 @@ class RookSyncModule(
233
235
  }
234
236
  }
235
237
 
236
- @ReactMethod
238
+ @ReactMethod
239
+ fun getAuthorizedDataSourcesV2(promise: Promise) {
240
+ scope.launch {
241
+ rookDataSources.getAuthorizedDataSourcesV2().fold(
242
+ {
243
+ val gson = Gson()
244
+ promise.resolve(gson.toJson(it))
245
+ }, {
246
+ promise.reject(it)
247
+ }
248
+ )
249
+ }
250
+ }
251
+
252
+ @ReactMethod
237
253
  fun getDataSourceAuthorizer(options: ReadableMap, promise: Promise) {
238
254
 
239
255
  val source = options.getString("dataSource") ?: ""
@@ -0,0 +1,19 @@
1
+ package com.rooksdk.utils.serializers
2
+
3
+ import com.google.gson.JsonElement
4
+ import com.google.gson.JsonPrimitive
5
+ import com.google.gson.JsonSerializationContext
6
+ import com.google.gson.JsonSerializer
7
+ import java.time.Instant
8
+ import java.lang.reflect.Type
9
+
10
+ class InstantSerializer : JsonSerializer<Instant> {
11
+ override fun serialize(
12
+ src: Instant?,
13
+ typeOfSrc: Type?,
14
+ context: JsonSerializationContext?
15
+ ): JsonElement {
16
+ return JsonPrimitive(src?.toString())
17
+ }
18
+ }
19
+
@@ -0,0 +1,21 @@
1
+ package com.rooksdk.utils.serializers
2
+
3
+ import com.google.gson.JsonElement
4
+ import com.google.gson.JsonPrimitive
5
+ import com.google.gson.JsonSerializationContext
6
+ import com.google.gson.JsonSerializer
7
+ import java.lang.reflect.Type
8
+ import java.time.LocalDate
9
+ import java.time.format.DateTimeFormatter
10
+
11
+ class LocalDateSerializer : JsonSerializer<LocalDate> {
12
+ private val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
13
+
14
+ override fun serialize(
15
+ src: LocalDate?,
16
+ typeOfSrc: Type?,
17
+ context: JsonSerializationContext?
18
+ ): JsonElement {
19
+ return JsonPrimitive(src?.format(formatter))
20
+ }
21
+ }
@@ -0,0 +1,32 @@
1
+ //
2
+ // EncodableDataSource.swift
3
+ // react-native-rook-sdk
4
+ //
5
+ // Created by Javier Villanueva on 09/10/25.
6
+ //
7
+
8
+ import Foundation
9
+ import RookSDK
10
+
11
+ struct EncodableDataSource: Encodable {
12
+
13
+ private let dataSource: RookSDK.DataSourceStatus
14
+
15
+ init(_ dataSource: RookSDK.DataSourceStatus) {
16
+ self.dataSource = dataSource
17
+ }
18
+
19
+ private enum CodingKeys: String, CodingKey {
20
+ case source
21
+ case status
22
+ case imageURL
23
+ }
24
+
25
+ func encode(to encoder: Encoder) throws {
26
+ var container = encoder.container(keyedBy: CodingKeys.self)
27
+
28
+ try container.encode(dataSource.source, forKey: .source)
29
+ try container.encode(dataSource.status, forKey: .status)
30
+ try container.encode(dataSource.imageURL, forKey: .imageURL)
31
+ }
32
+ }
@@ -0,0 +1,32 @@
1
+ //
2
+ // EncodableDataSourceAuthorizer.swift
3
+ // react-native-rook-sdk
4
+ //
5
+ // Created by Javier Villanueva on 08/10/25.
6
+ //
7
+
8
+ import RookSDK
9
+ import Foundation
10
+
11
+ struct EncodableDataSourceAuthorizer: Encodable {
12
+
13
+ private let authorizer: RookSDK.DataSourceAuthorizer
14
+
15
+ init(_ authorizer: RookSDK.DataSourceAuthorizer) {
16
+ self.authorizer = authorizer
17
+ }
18
+
19
+ private enum CodingKeys: String, CodingKey {
20
+ case dataSource
21
+ case authorized
22
+ case authorizationURL
23
+ }
24
+
25
+ func encode(to encoder: Encoder) throws {
26
+ var container = encoder.container(keyedBy: CodingKeys.self)
27
+
28
+ try container.encode(authorizer.dataSource, forKey: .dataSource)
29
+ try container.encode(authorizer.authorized, forKey: .authorized)
30
+ try container.encode(authorizer.authorizationURL, forKey: .authorizationURL)
31
+ }
32
+ }
@@ -0,0 +1,36 @@
1
+ //
2
+ // EncodableRookDataSource.swift
3
+ // Pods
4
+ //
5
+ // Created by Javier Villanueva on 08/10/25.
6
+ //
7
+
8
+ import Foundation
9
+ import RookSDK
10
+
11
+ struct EncodableRookDataSource: Encodable {
12
+
13
+ private let dataSource: RookSDK.RookDataSource
14
+
15
+ init(_ dataSource: RookSDK.RookDataSource) {
16
+ self.dataSource = dataSource
17
+ }
18
+
19
+ private enum CodingKeys: String, CodingKey {
20
+ case name
21
+ case description
22
+ case imageUrl
23
+ case connected
24
+ case authorizationURL
25
+ }
26
+
27
+ func encode(to encoder: Encoder) throws {
28
+ var container = encoder.container(keyedBy: CodingKeys.self)
29
+
30
+ try container.encode(dataSource.name, forKey: .name)
31
+ try container.encode(dataSource.description, forKey: .description)
32
+ try container.encode(dataSource.imageUrl, forKey: .imageUrl)
33
+ try container.encode(dataSource.connected, forKey: .connected)
34
+ try container.encode(dataSource.authorizationURL, forKey: .authorizationURL)
35
+ }
36
+ }
@@ -0,0 +1,47 @@
1
+ //
2
+ // EncodableStatusDataSources.swift
3
+ // react-native-rook-sdk
4
+ //
5
+ // Created by Javier Villanueva on 08/10/25.
6
+ //
7
+
8
+ import Foundation
9
+ import RookSDK
10
+
11
+ struct EncodableStatusDataSources: Encodable {
12
+ private let status: RookSDK.StatusDataSources
13
+
14
+ init(_ status: RookSDK.StatusDataSources) {
15
+ self.status = status
16
+ }
17
+
18
+ private enum CodingKeys: String, CodingKey {
19
+ case oura
20
+ case polar
21
+ case whoop
22
+ case fitbit
23
+ case garmin
24
+ case withings
25
+ case googleFit
26
+ case appleHealth
27
+ case healthConnect
28
+ case android
29
+ case dexcom
30
+ }
31
+
32
+ func encode(to encoder: Encoder) throws {
33
+ var container = encoder.container(keyedBy: CodingKeys.self)
34
+
35
+ try container.encode(status.oura, forKey: .oura)
36
+ try container.encode(status.polar, forKey: .polar)
37
+ try container.encode(status.whoop, forKey: .whoop)
38
+ try container.encode(status.fitbit, forKey: .fitbit)
39
+ try container.encode(status.garmin, forKey: .garmin)
40
+ try container.encode(status.withings, forKey: .withings)
41
+ try container.encode(status.googleFit, forKey: .googleFit)
42
+ try container.encode(status.appleHealth, forKey: .appleHealth)
43
+ try container.encode(status.healthConnect, forKey: .healthConnect)
44
+ try container.encode(status.android, forKey: .android)
45
+ try container.encode(status.dexcom, forKey: .dexcom)
46
+ }
47
+ }
@@ -0,0 +1,5 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface RookExternalModule: NSObject<RCTBridgeModule>
4
+
5
+ @end
@@ -0,0 +1,27 @@
1
+ //
2
+ // RookExternalModule.m
3
+ // react-native-rook-sdk
4
+ //
5
+ // Created by Javier Villanueva on 10/09/25.
6
+ //
7
+ #import <Foundation/Foundation.h>
8
+ #import <React/RCTBridgeModule.h>
9
+
10
+ @interface RCT_EXTERN_MODULE(RookLocalData, NSObject)
11
+
12
+ RCT_EXTERN_METHOD(getAppleHealthSleepSummary: (NSString *) date
13
+ resolve:(RCTPromiseResolveBlock)resolve
14
+ reject:(RCTPromiseRejectBlock)reject)
15
+
16
+ RCT_EXTERN_METHOD(getAppleHealthPhysicalSummary: (NSString *) date
17
+ resolve:(RCTPromiseResolveBlock)resolve
18
+ reject:(RCTPromiseRejectBlock)reject)
19
+
20
+ RCT_EXTERN_METHOD(getAppleHealthBodySummary: (NSString *) date
21
+ resolve:(RCTPromiseResolveBlock)resolve
22
+ reject:(RCTPromiseRejectBlock)reject)
23
+
24
+ RCT_EXTERN_METHOD(getAppleHealthActivityEvents: (NSString *) date
25
+ resolve:(RCTPromiseResolveBlock)resolve
26
+ reject:(RCTPromiseRejectBlock)reject)
27
+ @end
@@ -0,0 +1,152 @@
1
+ //
2
+ // RookLocalData.swift
3
+ // react-native-rook-sdk
4
+ //
5
+ // Created by Javier Villanueva on 10/09/25.
6
+ //
7
+
8
+ import RookSDK
9
+
10
+ @objc(RookLocalData)
11
+ public class RookLocalData: NSObject {
12
+
13
+ lazy var summaryManager: RookSummaryManager = {
14
+ return RookSummaryManager()
15
+ }()
16
+
17
+ lazy var eventManager: RookEventsManager = {
18
+ return RookEventsManager()
19
+ }()
20
+
21
+ func parseStringToDate(_ input: String) -> Date? {
22
+ let dateFormatter = DateFormatter()
23
+ dateFormatter.dateFormat = "yyyy-MM-dd"
24
+ return dateFormatter.date(from: input)
25
+ }
26
+
27
+ @objc(getAppleHealthSleepSummary:resolve:reject:)
28
+ public func getAppleHealthSleepSummary(
29
+ _ date: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock
30
+ ) {
31
+ Task {
32
+ do {
33
+ guard let parsed = parseStringToDate(date) else {
34
+ reject("AppleHealthGetSleepSummaryError", "Invalid date format", nil)
35
+ return
36
+ }
37
+
38
+ let sleepSummaries = try await summaryManager.getSleepSummary(date: parsed)
39
+ let dic = sleepSummaries.map { $0.toDictionary() }
40
+
41
+ DispatchQueue.main.async {
42
+ resolve(dic)
43
+ }
44
+ } catch {
45
+
46
+ DispatchQueue.main.async {
47
+ reject("AppleHealthGetSleepSummaryError", error.localizedDescription, error as NSError)
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ @objc(getAppleHealthPhysicalSummary:resolve:reject:)
54
+ public func getAppleHealthPhysicalSummary(
55
+ _ date: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock
56
+ ) {
57
+ Task {
58
+ do {
59
+ guard let parsed = parseStringToDate(date) else {
60
+ reject("AppleHealthGetPhysicalSummaryError", "Invalid date format", nil)
61
+ return
62
+ }
63
+
64
+ let physicalSummaries = try await summaryManager.getPhysicalSummary(date: parsed)
65
+ let dic = physicalSummaries.toDictionary()
66
+
67
+ DispatchQueue.main.async {
68
+ resolve(dic)
69
+ }
70
+
71
+ } catch {
72
+
73
+ DispatchQueue.main.async {
74
+ reject("AppleHealthGetBodySummaryError", error.localizedDescription, error as NSError)
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ @objc(getAppleHealthBodySummary:resolve:reject:)
81
+ public func getAppleHealthBodySummary(
82
+ _ date: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock
83
+ ) {
84
+ Task {
85
+ do {
86
+ guard let parsed = parseStringToDate(date) else {
87
+ reject("AppleHealthGetBodySummaryError", "Invalid date format", nil)
88
+ return
89
+ }
90
+ let bodySummaries = try await summaryManager.getBodySummary(date: parsed)
91
+ let dic = bodySummaries.toDictionary()
92
+
93
+ DispatchQueue.main.async {
94
+ resolve(dic)
95
+ }
96
+
97
+ } catch {
98
+
99
+ DispatchQueue.main.async {
100
+ reject("AppleHealthGetBodySummaryError", error.localizedDescription, error as NSError)
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
+ @objc(getAppleHealthActivityEvents:resolve:reject:)
107
+ public func getAppleHealthActivityEvents(
108
+ _ date: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock
109
+ ) {
110
+ Task {
111
+ do {
112
+ guard let parsed = parseStringToDate(date) else {
113
+ reject("AppleHealthGetActivityEventsError", "Invalid date format", nil)
114
+ return
115
+ }
116
+
117
+ let activityEvents = try await eventManager.getActivityEvents(date: parsed)
118
+ let dic = activityEvents.map { $0.toDictionary() }
119
+
120
+ DispatchQueue.main.async {
121
+ resolve(dic)
122
+ }
123
+
124
+ } catch {
125
+
126
+ DispatchQueue.main.async {
127
+ reject("AppleHealthGetActivityEvents", error.localizedDescription, error as NSError)
128
+ }
129
+ }
130
+ }
131
+ }
132
+
133
+ }
134
+
135
+ extension Encodable {
136
+ func toDictionary() -> [String: Any] {
137
+ let encoder = JSONEncoder()
138
+
139
+ let dateFormatter = DateFormatter()
140
+ dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
141
+
142
+ encoder.dateEncodingStrategy = .formatted(dateFormatter)
143
+
144
+ guard let data = try? encoder.encode(self),
145
+ let dictionary = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]
146
+ else {
147
+ return [:]
148
+ }
149
+
150
+ return dictionary
151
+ }
152
+ }
package/ios/RookSdk.mm CHANGED
@@ -1,4 +1,5 @@
1
1
  #import "RookSdk.h"
2
+ #import <React/RCTLog.h>
2
3
  #import "RookSDK/RookSDK-Swift.h"
3
4
  #import "RCTConvert.h"
4
5