@amplitude/analytics-react-native 1.3.3 → 1.3.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 (29) hide show
  1. package/android/src/main/java/com/amplitude/reactnative/AmplitudeReactNativeModule.kt +101 -0
  2. package/android/src/main/java/com/amplitude/reactnative/LegacyDatabaseStorage.kt +313 -0
  3. package/ios/AmplitudeReactNative.m +3 -0
  4. package/ios/AmplitudeReactNative.swift +74 -0
  5. package/ios/AmplitudeReactNative.xcodeproj/project.pbxproj +9 -17
  6. package/ios/LegacyDatabaseStorage.swift +224 -0
  7. package/lib/commonjs/config.js +19 -7
  8. package/lib/commonjs/config.js.map +1 -1
  9. package/lib/commonjs/migration/remnant-data-migration.js +170 -0
  10. package/lib/commonjs/migration/remnant-data-migration.js.map +1 -0
  11. package/lib/commonjs/react-native-client.js +2 -2
  12. package/lib/commonjs/react-native-client.js.map +1 -1
  13. package/lib/commonjs/version.js +1 -1
  14. package/lib/module/config.js +18 -7
  15. package/lib/module/config.js.map +1 -1
  16. package/lib/module/migration/remnant-data-migration.js +163 -0
  17. package/lib/module/migration/remnant-data-migration.js.map +1 -0
  18. package/lib/module/react-native-client.js +2 -2
  19. package/lib/module/react-native-client.js.map +1 -1
  20. package/lib/module/version.js +1 -1
  21. package/lib/typescript/config.d.ts.map +1 -1
  22. package/lib/typescript/migration/remnant-data-migration.d.ts +20 -0
  23. package/lib/typescript/migration/remnant-data-migration.d.ts.map +1 -0
  24. package/lib/typescript/version.d.ts +1 -1
  25. package/package.json +5 -5
  26. package/src/config.ts +26 -7
  27. package/src/migration/remnant-data-migration.ts +168 -0
  28. package/src/react-native-client.ts +2 -2
  29. package/src/version.ts +1 -1
@@ -6,12 +6,20 @@ import com.facebook.react.bridge.ReactApplicationContext
6
6
  import com.facebook.react.bridge.ReactContextBaseJavaModule
7
7
  import com.facebook.react.bridge.ReactMethod
8
8
  import com.facebook.react.bridge.ReadableMap
9
+ import com.facebook.react.bridge.WritableNativeArray
9
10
  import com.facebook.react.bridge.WritableNativeMap
10
11
 
11
12
  const val MODULE_NAME = "AmplitudeReactNative"
12
13
 
13
14
  @ReactModule(name = MODULE_NAME)
14
15
  class AmplitudeReactNativeModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
16
+ companion object {
17
+ const val DEVICE_ID_KEY = "device_id"
18
+ const val USER_ID_KEY = "user_id"
19
+ const val LAST_EVENT_TIME_KEY = "last_event_time"
20
+ const val LAST_EVENT_ID_KEY = "last_event_id"
21
+ const val PREVIOUS_SESSION_ID_KEY = "previous_session_id"
22
+ }
15
23
 
16
24
  private var androidContextProvider: AndroidContextProvider? = null
17
25
 
@@ -42,4 +50,97 @@ class AmplitudeReactNativeModule(private val reactContext: ReactApplicationConte
42
50
  putString("appSetId", androidContextProvider!!.appSetId)
43
51
  })
44
52
  }
