react-native-flic2 2.0.0-alpha.39 → 2.0.0-beta.2

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.
@@ -15,6 +15,7 @@
15
15
  <!-- Foreground service permission -->
16
16
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
17
17
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
18
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
18
19
 
19
20
  <application>
20
21
  <service
@@ -22,6 +23,28 @@
22
23
  android:enabled="true"
23
24
  android:exported="false"
24
25
  android:foregroundServiceType="connectedDevice" />
26
+
27
+ <receiver
28
+ android:name=".Flic2Service$BootUpReceiver"
29
+ android:enabled="true"
30
+ android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
31
+ android:exported="false">
32
+ <intent-filter>
33
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
34
+ <category android:name="android.intent.category.DEFAULT" />
35
+ </intent-filter>
36
+ </receiver>
37
+
38
+ <receiver
39
+ android:name=".Flic2Service$UpdateReceiver"
40
+ android:enabled="true"
41
+ android:exported="false">
42
+ <intent-filter>
43
+ <action android:name="android.intent.action.PACKAGE_REPLACED" />
44
+ <data
45
+ android:scheme="package" />
46
+ </intent-filter>
47
+ </receiver>
25
48
  </application>
26
49
 
27
50
  </manifest>
@@ -0,0 +1,29 @@
1
+ package com.flic2
2
+
3
+ import android.app.ActivityManager
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import android.os.Build
7
+
8
+ object ActivityUtil {
9
+ private const val TAG = "ActivityUtil"
10
+
11
+ fun isServiceRunning(context: Context, serviceClass: Class<*>): Boolean {
12
+ val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
13
+ for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
14
+ if (serviceClass.name == service.service.className) {
15
+ return true
16
+ }
17
+ }
18
+ return false
19
+ }
20
+
21
+ fun startForegroundService(context: Context, intent: Intent) {
22
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
23
+ context.startForegroundService(intent)
24
+ } else {
25
+ context.startService(intent)
26
+ }
27
+ }
28
+ }
29
+
@@ -51,6 +51,8 @@ class Flic2ButtonEventListener(
51
51
  })
52
52
  }
53
53
 
54
+ // Android library calls ALL applicable callback methods, causing duplicate events.
55
+ // Only onButtonSingleOrDoubleClickOrHold should emit events to match iOS behavior.
54
56
  override fun onButtonClickOrHold(
55
57
  button: Flic2Button,
56
58
  wasQueued: Boolean,
@@ -59,13 +61,11 @@ class Flic2ButtonEventListener(
59
61
  isClick: Boolean,
60
62
  isHold: Boolean
61
63
  ) {
62
- val event = if (isClick) "click" else "hold"
63
- emitEvent(createButtonEvent(button, event).apply {
64
- putBoolean("queued", wasQueued)
65
- putDouble("age", System.currentTimeMillis() - timestamp.toDouble())
66
- })
64
+ // Intentionally empty - events are handled by onButtonSingleOrDoubleClickOrHold
67
65
  }
68
66
 
67
+ // Android library calls ALL applicable callback methods, causing duplicate events.
68
+ // Only onButtonSingleOrDoubleClickOrHold should emit events to match iOS behavior.
69
69
  override fun onButtonSingleOrDoubleClick(
70
70
  button: Flic2Button,
71
71
  wasQueued: Boolean,
@@ -74,11 +74,7 @@ class Flic2ButtonEventListener(
74
74
  isSingleClick: Boolean,
75
75
  isDoubleClick: Boolean
76
76
  ) {
77
- val event = if (isSingleClick) "click" else "doubleClick"
78
- emitEvent(createButtonEvent(button, event).apply {
79
- putBoolean("queued", wasQueued)
80
- putDouble("age", System.currentTimeMillis() - timestamp.toDouble())
81
- })
77
+ // Intentionally empty - events are handled by onButtonSingleOrDoubleClickOrHold
82
78
  }
83
79
 
84
80
  override fun onButtonSingleOrDoubleClickOrHold(
@@ -57,6 +57,8 @@ class Flic2Module(reactContext: ReactApplicationContext) :
57
57
  manager.buttons.forEach { button ->
58
58
  setupButtonListener(button)
59
59
  }
60
+ // Update foreground service state based on button count
61
+ updateForegroundServiceState(manager.buttons.size)
60
62
  }
61
63
 
62
64
  // Resolve the initialize promise if pending
@@ -95,20 +97,6 @@ class Flic2Module(reactContext: ReactApplicationContext) :
95
97
  }
96
98
  }