53
+
54
+ @ReactMethod
55
+ private fun getLegacySessionData(instanceName: String?, promise: Promise) {
56
+ try {
57
+ val storage = LegacyDatabaseStorageProvider.getStorage(reactContext.applicationContext, instanceName)
58
+ val deviceId = getLegacyValue(storage, DEVICE_ID_KEY)
59
+ val userId = getLegacyValue(storage, USER_ID_KEY)
60
+ val previousSessionId = getLegacyLongValue(storage, PREVIOUS_SESSION_ID_KEY)
61
+ val lastEventTime = getLegacyLongValue(storage, LAST_EVENT_TIME_KEY)
62
+ val lastEventId = getLegacyLongValue(storage, LAST_EVENT_ID_KEY)
63
+ promise.resolve(WritableNativeMap().apply {
64
+ if (deviceId != null) {
65
+ putString("deviceId", deviceId)
66
+ }
67
+ if (userId != null) {
68
+ putString("userId", userId)
69
+ }
70
+ if (previousSessionId != null) {
71
+ putDouble("sessionId", previousSessionId.toDouble())
72
+ }
73
+ if (lastEventTime != null) {
74
+ putDouble("lastEventTime", lastEventTime.toDouble())
75
+ }
76
+ if (lastEventId != null) {
77
+ putDouble("lastEventId", lastEventId.toDouble())
78
+ }
79
+ })
80
+ } catch (e: Exception) {
81
+ LogcatLogger.logger.error(
82
+ "can't get legacy session data: $e"
83
+ )
84
+ }
85
+ }
86
+
87
+ private fun getLegacyValue(storage: LegacyDatabaseStorage, key: String): String? {
88
+ try {
89
+ return storage.getValue(key)
90
+ } catch (e: Exception) {
91
+ LogcatLogger.logger.error(
92
+ "can't get legacy $key: $e"
93
+ )
94
+ return null
95
+ }
96
+ }
97
+
98
+ private fun getLegacyLongValue(storage: LegacyDatabaseStorage, key: String): Long? {
99
+ try {
100
+ return storage.getLongValue(key)
101
+ } catch (e: Exception) {
102
+ LogcatLogger.logger.error(
103
+ "can't get legacy $key: $e"
104
+ )
105
+ return null
106
+ }
107
+ }
108
+
109
+ @ReactMethod
110
+ private fun getLegacyEvents(instanceName: String?, eventKind: String, promise: Promise) {
111
+ try {
112
+ val storage = LegacyDatabaseStorageProvider.getStorage(reactContext.applicationContext, instanceName)
113
+ val jsonEvents = when (eventKind) {
114
+ "event" -> storage.readEvents()
115
+ "identify" -> storage.readIdentifies()
116
+ "interceptedIdentify" -> storage.readInterceptedIdentifies()
117
+ else -> listOf()
118
+ }
119
+
120
+ val events = WritableNativeArray()
121
+ jsonEvents.forEach { event -> events.pushString(event.toString()) }
122
+ promise.resolve(events)
123
+ } catch (e: Exception) {
124
+ LogcatLogger.logger.error(
125
+ "can't get legacy ${eventKind}s: $e"
126
+ )
127
+ promise.resolve(WritableNativeArray())
128
+ }
129
+ }
130
+
131
+ @ReactMethod
132
+ private fun removeLegacyEvent(instanceName: String?, eventKind: String, eventId: Int) {
133
+ try {
134
+ val storage = LegacyDatabaseStorageProvider.getStorage(reactContext.applicationContext, instanceName)
135
+ when (eventKind) {
136
+ "event" -> storage.removeEvent(eventId)
137
+ "identify" -> storage.removeIdentify(eventId)
138
+ "interceptedIdentify" -> storage.removeInterceptedIdentify(eventId)
139
+ }
140
+ } catch (e: Exception) {
141
+ LogcatLogger.logger.error(
142
+ "can't remove legacy $eventKind with id=$eventId: $e"
143
+ )
144
+ }
145
+ }
45
146
  }
@@ -0,0 +1,313 @@
1
+ package com.amplitude.reactnative
2
+
3
+ import android.content.Context
4
+ import android.database.Cursor
5
+ import android.database.sqlite.SQLiteDatabase
6
+ import android.database.sqlite.SQLiteException
7
+ import android.database.sqlite.SQLiteOpenHelper
8
+ import org.json.JSONObject
9
+ import java.io.File
10
+ import java.util.LinkedList
11
+ import java.util.Locale
12
+
13
+ /**
14
+ * Store the database related constants.
15
+ * Align with com/amplitude/api/DatabaseHelper.java in previous SDK.
16
+ */
17
+ object DatabaseConstants {
18
+ const val DEFAULT_INSTANCE = "\$default_instance"
19
+ const val DATABASE_NAME = "com.amplitude.api"
20
+ const val DATABASE_VERSION = 4
21
+
22
+ const val EVENT_TABLE_NAME = "events"
23
+ const val IDENTIFY_TABLE_NAME = "identifys"
24
+ const val IDENTIFY_INTERCEPTOR_TABLE_NAME = "identify_interceptor"
25
+ const val ID_FIELD = "id"
26
+ const val EVENT_FIELD = "event"
27
+
28
+ const val LONG_STORE_TABLE_NAME = "long_store"
29
+ const val STORE_TABLE_NAME = "store"
30
+ const val KEY_FIELD = "key"
31
+ const val VALUE_FIELD = "value"
32
+ }
33
+
34
+ /**
35
+ * The SDK doesn't need to write/read from local sqlite database.
36
+ * This storage class is used for migrating events only.
37
+ */
38
+ class LegacyDatabaseStorage(context: Context, databaseName: String) : SQLiteOpenHelper(
39
+ context,
40
+ databaseName,
41
+ null,
42
+ DatabaseConstants.DATABASE_VERSION
43
+ ) {
44
+ private var file: File = context.getDatabasePath(databaseName)
45
+ var currentDbVersion: Int = DatabaseConstants.DATABASE_VERSION
46
+ private set
47
+
48
+ override fun onCreate(db: SQLiteDatabase) {
49
+ throw NotImplementedError()
50
+ }
51
+
52
+ override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
53
+ currentDbVersion = oldVersion
54
+ }
55
+
56
+ private fun queryDb(
57
+ db: SQLiteDatabase,
58
+ table: String?,
59
+ columns: Array<String?>?,
60
+ selection: String?,
61
+ selectionArgs: Array<String?>?,
62
+ orderBy: String?,
63
+ ): Cursor? {
64
+ return db.query(table, columns, selection, selectionArgs, null, null, orderBy, null)
65
+ }
66
+
67
+ private fun handleIfCursorRowTooLargeException(e: java.lang.IllegalStateException) {
68
+ val message = e.message
69
+ if (!message.isNullOrEmpty() && message.contains("Couldn't read") && message.contains("CursorWindow")) {
70
+ closeDb()
71
+ } else {
72
+ throw e
73
+ }
74
+ }
75
+
76
+ private fun convertIfCursorWindowException(e: java.lang.RuntimeException) {
77
+ val message = e.message
78
+ if (!message.isNullOrEmpty() && (message.startsWith("Cursor window allocation of") || message.startsWith("Could not allocate CursorWindow"))) {
79
+ throw CursorWindowAllocationException(message)
80
+ } else {
81
+ throw e
82
+ }
83
+ }
84
+
85
+ private fun closeDb() {
86
+ try {
87
+ close()
88
+ } catch (e: Exception) {
89
+ LogcatLogger.logger.error("close failed: ${e.message}")
90
+ }
91
+ }
92
+
93
+ @Synchronized
94
+ fun readEvents(): List<JSONObject> {
95
+ return readEventsFromTable(DatabaseConstants.EVENT_TABLE_NAME)
96
+ }
97
+
98
+ @Synchronized
99
+ fun readIdentifies(): List<JSONObject> {
100
+ return readEventsFromTable(DatabaseConstants.IDENTIFY_TABLE_NAME)
101
+ }
102
+
103
+ @Synchronized
104
+ fun readInterceptedIdentifies(): List<JSONObject> {
105
+ if (currentDbVersion < 4) {
106
+ return listOf()
107
+ }
108
+ return readEventsFromTable(DatabaseConstants.IDENTIFY_INTERCEPTOR_TABLE_NAME)
109
+ }
110
+
111
+ private fun readEventsFromTable(table: String): List<JSONObject> {
112
+ if (!file.exists()) {
113
+ return arrayListOf()
114
+ }
115
+
116
+ val events: MutableList<JSONObject> = LinkedList()
117
+ var cursor: Cursor? = null
118
+ try {
119
+ val db = readableDatabase
120
+ cursor = queryDb(
121
+ db,
122
+ table,
123
+ arrayOf(DatabaseConstants.ID_FIELD, DatabaseConstants.EVENT_FIELD),
124
+ null,
125
+ null,
126
+ DatabaseConstants.ID_FIELD + " ASC",
127
+ )
128
+ while (cursor!!.moveToNext()) {
129
+ val eventId = cursor.getLong(0)
130
+ val event = cursor.getString(1)
131
+ if (event.isNullOrEmpty()) {
132
+ continue
133
+ }
134
+ val obj = JSONObject(event)
135
+ obj.put("event_id", eventId)
136
+ events.add(obj)
137
+ }
138
+ } catch (e: SQLiteException) {
139
+ LogcatLogger.logger.error(
140
+ "read events from $table failed: ${e.message}"
141
+ )
142
+ closeDb()
143
+ } catch (e: StackOverflowError) {
144
+ LogcatLogger.logger.error(
145
+ "read events from $table failed: ${e.message}"
146
+ )
147
+ closeDb()
148
+ } catch (e: IllegalStateException) { // put before Runtime since IllegalState extends
149
+ handleIfCursorRowTooLargeException(e)
150
+ } catch (e: RuntimeException) {
151
+ convertIfCursorWindowException(e)
152
+ } finally {
153
+ cursor?.close()
154
+ close()
155
+ }
156
+ return events
157
+ }
158
+
159
+ @Synchronized
160
+ fun removeEvent(eventId: Int) {
161
+ removeEventFromTable(DatabaseConstants.EVENT_TABLE_NAME, eventId)
162
+ }
163
+
164
+ @Synchronized
165
+ fun removeIdentify(eventId: Int) {
166
+ removeEventFromTable(DatabaseConstants.IDENTIFY_TABLE_NAME, eventId)
167
+ }
168
+
169
+ @Synchronized
170
+ fun removeInterceptedIdentify(eventId: Int) {
171
+ if (currentDbVersion < 4) {
172
+ return
173
+ }
174
+ removeEventFromTable(DatabaseConstants.IDENTIFY_INTERCEPTOR_TABLE_NAME, eventId)
175
+ }
176
+
177
+ private fun removeEventFromTable(table: String, eventId: Int) {
178
+ try {
179
+ val db = writableDatabase
180
+ db.delete(
181
+ table,
182
+ "${DatabaseConstants.ID_FIELD} = ?",
183
+ arrayOf(eventId.toString())
184
+ )
185
+ } catch (e: SQLiteException) {
186
+ LogcatLogger.logger.error(
187
+ "remove events from $table failed: ${e.message}"
188
+ )
189
+ closeDb()
190
+ } catch (e: StackOverflowError) {
191
+ LogcatLogger.logger.error(
192
+ "remove events from $table failed: ${e.message}"
193
+ )
194
+ closeDb()
195
+ } finally {
196
+ close()
197
+ }
198
+ }
199
+
200
+ @Synchronized
201
+ fun getValue(key: String): String? {
202
+ return getValueFromTable(DatabaseConstants.STORE_TABLE_NAME, key) as String?
203
+ }
204
+
205
+ @Synchronized
206
+ fun getLongValue(key: String): Long? {
207
+ return getValueFromTable(DatabaseConstants.LONG_STORE_TABLE_NAME, key) as Long?
208
+ }
209
+
210
+ private fun getValueFromTable(table: String, key: String): Any? {
211
+ if (!file.exists()) {
212
+ return null
213
+ }
214
+
215
+ var value: Any? = null
216
+ var cursor: Cursor? = null
217
+ try {
218
+ val db = readableDatabase
219
+ cursor = queryDb(
220
+ db,
221
+ table,
222
+ arrayOf<String?>(
223
+ DatabaseConstants.KEY_FIELD,
224
+ DatabaseConstants.VALUE_FIELD
225
+ ),
226
+ DatabaseConstants.KEY_FIELD + " = ?",
227
+ arrayOf(key),
228
+ null,
229
+ )
230
+ if (cursor!!.moveToFirst()) {
231
+ value = if (table == DatabaseConstants.STORE_TABLE_NAME) cursor.getString(1) else cursor.getLong(1)
232
+ }
233
+ } catch (e: SQLiteException) {
234
+ LogcatLogger.logger.error(
235
+ "getValue from $table failed: ${e.message}"
236
+ )
237
+ // Hard to recover from SQLiteExceptions, just start fresh
238
+ closeDb()
239
+ } catch (e: StackOverflowError) {
240
+ LogcatLogger.logger.error(
241
+ "getValue from $table failed: ${e.message}"
242
+ )
243
+ // potential stack overflow error when getting database on custom Android versions
244
+ closeDb()
245
+ } catch (e: IllegalStateException) { // put before Runtime since IllegalState extends
246
+ // cursor window row too big exception
247
+ handleIfCursorRowTooLargeException(e)
248
+ } catch (e: RuntimeException) {
249
+ // cursor window allocation exception
250
+ convertIfCursorWindowException(e)
251
+ } finally {
252
+ cursor?.close()
253
+ close()
254
+ }
255
+ return value
256
+ }
257
+
258
+ @Synchronized
259
+ fun removeValue(key: String) {
260
+ removeValueFromTable(DatabaseConstants.STORE_TABLE_NAME, key)
261
+ }
262
+
263
+ @Synchronized
264
+ fun removeLongValue(key: String) {
265
+ removeValueFromTable(DatabaseConstants.LONG_STORE_TABLE_NAME, key)
266
+ }
267
+
268
+ private fun removeValueFromTable(table: String, key: String) {
269
+ try {
270
+ val db = writableDatabase
271
+ db.delete(
272
+ table,
273
+ "${DatabaseConstants.KEY_FIELD} = ?",
274
+ arrayOf(key)
275
+ )
276
+ } catch (e: SQLiteException) {
277
+ LogcatLogger.logger.error(
278
+ "remove value from $table failed: ${e.message}"
279
+ )
280
+ closeDb()
281
+ } catch (e: StackOverflowError) {
282
+ LogcatLogger.logger.error(
283
+ "remove value from $table failed: ${e.message}"
284
+ )
285
+ closeDb()
286
+ } finally {
287
+ close()
288
+ }
289
+ }
290
+ }
291
+
292
+ class CursorWindowAllocationException(description: String?) :
293
+ java.lang.RuntimeException(description)
294
+
295
+ object LegacyDatabaseStorageProvider {
296
+ private val instances: MutableMap<String, LegacyDatabaseStorage> = mutableMapOf()
297
+
298
+ fun getStorage(context: Context, instanceName: String?): LegacyDatabaseStorage {
299
+ val databaseName = getDatabaseName(instanceName)
300
+ var storage = instances[databaseName]
301
+ if (storage == null) {
302
+ storage = LegacyDatabaseStorage(context, databaseName)
303
+ instances[databaseName] = storage
304
+ }
305
+
306
+ return storage
307
+ }
308
+
309
+ private fun getDatabaseName(instanceName: String?): String {
310
+ val normalizedInstanceName = instanceName?.lowercase(Locale.getDefault())
311
+ return if (normalizedInstanceName.isNullOrEmpty() || normalizedInstanceName == DatabaseConstants.DEFAULT_INSTANCE) DatabaseConstants.DATABASE_NAME else "${DatabaseConstants.DATABASE_NAME}_$normalizedInstanceName"
312
+ }
313
+ }
@@ -3,5 +3,8 @@
3
3
  @interface RCT_EXTERN_MODULE(AmplitudeReactNative, NSObject)