97
99
 
98
- // Example method - keep for reference
99
- override fun multiply(a: Double, b: Double): Double {
100
- val result = a * b
101
-
102
- val eventData = Arguments.createMap().apply {
103
- putDouble("a", a)
104
- putDouble("b", b)
105
- putDouble("result", result)
106
- }
107
- emitOnMultiply(eventData)
108
-
109
- return result
110
- }
111
-
112
100
  // MARK: - Manager Methods
113
101
 
114
102
  override fun initialize(background: Boolean, promise: Promise) {
@@ -118,11 +106,11 @@ class Flic2Module(reactContext: ReactApplicationContext) :
118
106
 
119
107
  val intent = Intent(reactApplicationContext, Flic2Service::class.java)
120
108
 
121
- // Start service
122
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
123
- reactApplicationContext.startForegroundService(intent)
124
- } else {
125
- reactApplicationContext.startService(intent)
109
+ // Check if service is already running
110
+ val isRunning = ActivityUtil.isServiceRunning(reactApplicationContext, Flic2Service::class.java)
111
+ if (!isRunning) {
112
+ // Start service
113
+ ActivityUtil.startForegroundService(reactApplicationContext, intent)
126
114
  }
127
115
 
128
116
  // Bind to service - promise will be resolved in onServiceConnected
@@ -172,46 +160,42 @@ class Flic2Module(reactContext: ReactApplicationContext) :
172
160
 
173
161
  Log.d(TAG, "Starting scan")
174
162
 
163
+ // Emit started event (matches iOS)
164
+ emitOnScanStatusChange(Arguments.createMap().apply {
165
+ putString("event", "started")
166
+ putString("eventName", "started")
167
+ })
168
+
175
169
  manager.startScan(object : Flic2ScanCallback {
176
170
  override fun onDiscoveredAlreadyPairedButton(button: Flic2Button) {
177
171
  Log.d(TAG, "Discovered already paired button")
178
- emitOnScanStatusChange(Arguments.createMap().apply {
179
- putInt("event", 0)
180
- putString("eventName", "discovered")
181
- })
182
172
  }
183
173
 
184
174
  override fun onDiscovered(bdAddr: String) {
185
175
  Log.d(TAG, "Discovered button: $bdAddr")
186
- emitOnScanStatusChange(Arguments.createMap().apply {
187
- putInt("event", 0)
188
- putString("eventName", "discovered")
189
- })
190
176
  }
191
177
 
192
178
  override fun onConnected() {
193
179
  Log.d(TAG, "Button connected during scan")
194
- emitOnScanStatusChange(Arguments.createMap().apply {
195
- putInt("event", 1)
196
- putString("eventName", "connected")
197
- })
198
180
  }
199
181
 
200
182
  override fun onComplete(result: Int, subCode: Int, button: Flic2Button?) {
201
183
  Log.d(TAG, "Scan complete: result=$result, button=${button?.uuid}")
202
184
 
203
- if (result == Flic2ScanCallback.RESULT_SUCCESS && button != null) {
204
- emitOnScanStatusChange(Arguments.createMap().apply {
205
- putInt("event", 2)
206
- putString("eventName", "verified")
207
- })
185
+ val resultCode = mapScanResultToCode(result)
208
186
 
187
+ if (result == Flic2ScanCallback.RESULT_SUCCESS && button != null) {
209
188
  // Auto-connect (trigger mode not available in Android v1.1.0+)
210
189
  button.connect()
211
190
 
212
191
  setupButtonListener(button)
213
192
 
214
- // Emit discovered event
193
+ // Update foreground service state after adding button
194
+ flic2Service?.getManager()?.let { manager ->
195
+ updateForegroundServiceState(manager.buttons.size)
196
+ }
197
+
198
+ // Emit discovered event as button event (like iOS)
215
199
  emitOnButtonEvent(Arguments.createMap().apply {
216
200
  putString("uuid", button.uuid)
217
201
  putString("event", "discovered")
@@ -221,6 +205,13 @@ class Flic2Module(reactContext: ReactApplicationContext) :
221
205
  val errorCode = Flic2Converter.scanResultToString(result)
222
206
  Log.e(TAG, "Scan failed with error code: $errorCode")
223
207
  }
208
+
209
+ // Emit scan completion with result code
210
+ emitOnScanStatusChange(Arguments.createMap().apply {
211
+ putString("event", "completion")
212
+ putString("eventName", "completion")
213
+ putInt("result", resultCode)
214
+ })
224
215
  }
225
216
  })
226
217
 
@@ -275,6 +266,9 @@ class Flic2Module(reactContext: ReactApplicationContext) :
275
266
  // Forget button
276
267
  manager.forgetButton(button)
277
268
 
269
+ // Update foreground service state after removing button
270
+ updateForegroundServiceState(manager.buttons.size)
271
+
278
272
  promise.resolve(Arguments.createMap().apply {
279
273
  putBoolean("success", true)
280
274
  putString("message", "Button forgotten")
@@ -430,6 +424,9 @@ class Flic2Module(reactContext: ReactApplicationContext) :
430
424
  manager.forgetButton(button)
431
425
  }
432
426
 
427
+ // Update foreground service state after removing all buttons
428
+ updateForegroundServiceState(manager.buttons.size)
429
+
433
430
  promise.resolve(Arguments.createMap().apply {
434
431
  putBoolean("success", true)
435
432
  putString("message", "All buttons forgotten")
@@ -477,4 +474,31 @@ class Flic2Module(reactContext: ReactApplicationContext) :
477
474
  // Store listener reference
478
475
  buttonListeners[button.uuid] = listener
479
476
  }
477
+
478
+ private fun updateForegroundServiceState(buttonCount: Int) {
479
+ if (buttonCount > 0) {
480
+ // Start foreground service when buttons exist
481
+ flic2Service?.startForegroundService()
482
+ } else {
483
+ // Stop foreground service when no buttons
484
+ flic2Service?.stopForegroundService()
485
+ }
486
+ }
487
+
488
+ private fun mapScanResultToCode(result: Int): Int {
489
+ // Map Android library's 9 result codes (0-8) to TypeScript enum codes (0-21) matching iOS
490
+ // Android library only provides these constants, so we map them to the closest equivalent
491
+ return when (result) {
492
+ Flic2ScanCallback.RESULT_SUCCESS -> 0 // SUCCESS
493
+ Flic2ScanCallback.RESULT_FAILED_ALREADY_RUNNING -> 1 // ALREADY_RUNNING
494
+ Flic2ScanCallback.RESULT_FAILED_BLUETOOTH_OFF -> 2 // BLUETOOTH_NOT_ACTIVATED
495
+ Flic2ScanCallback.RESULT_FAILED_SCAN_ERROR -> 3 // UNKNOWN
496
+ Flic2ScanCallback.RESULT_FAILED_NO_NEW_BUTTONS_FOUND -> 4 // NO_PUBLIC_BUTTON_DISCOVERED
497
+ Flic2ScanCallback.RESULT_FAILED_BUTTON_ALREADY_CONNECTED_TO_OTHER_DEVICE -> 5 // ALREADY_CONNECTED_TO_ANOTHER_DEVICE
498
+ Flic2ScanCallback.RESULT_FAILED_CONNECT_TIMED_OUT -> 6 // CONNECTION_TIMEOUT
499
+ Flic2ScanCallback.RESULT_FAILED_VERIFY_TIMED_OUT -> 7 // INVALID_VERIFIER
500
+ Flic2ScanCallback.RESULT_SYSTEM_PAIRING_DIALOG_NOT_ACCEPTED -> 9 // BLE_PAIRING_FAILED_USER_CANCELED
501
+ else -> 3 // UNKNOWN (for any unexpected codes)
502
+ }
503
+ }
480
504
  }
@@ -5,7 +5,10 @@ import android.app.NotificationChannel
5
5
  import android.app.NotificationManager
6
6
  import android.app.PendingIntent
7
7
  import android.app.Service
8
+ import android.content.BroadcastReceiver
9
+ import android.content.Context
8
10
  import android.content.Intent
11
+ import android.content.pm.PackageManager
9
12
  import android.os.Binder
10
13
  import android.os.Build
11
14
  import android.os.Handler
@@ -19,12 +22,22 @@ class Flic2Service : Service() {
19
22
 
20
23
  private val binder = Flic2ServiceBinder()
21
24
  private var manager: Flic2Manager? = null
25
+ private var isServiceStarted = false
26
+ private var notification: Notification? = null
22
27
 
23
28
  companion object {
24
29
  private const val TAG = "Flic2Service"
25
- private const val NOTIFICATION_ID = 1
26
- private const val CHANNEL_ID = "Flic2ServiceChannel"
27
- private const val CHANNEL_NAME = "Flic2 Service"
30
+ private const val DEFAULT_NOTIFICATION_ID = 123321
31
+ private const val DEFAULT_CHANNEL_ID = "Notification_Channel_Flic2Service"
32
+
33
+ // Metadata keys for notification configuration
34
+ private const val KEY_CHANNEL_NAME = "nl.xguard.flic2.notification_channel_name"
35
+ private const val KEY_CHANNEL_DESCRIPTION = "nl.xguard.flic2.notification_channel_description"
36
+ private const val NOTIFICATION_TITLE_KEY = "nl.xguard.flic2.notification_title"
37
+ private const val NOTIFICATION_TEXT_KEY = "nl.xguard.flic2.notification_text"
38
+ private const val NOTIFICATION_ICON_KEY = "nl.xguard.flic2.notification_icon"
39
+ private const val NOTIFICATION_ID_KEY = "nl.xguard.flic2.notification_id"
40
+ private const val CHANNEL_ID_KEY = "nl.xguard.flic2.notification_channel_id"
28
41
  }
29
42
 
30
43
  inner class Flic2ServiceBinder : Binder() {
@@ -47,31 +60,25 @@ class Flic2Service : Service() {
47
60
  } catch (e: Exception) {
48
61
  Log.e(TAG, "Failed to initialize Flic2Manager", e)
49
62
  }
63
+
64
+ // Create notification channel and notification in onCreate
65
+ createNotificationChannel()
66
+ notification = createNotification()
50
67
  }
51
68
 
52
69
  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
53
70
  Log.d(TAG, "Service onStartCommand")
54
71
 
55
- // Create notification channel for Android O and above
56
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
57
- val channel = NotificationChannel(
58
- CHANNEL_ID,
59
- CHANNEL_NAME,
60
- NotificationManager.IMPORTANCE_LOW
61
- ).apply {
62
- description = "Keeps Flic2 buttons connected in the background"
63
- setShowBadge(false)
72
+ if (intent != null) {
73
+ if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
74
+ Log.d(TAG, "onStartCommand: ACTION_BOOT_COMPLETED")
64
75
  }
65
-
66
- val notificationManager = getSystemService(NotificationManager::class.java)
67
- notificationManager.createNotificationChannel(channel)
68
76
  }
69
77
 
70
- // Create notification
71
- val notification = createNotification()
72
-
73
- // Start as foreground service
74
- startForeground(NOTIFICATION_ID, notification)
78
+ // Start foreground service if notification is ready
79
+ if (notification != null) {
80
+ startForegroundService()
81
+ }
75
82
 
76
83
  return START_STICKY
77
84
  }
@@ -90,6 +97,45 @@ class Flic2Service : Service() {
90
97
 
91
98
  fun isManagerInitialized(): Boolean = manager != null
92
99
 
100
+ fun startForegroundService() {
101
+ if (!isServiceStarted && notification != null) {
102
+ isServiceStarted = true
103
+ try {
104
+ val notificationId = getNotificationId()
105
+ startForeground(notificationId, notification)
106
+ } catch (e: Exception) {
107
+ Log.w(TAG, "startForegroundService() exception", e)
108
+ }
109
+ }
110
+ }
111
+
112
+ fun stopForegroundService() {
113
+ if (isServiceStarted) {
114
+ isServiceStarted = false
115
+ stopForeground(true)
116
+ }
117
+ }
118
+
119
+ private fun createNotificationChannel() {
120
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
121
+ val channelId = getChannelId()
122
+ val channelName = getChannelName()
123
+ val channelDescription = getChannelDescription()
124
+
125
+ val channel = NotificationChannel(
126
+ channelId,
127
+ channelName,
128
+ NotificationManager.IMPORTANCE_LOW
129
+ ).apply {
130
+ description = channelDescription
131
+ setShowBadge(false)
132
+ }
133
+
134
+ val notificationManager = getSystemService(NotificationManager::class.java)
135
+ notificationManager.createNotificationChannel(channel)
136
+ }
137
+ }
138
+
93
139
  private fun createNotification(): Notification {
94
140
  val notificationIntent = Intent(this, Flic2Service::class.java)
95
141
  val pendingIntent = PendingIntent.getActivity(
@@ -99,14 +145,141 @@ class Flic2Service : Service() {
99
145
  PendingIntent.FLAG_IMMUTABLE
100
146
  )
101
147
 
102
- return NotificationCompat.Builder(this, CHANNEL_ID)
103
- .setContentTitle("Flic2 Service")
104
- .setContentText("Flic2 buttons are connected")
105
- .setSmallIcon(android.R.drawable.ic_dialog_info)
148
+ val channelId = getChannelId()
149
+ val title = getNotificationTitle()
150
+ val text = getNotificationText()
151
+ val icon = getNotificationIcon()
152
+
153
+ return NotificationCompat.Builder(this, channelId)
154
+ .setContentTitle(title)
155
+ .setContentText(text)
156
+ .setSmallIcon(icon)
106
157
  .setContentIntent(pendingIntent)
107
158
  .setPriority(NotificationCompat.PRIORITY_LOW)
108
159
  .setOngoing(true)
109
160
  .build()
110
161
  }
162
+
163
+ private fun getNotificationId(): Int {
164
+ return try {
165
+ val metadata = applicationContext.packageManager
166
+ .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
167
+ .metaData
168
+ metadata?.getInt(NOTIFICATION_ID_KEY, DEFAULT_NOTIFICATION_ID) ?: DEFAULT_NOTIFICATION_ID
169
+ } catch (e: PackageManager.NameNotFoundException) {
170
+ Log.w(TAG, "getNotificationId() NameNotFoundException", e)
171
+ DEFAULT_NOTIFICATION_ID
172
+ } catch (e: Exception) {
173
+ Log.w(TAG, "getNotificationId() exception", e)
174
+ DEFAULT_NOTIFICATION_ID
175
+ }
176
+ }
177
+
178
+ private fun getChannelId(): String {
179
+ return try {
180
+ val metadata = applicationContext.packageManager
181
+ .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
182
+ .metaData
183
+ metadata?.getString(CHANNEL_ID_KEY) ?: DEFAULT_CHANNEL_ID
184
+ } catch (e: PackageManager.NameNotFoundException) {
185
+ Log.w(TAG, "getChannelId() NameNotFoundException", e)
186
+ DEFAULT_CHANNEL_ID
187
+ } catch (e: Exception) {
188
+ Log.w(TAG, "getChannelId() exception", e)
189
+ DEFAULT_CHANNEL_ID
190
+ }
191
+ }
192
+
193
+ private fun getChannelName(): String {
194
+ return try {
195
+ val metadata = applicationContext.packageManager
196
+ .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
197
+ .metaData
198
+ metadata?.getString(KEY_CHANNEL_NAME) ?: "Flic2Channel"
199
+ } catch (e: PackageManager.NameNotFoundException) {
200
+ Log.w(TAG, "getChannelName() NameNotFoundException", e)
201
+ "Flic2Channel"
202
+ } catch (e: Exception) {
203
+ Log.w(TAG, "getChannelName() exception", e)
204
+ "Flic2Channel"
205
+ }
206
+ }
207
+
208
+ private fun getChannelDescription(): String {
209
+ return try {
210
+ val metadata = applicationContext.packageManager
211
+ .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
212
+ .metaData
213
+ metadata?.getString(KEY_CHANNEL_DESCRIPTION) ?: "Flic2Channel"
214
+ } catch (e: PackageManager.NameNotFoundException) {
215
+ Log.w(TAG, "getChannelDescription() NameNotFoundException", e)
216
+ "Flic2Channel"
217
+ } catch (e: Exception) {
218
+ Log.w(TAG, "getChannelDescription() exception", e)
219
+ "Flic2Channel"
220
+ }
221
+ }
222
+
223
+ private fun getNotificationTitle(): String {
224
+ return try {
225
+ val metadata = applicationContext.packageManager
226
+ .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
227
+ .metaData
228
+ metadata?.getString(NOTIFICATION_TITLE_KEY) ?: "Flic 2"
229
+ } catch (e: PackageManager.NameNotFoundException) {
230
+ Log.w(TAG, "getNotificationTitle() NameNotFoundException", e)
231
+ "Flic 2"
232
+ } catch (e: Exception) {
233
+ Log.w(TAG, "getNotificationTitle() exception", e)
234
+ "Flic 2"
235
+ }
236
+ }
237
+
238
+ private fun getNotificationText(): String {
239
+ return try {
240
+ val metadata = applicationContext.packageManager
241
+ .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
242
+ .metaData
243
+ metadata?.getString(NOTIFICATION_TEXT_KEY) ?: "Flic 2 service is running"
244
+ } catch (e: PackageManager.NameNotFoundException) {
245
+ Log.w(TAG, "getNotificationText() NameNotFoundException", e)
246
+ "Flic 2 service is running"
247
+ } catch (e: Exception) {
248
+ Log.w(TAG, "getNotificationText() exception", e)
249
+ "Flic 2 service is running"
250
+ }
251
+ }
252
+
253
+ private fun getNotificationIcon(): Int {
254
+ return try {
255
+ val metadata = applicationContext.packageManager
256
+ .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
257
+ .metaData
258
+ val icon = metadata?.getInt(NOTIFICATION_ICON_KEY, 0) ?: 0
259
+ if (icon != 0) icon else android.R.drawable.ic_dialog_info
260
+ } catch (e: PackageManager.NameNotFoundException) {
261
+ Log.w(TAG, "getNotificationIcon() NameNotFoundException", e)
262
+ android.R.drawable.ic_dialog_info
263
+ } catch (e: Exception) {
264
+ Log.w(TAG, "getNotificationIcon() exception", e)
265
+ android.R.drawable.ic_dialog_info
266
+ }
267
+ }
268
+
269
+ // BootUpReceiver for handling device boot
270
+ class BootUpReceiver : BroadcastReceiver() {
271
+ override fun onReceive(context: Context, intent: Intent) {
272
+ Log.d(TAG, "BootUpReceiver()")
273
+ // The Application class's onCreate has already been called at this point, which is what we want
274
+ }
275
+ }
276
+
277
+ // UpdateReceiver for handling app updates
278
+ class UpdateReceiver : BroadcastReceiver() {
279
+ override fun onReceive(context: Context, intent: Intent) {
280
+ Log.d(TAG, "UpdateReceiver()")
281
+ // The Application class's onCreate has already been called at this point, which is what we want
282
+ }
283
+ }
111
284
  }
112
285
 
package/ios/Flic2.h CHANGED
@@ -6,7 +6,6 @@
6
6
 
7
7
  @interface Flic2 : NativeFlic2SpecBase <NativeFlic2Spec, FLICManagerDelegate, FLICButtonDelegate>
8
8
 
9
- @property (nonatomic, strong) FLICManager *manager;
10
9
  @property (nonatomic, assign) BOOL managerRestored;
11
10
 
12
11
  @end