4
4
 
5
5
  RCT_EXTERN_METHOD(getApplicationContext: (NSDictionary*)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
6
+ RCT_EXTERN_METHOD(getLegacySessionData: (NSString*)instanceName resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
7
+ RCT_EXTERN_METHOD(getLegacyEvents: (NSString*)instanceName eventKind:(NSString*)eventKind resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
8
+ RCT_EXTERN_METHOD(removeLegacyEvent: (NSString*)instanceName eventKind:(NSString*)eventKind eventId:(double)eventId)
6
9
 
7
10
  @end
@@ -33,4 +33,78 @@ class ReactNative: NSObject {
33
33
  }
34
34
  resolve(applicationContext)
35
35
  }
36
+
37
+ @objc
38
+ func getLegacySessionData(
39
+ _ instanceName: String?,
40
+ resolver resolve: RCTPromiseResolveBlock,
41
+ rejecter reject: RCTPromiseRejectBlock
42
+ ) -> Void {
43
+ let storage = LegacyDatabaseStorage.getStorage(instanceName)
44
+ var sessionData: [String: Any?] = [:]
45
+
46
+ if let deviceId = storage.getValue("device_id") {
47
+ sessionData["deviceId"] = deviceId
48
+ }
49
+ if let userId = storage.getValue("user_id") {
50
+ sessionData["userId"] = userId
51
+ }
52
+ if let previousSessionId = storage.getLongValue("previous_session_id") {
53
+ sessionData["sessionId"] = previousSessionId
54
+ }
55
+ if let lastEventTime = storage.getLongValue("previous_session_time") {
56
+ sessionData["lastEventTime"] = lastEventTime
57
+ }
58
+ if let lastEventId = storage.getLastEventId() {
59
+ sessionData["lastEventId"] = lastEventId
60
+ }
61
+ resolve(sessionData)
62
+ }
63
+
64
+ @objc
65
+ func getLegacyEvents(
66
+ _ instanceName: String?,
67
+ eventKind: String,
68
+ resolver resolve: RCTPromiseResolveBlock,
69
+ rejecter reject: RCTPromiseRejectBlock
70
+ ) -> Void {
71
+ let storage = LegacyDatabaseStorage.getStorage(instanceName)
72
+ var events: [[String: Any]] = []
73
+ switch eventKind {
74
+ case "event":
75
+ events = storage.readEvents()
76
+ case "identify":
77
+ events = storage.readIdentifies()
78
+ case "interceptedIdentify":
79
+ events = storage.readInterceptedIdentifies()
80
+ default:
81
+ break
82
+ }
83
+ var jsonEvents: [String] = []
84
+ events.forEach { event in
85
+ if let jsonEvent = try? JSONSerialization.data(withJSONObject: event) {
86
+ jsonEvents.append(String(decoding: jsonEvent, as: UTF8.self))
87
+ }
88
+ }
89
+ resolve(jsonEvents)
90
+ }
91
+
92
+ @objc
93
+ func removeLegacyEvent(
94
+ _ instanceName: String?,
95
+ eventKind: String,
96
+ eventId: Double
97
+ ) -> Void {
98
+ let storage = LegacyDatabaseStorage.getStorage(instanceName)
99
+ switch eventKind {
100
+ case "event":
101
+ storage.removeEvent(Int64(eventId))
102
+ case "identify":
103
+ storage.removeIdentify(Int64(eventId))
104
+ case "interceptedIdentify":
105
+ storage.removeInterceptedIdentify(Int64(eventId))
106
+ default:
107
+ break
108
+ }
109
+ }
36
110
  }
@@ -7,10 +7,9 @@
7
7
  objects = {
8
8
 
9
9
  /* Begin PBXBuildFile section */
10
-
11
- 5E555C0D2413F4C50049A1A2 /* AmplitudeReactNative.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* AmplitudeReactNative.m */; };
12
- F4FF95D7245B92E800C19C63 /* AmplitudeReactNative.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* AmplitudeReactNative.swift */; };
13
-
10
+ 5E555C0D2413F4C50049A1A2 /* PBXBuildFile */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* AmplitudeReactNative.m */; };
11
+ 8EDEC1ED2DCD14B370FA86F1 /* LegacyDatabaseStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EDECE6C52794FD9D46192E2 /* LegacyDatabaseStorage.swift */; };
12
+ F4FF95D7245B92E800C19C63 /* AmplitudeReactNative.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* AmplitudeReactNative.swift */; };
14
13
  /* End PBXBuildFile section */
15
14
 
16
15
  /* Begin PBXCopyFilesBuildPhase section */
@@ -27,11 +26,10 @@
27
26
 
28
27
  /* Begin PBXFileReference section */
29
28
  134814201AA4EA6300B7C361 /* libAmplitudeReactNative.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAmplitudeReactNative.a; sourceTree = BUILT_PRODUCTS_DIR; };
30
-
29
+ 8EDECE6C52794FD9D46192E2 /* LegacyDatabaseStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacyDatabaseStorage.swift; sourceTree = "<group>"; };
31
30
  B3E7B5891CC2AC0600A0062D /* AmplitudeReactNative.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AmplitudeReactNative.m; sourceTree = "<group>"; };
32
31
  F4FF95D5245B92E700C19C63 /* AmplitudeReactNative-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AmplitudeReactNative-Bridging-Header.h"; sourceTree = "<group>"; };
33
32
  F4FF95D6245B92E800C19C63 /* AmplitudeReactNative.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AmplitudeReactNative.swift; sourceTree = "<group>"; };
34
-
35
33
  /* End PBXFileReference section */
36
34
 
37
35
  /* Begin PBXFrameworksBuildPhase section */
@@ -56,12 +54,11 @@
56
54
  58B511D21A9E6C8500147676 = {
57
55
  isa = PBXGroup;
58
56
  children = (
59
-
60
57
  F4FF95D6245B92E800C19C63 /* AmplitudeReactNative.swift */,
61
58
  B3E7B5891CC2AC0600A0062D /* AmplitudeReactNative.m */,
62
59
  F4FF95D5245B92E700C19C63 /* AmplitudeReactNative-Bridging-Header.h */,
63
-
64
60
  134814211AA4EA7D00B7C361 /* Products */,
61
+ 8EDECE6C52794FD9D46192E2 /* LegacyDatabaseStorage.swift */,
65
62
  );
66
63
  sourceTree = "<group>";
67
64
  };
@@ -99,7 +96,7 @@
99
96
  };
100
97
  };
101
98
  };
102
- buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "ReactNative" */;
99
+ buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "AmplitudeReactNative" */;
103
100
  compatibilityVersion = "Xcode 3.2";
104
101
  developmentRegion = English;
105
102
  hasScannedForEncodings = 0;
@@ -122,10 +119,9 @@
122
119
  isa = PBXSourcesBuildPhase;
123
120
  buildActionMask = 2147483647;
124
121
  files = (
125
-
126
122
  F4FF95D7245B92E800C19C63 /* AmplitudeReactNative.swift in Sources */,
127
- B3E7B58A1CC2AC0600A0062D /* AmplitudeReactNative.m in Sources */,
128
-
123
+ B3E7B58A1CC2AC0600A0062D,
124
+ 8EDEC1ED2DCD14B370FA86F1 /* LegacyDatabaseStorage.swift in Sources */,
129
125
  );
130
126
  runOnlyForDeploymentPostprocessing = 0;
131
127
  };
@@ -238,11 +234,9 @@
238
234
  OTHER_LDFLAGS = "-ObjC";
239
235
  PRODUCT_NAME = ReactNative;
240
236
  SKIP_INSTALL = YES;
241
-
242
237
  SWIFT_OBJC_BRIDGING_HEADER = "AmplitudeReactNative-Bridging-Header.h";
243
238
  SWIFT_OPTIMIZATION_LEVEL = "-Onone";
244
239
  SWIFT_VERSION = 5.0;
245
-
246
240
  };
247
241
  name = Debug;
248
242
  };
@@ -259,17 +253,15 @@
259
253
  OTHER_LDFLAGS = "-ObjC";
260
254
  PRODUCT_NAME = ReactNative;
261
255
  SKIP_INSTALL = YES;
262
-
263
256
  SWIFT_OBJC_BRIDGING_HEADER = "AmplitudeReactNative-Bridging-Header.h";
264
257
  SWIFT_VERSION = 5.0;
265
-
266
258
  };
267
259
  name = Release;
268
260
  };
269
261
  /* End XCBuildConfiguration section */
270
262
 
271
263
  /* Begin XCConfigurationList section */
272
- 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "ReactNative" */ = {
264
+ 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "AmplitudeReactNative" */ = {
273
265
  isa = XCConfigurationList;
274
266
  buildConfigurations = (
275
267
  58B511ED1A9E6C8500147676 /* Debug */,