@capacitor/background-runner 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -441,9 +441,11 @@ A simple string key / value store backed by UserDefaults on iOS and Shared Prefe
441
441
 
442
442
  Send basic local notifications.
443
443
 
444
- | Prop | Type | Description | Since |
445
- | -------------- | ------------------------------------- | ----------------------------- | ----- |
446
- | **`schedule`** | <code>(options: {}) =&gt; void</code> | Schedule a local notification | 1.0.0 |
444
+ | Prop | Type | Description | Since |
445
+ | ---------------- | --------------------------------------------------------------------------------------------------- | ---------------------------------- | ----- |
446
+ | **`schedule`** | <code>(options: {}) =&gt; void</code> | Schedule a local notification | 1.0.0 |
447
+ | **`setBadge`** | <code>(options: <a href="#notificationbadgeoptions">NotificationBadgeOptions</a>) =&gt; void</code> | Set the application badge count | 2.0.0 |
448
+ | **`clearBadge`** | <code>() =&gt; void</code> | Clears the application badge count | 2.0.0 |
447
449
 
448
450
 
449
451
  #### NotificationScheduleOptions
@@ -470,6 +472,15 @@ Send basic local notifications.
470
472
  | **`channelId`** | <code>string</code> | Specifies the channel the notification should be delivered on. If channel with the given name does not exist then the notification will not fire. If not provided, it will use the default channel. Calls `setChannelId()` on [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder) with the provided value. Only available for Android 26+. | 1.0.0 |
471
473
 
472
474
 
475
+ #### NotificationBadgeOptions
476
+
477
+ | Prop | Type | Description | Since |
478
+ | -------------------------- | ------------------- | ------------------------------------------------------------------------------------- | ----- |
479
+ | **`count`** | <code>number</code> | The number to set on the application badge count. | 2.0.0 |
480
+ | **`notificationTitle`** | <code>string</code> | The **required** title for the associated badge count notification. Only for Android. | 2.0.0 |
481
+ | **`notificationSubtitle`** | <code>string</code> | The subtitle for the associated badge count notification. Only for Android. | 2.0.0 |
482
+
483
+
473
484
  #### CapacitorGeolocation
474
485
 
475
486
  Get access to device location information.
@@ -492,21 +503,46 @@ Get access to device location information.
492
503
  | **`heading`** | <code>number \| null</code> | The heading the user is facing (if available) | 1.0.0 |
493
504
 
494
505
 
495
- #### CapcacitorWatch
506
+ #### CapacitorWatch
496
507
 
497
508
  Interact with a watch paired with this app
498
509
 
499
- sendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a CapactiorWatch Watch application.
510
+ sendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a <a href="#capacitorwatch">CapacitorWatch</a> Watch application.
500
511
  They could be used if a native watch app is developed as a companion app to a Capacitor app
501
512
 
502
- | Prop | Type | Description |
503
- | ------------------------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
504
- | **`sendMessage`** | <code>(options: []) =&gt; void</code> | Sends a message to the watch with the sendMessage() WCSession delegate method This has no effect on a CapacitorWatch watch app |
505
- | **`transferUserInfo`** | <code>(options: []) =&gt; void</code> | Sends information to the watch with the transferUserInfo() WCSession delegate method This has no effect on a CapacitorWatch watch app |
506
- | **`updateApplicationContext`** | <code>(options: []) =&gt; void</code> | Updates the application context on the watch with the updateApplicationContext() WCSession delegate method This has no effect on a CapacitorWatch watch app |
507
- | **`isReachable`** | <code>boolean</code> | Checks to see if the compaion watch is reachable |
508
- | **`updateWatchUI`** | <code>(options: { watchUI: string; }) =&gt; void</code> | Replaces the current UI on the watch with what is specified here. |
509
- | **`updateWatchData`** | <code>(options: { data: { [key: string]: string; }; }) =&gt; void</code> | Updates the data the watch is using to display variables in text and button fields |
513
+ | Prop | Type | Description |
514
+ | ------------------------------ | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
515
+ | **`sendMessage`** | <code>(options: []) =&gt; void</code> | Sends a message to the watch with the sendMessage() WCSession delegate method This has no effect on a <a href="#capacitorwatch">CapacitorWatch</a> watch app |
516
+ | **`transferUserInfo`** | <code>(options: []) =&gt; void</code> | Sends information to the watch with the transferUserInfo() WCSession delegate method This has no effect on a <a href="#capacitorwatch">CapacitorWatch</a> watch app |
517
+ | **`updateApplicationContext`** | <code>(options: []) =&gt; void</code> | Updates the application context on the watch with the updateApplicationContext() WCSession delegate method This has no effect on a <a href="#capacitorwatch">CapacitorWatch</a> watch app |
518
+ | **`isReachable`** | <code>boolean</code> | Checks to see if the compaion watch is reachable |
519
+ | **`updateWatchUI`** | <code>(options: { watchUI: string; }) =&gt; void</code> | Replaces the current UI on the watch with what is specified here. |
520
+ | **`updateWatchData`** | <code>(options: { data: { [key: string]: string; }; }) =&gt; void</code> | Updates the data the watch is using to display variables in text and button fields |
521
+
522
+
523
+ #### CapacitorApp
524
+
525
+ | Prop | Type |
526
+ | -------------- | ------------------------------------------------------ |
527
+ | **`getState`** | <code>() =&gt; <a href="#appstate">AppState</a></code> |
528
+ | **`getInfo`** | <code>() =&gt; <a href="#appinfo">AppInfo</a></code> |
529
+
530
+
531
+ #### AppState
532
+
533
+ | Prop | Type | Description | Since |
534
+ | -------------- | -------------------- | --------------------------------- | ----- |
535
+ | **`isActive`** | <code>boolean</code> | Whether the app is active or not. | 1.0.0 |
536
+
537
+
538
+ #### AppInfo
539
+
540
+ | Prop | Type | Description | Since |
541
+ | ------------- | ------------------- | --------------------------------------------------------------------------------------------------- | ----- |
542
+ | **`name`** | <code>string</code> | The name of the app. | 1.0.0 |
543
+ | **`id`** | <code>string</code> | The identifier of the app. On iOS it's the Bundle Identifier. On Android it's the Application ID | 1.0.0 |
544
+ | **`build`** | <code>string</code> | The build version. On iOS it's the CFBundleVersion. On Android it's the versionCode. | 1.0.0 |
545
+ | **`version`** | <code>string</code> | The app version. On iOS it's the CFBundleShortVersionString. On Android it's package's versionName. | 1.0.0 |
510
546
 
511
547
 
512
548
  </capacitor-api-docs>
@@ -1,7 +1,7 @@
1
1
  ext {
2
2
  junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
3
  androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
4
- androidxCoreKTXVersion = project.hasProperty('androidxCoreKTXVersion') ? rootProject.ext.androidxCoreKTXVersion : '1.10.0'
4
+ androidxCoreKTXVersion = project.hasProperty('androidxCoreKTXVersion') ? rootProject.ext.androidxCoreKTXVersion : '1.12.0'
5
5
  androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
6
6
  androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
7
7
  workManagerVersion = project.hasProperty('workManagerVersion') ? rootProject.ext.workManagerVersion : '2.8.1'
@@ -9,13 +9,13 @@ ext {
9
9
  }
10
10
 
11
11
  buildscript {
12
- ext.kotlin_version = project.hasProperty("kotlin_version") ? rootProject.ext.kotlin_version : '1.8.20'
12
+ ext.kotlin_version = project.hasProperty("kotlin_version") ? rootProject.ext.kotlin_version : '1.9.10'
13
13
  repositories {
14
14
  google()
15
15
  mavenCentral()
16
16
  }
17
17
  dependencies {
18
- classpath 'com.android.tools.build:gradle:8.0.0'
18
+ classpath 'com.android.tools.build:gradle:8.2.1'
19
19
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
20
20
 
21
21
  }
@@ -26,10 +26,10 @@ apply plugin: 'org.jetbrains.kotlin.android'
26
26
 
27
27
  android {
28
28
  namespace "com.capacitorjs.plugins.backgroundrunner"
29
- compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 33
29
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
30
30
  defaultConfig {
31
31
  minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
32
- targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 33
32
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34
33
33
  versionCode 1
34
34
  versionName "1.0"
35
35
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -13,6 +13,8 @@ import io.ionic.android_js_engine.Context
13
13
  import io.ionic.android_js_engine.NativeCapacitorAPI
14
14
  import io.ionic.android_js_engine.NativeJSFunction
15
15
  import io.ionic.android_js_engine.Runner
16
+ import io.ionic.backgroundrunner.plugin.api.App
17
+ import io.ionic.backgroundrunner.plugin.api.AppState
16
18
  import io.ionic.backgroundrunner.plugin.api.Device
17
19
  import io.ionic.backgroundrunner.plugin.api.Geolocation
18
20
  import io.ionic.backgroundrunner.plugin.api.KV
@@ -187,6 +189,7 @@ class BackgroundRunner(context: android.content.Context) {
187
189
  api.initKVAPI(KV(context, config.label))
188
190
  api.initGeolocationAPI(Geolocation(context))
189
191
  api.initNotificationsAPI(Notifications(context))
192
+ api.initAppAPI(App(context))
190
193
 
191
194
  val newContext = runner.createContext(contextName, api)
192
195
  newContext.execute(srcFile, false)
@@ -9,6 +9,7 @@ import com.getcapacitor.PluginMethod
9
9
  import com.getcapacitor.annotation.CapacitorPlugin
10
10
  import com.getcapacitor.annotation.Permission
11
11
  import com.getcapacitor.annotation.PermissionCallback
12
+ import io.ionic.backgroundrunner.plugin.api.AppState
12
13
  import kotlinx.coroutines.Dispatchers
13
14
  import kotlinx.coroutines.GlobalScope
14
15
  import kotlinx.coroutines.launch
@@ -30,27 +31,36 @@ import kotlinx.coroutines.runBlocking
30
31
  )
31
32
  class BackgroundRunnerPlugin: Plugin() {
32
33
  private var impl: BackgroundRunner? = null
34
+ private var appState: AppState = AppState.getInstance()
33
35
 
34
36
  companion object {
35
37
  const val GEOLOCATION = "geolocation"
36
38
  const val NOTIFICATIONS = "notifications"
37
39
  }
38
40
 
41
+ override fun handleOnStart() {
42
+ super.handleOnStart()
43
+ appState.isActive = true
44
+ }
45
+
39
46
  override fun handleOnPause() {
40
47
  super.handleOnPause()
41
48
  Log.d("Background Runner", "registering runner workers")
49
+ appState.isActive = false
42
50
  impl?.scheduleBackgroundTask(this.context)
43
51
  }
44
52
 
45
53
  override fun handleOnStop() {
46
54
  super.handleOnStop()
47
55
  Log.d("Background Runner", "shutting down foreground runner")
56
+ appState.isActive = false
48
57
  impl?.shutdown()
49
58
  }
50
59
 
51
60
  override fun handleOnResume() {
52
61
  super.handleOnResume()
53
62
  Log.d("Background Runner", "starting foreground runner")
63
+ appState.isActive = true
54
64
  impl?.start()
55
65
  }
56
66
 
@@ -0,0 +1,31 @@
1
+ package io.ionic.backgroundrunner.plugin.api
2
+
3
+ import androidx.core.content.pm.PackageInfoCompat
4
+ import com.getcapacitor.util.InternalUtils
5
+ import io.ionic.android_js_engine.capacitor_api.AppAPI
6
+ import org.json.JSONObject
7
+
8
+ class App(private val context: android.content.Context): AppAPI {
9
+
10
+ override fun getInfo(): String {
11
+ val packageInfo = InternalUtils.getPackageInfo(context.packageManager, context.packageName)
12
+ val appInfo = context.applicationInfo
13
+
14
+ val appName = if (appInfo.labelRes == 0) appInfo.nonLocalizedLabel.toString() else context.getString(appInfo.labelRes)
15
+
16
+ val info = JSONObject()
17
+ info.put("name", appName)
18
+ info.put("id", packageInfo.packageName)
19
+ info.put("build", PackageInfoCompat.getLongVersionCode(packageInfo).toString())
20
+ info.put("version", packageInfo.versionName)
21
+
22
+ return info.toString()
23
+ }
24
+
25
+ override fun getState(): String {
26
+
27
+ val state = JSONObject()
28
+ state.put("isActive", AppState.getInstance().isActive)
29
+ return state.toString()
30
+ }
31
+ }
@@ -0,0 +1,14 @@
1
+ package io.ionic.backgroundrunner.plugin.api
2
+
3
+ class AppState {
4
+ public var isActive = false
5
+
6
+ companion object {
7
+ @Volatile
8
+ private var instance: AppState? = null
9
+
10
+ fun getInstance() = instance ?: synchronized(this) {
11
+ instance ?: AppState().also { instance = it }
12
+ }
13
+ }
14
+ }
@@ -35,12 +35,15 @@ class Notification(jsonObject: JSONObject) {
35
35
  ongoing = jsonObject.optBoolean("ongoing", false)
36
36
  autoCancel = jsonObject.optBoolean("autoCancel", false)
37
37
 
38
- val scheduleDateString = jsonObject.getString("scheduleAt")
39
-
40
- val sdf = SimpleDateFormat(jsDateFormat)
41
- val parsedDate = sdf.parse(scheduleDateString)
42
-
43
- scheduleAt = parsedDate ?: Date()
38
+ val scheduleDateString = jsonObject.optString("scheduleAt", "")
39
+ if (scheduleDateString.isNotEmpty()) {
40
+ val sdf = SimpleDateFormat(jsDateFormat)
41
+ val parsedDate = sdf.parse(scheduleDateString)
42
+
43
+ scheduleAt = parsedDate ?: Date()
44
+ } else {
45
+ scheduleAt = Date()
46
+ }
44
47
  }
45
48
 
46
49
  fun smallIcon(context: android.content.Context, defaultIcon: Int): Int {
@@ -17,6 +17,8 @@ import com.getcapacitor.CapConfig
17
17
  import com.getcapacitor.plugin.util.AssetUtil
18
18
  import io.ionic.android_js_engine.capacitor_api.NotificationsAPI
19
19
  import org.json.JSONArray
20
+ import org.json.JSONObject
21
+
20
22
 
21
23
  class Notifications(context: Context) : NotificationsAPI {
22
24
  private val manager: NotificationManagerCompat
@@ -32,12 +34,40 @@ class Notifications(context: Context) : NotificationsAPI {
32
34
  this.config = CapConfig.loadDefault(context)
33
35
 
34
36
  this.createNotificationChannel()
37
+ this.createBadgeNotificationChannel()
35
38
  }
36
39
  companion object {
37
40
  const val notificationIntentKey = "LocalNotificationId"
38
41
  const val defaultNotificationChannelID = "default"
42
+ const val defaultBadgeNotificationChannelID = "badge"
43
+ }
44
+
45
+ override fun clearBadge() {
46
+ val builder = NotificationCompat.Builder(context, defaultBadgeNotificationChannelID)
47
+ builder.setSmallIcon(getDefaultSmallIcon())
48
+ builder.setNumber(0)
49
+ builder.setAutoCancel(true)
50
+
51
+ val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
52
+ manager.notify(1001, builder.build())
53
+ }
54
+
55
+ override fun setBadge(jsonString: String) {
56
+ val obj = JSONObject(jsonString)
57
+ val options = SetBadgeOptions(obj)
58
+
59
+ val builder = NotificationCompat.Builder(context, defaultBadgeNotificationChannelID)
60
+ builder.setSmallIcon(getDefaultSmallIcon())
61
+ builder.setContentTitle(options.messageTitle)
62
+ builder.setContentText(options.messageSubtitle)
63
+ builder.setNumber(options.count)
64
+ builder.setAutoCancel(true)
65
+
66
+ val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
67
+ manager.notify(1001, builder.build())
39
68
  }
40
69
 
70
+
41
71
  override fun schedule(jsonString: String) {
42
72
  val notifications = mutableListOf<Notification>()
43
73
 
@@ -96,6 +126,22 @@ class Notifications(context: Context) : NotificationsAPI {
96
126
  }
97
127
  }
98
128
 
129
+ private fun createBadgeNotificationChannel() {
130
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
131
+ val name: CharSequence = "Badge"
132
+ val description = "Badge"
133
+ val importance = NotificationManager.IMPORTANCE_LOW
134
+ val channel = NotificationChannel(defaultBadgeNotificationChannelID, name, importance)
135
+ channel.description = description
136
+ channel.setShowBadge(true)
137
+
138
+ val notificationManager = context.getSystemService(
139
+ NotificationManager::class.java
140
+ )
141
+ notificationManager.createNotificationChannel(channel)
142
+ }
143
+ }
144
+
99
145
  private fun getDefaultSoundUrl(context: Context): Uri? {
100
146
  val soundId = getDefaultSound(context)
101
147
  return if (soundId != AssetUtil.RESOURCE_ID_ZERO_VALUE) {
@@ -0,0 +1,11 @@
1
+ package io.ionic.backgroundrunner.plugin.api
2
+
3
+ import org.json.JSONObject
4
+
5
+ data class SetBadgeOptions(var count: Int, var messageTitle: String, var messageSubtitle: String) {
6
+ constructor(jsonObject: JSONObject) : this(0, "", "") {
7
+ this.count = jsonObject.optInt("count", 0)
8
+ this.messageTitle = jsonObject.optString("notificationTitle", "")
9
+ this.messageSubtitle = jsonObject.optString("notificationSubtitle", "")
10
+ }
11
+ }
@@ -47,9 +47,18 @@
47
47
  "tags": [],
48
48
  "docs": "",
49
49
  "complexTypes": [
50
- "CapcacitorWatch"
50
+ "CapacitorWatch"
51
51
  ],
52
- "type": "CapcacitorWatch"
52
+ "type": "CapacitorWatch"
53
+ },
54
+ {
55
+ "name": "CapacitorApp",
56
+ "tags": [],
57
+ "docs": "",
58
+ "complexTypes": [
59
+ "CapacitorApp"
60
+ ],
61
+ "type": "CapacitorApp"
53
62
  }
54
63
  ]
55
64
  },
@@ -239,6 +248,52 @@
239
248
  "NotificationScheduleOptions"
240
249
  ],
241
250
  "type": "(options: {}) => void"
251
+ },
252
+ {
253
+ "name": "setBadge",
254
+ "tags": [
255
+ {
256
+ "text": "`CapacitorNotifications.setBadge({...})`",
257
+ "name": "example"
258
+ },
259
+ {
260
+ "text": "options",
261
+ "name": "param"
262
+ },
263
+ {
264
+ "text": "void",
265
+ "name": "returns"
266
+ },
267
+ {
268
+ "text": "2.0.0",
269
+ "name": "since"
270
+ }
271
+ ],
272
+ "docs": "Set the application badge count",
273
+ "complexTypes": [
274
+ "NotificationBadgeOptions"
275
+ ],
276
+ "type": "(options: NotificationBadgeOptions) => void"
277
+ },
278
+ {
279
+ "name": "clearBadge",
280
+ "tags": [
281
+ {
282
+ "text": "`CapacitorNotifications.clearBadge()`",
283
+ "name": "example"
284
+ },
285
+ {
286
+ "text": "void",
287
+ "name": "returns"
288
+ },
289
+ {
290
+ "text": "2.0.0",
291
+ "name": "since"
292
+ }
293
+ ],
294
+ "docs": "Clears the application badge count",
295
+ "complexTypes": [],
296
+ "type": "() => void"
242
297
  }
243
298
  ]
244
299
  },
@@ -469,6 +524,51 @@
469
524
  }
470
525
  ]
471
526
  },
527
+ {
528
+ "name": "NotificationBadgeOptions",
529
+ "slug": "notificationbadgeoptions",
530
+ "docs": "",
531
+ "tags": [],
532
+ "methods": [],
533
+ "properties": [
534
+ {
535
+ "name": "count",
536
+ "tags": [
537
+ {
538
+ "text": "2.0.0",
539
+ "name": "since"
540
+ }
541
+ ],
542
+ "docs": "The number to set on the application badge count.",
543
+ "complexTypes": [],
544
+ "type": "number"
545
+ },
546
+ {
547
+ "name": "notificationTitle",
548
+ "tags": [
549
+ {
550
+ "text": "2.0.0",
551
+ "name": "since"
552
+ }
553
+ ],
554
+ "docs": "The **required** title for the associated badge count notification.\n\nOnly for Android.",
555
+ "complexTypes": [],
556
+ "type": "string"
557
+ },
558
+ {
559
+ "name": "notificationSubtitle",
560
+ "tags": [
561
+ {
562
+ "text": "2.0.0",
563
+ "name": "since"
564
+ }
565
+ ],
566
+ "docs": "The subtitle for the associated badge count notification.\n\nOnly for Android.",
567
+ "complexTypes": [],
568
+ "type": "string"
569
+ }
570
+ ]
571
+ },
472
572
  {
473
573
  "name": "CapacitorGeolocation",
474
574
  "slug": "capacitorgeolocation",
@@ -591,9 +691,9 @@
591
691
  ]
592
692
  },
593
693
  {
594
- "name": "CapcacitorWatch",
595
- "slug": "capcacitorwatch",
596
- "docs": "Interact with a watch paired with this app\n\nsendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a CapactiorWatch Watch application.\nThey could be used if a native watch app is developed as a companion app to a Capacitor app",
694
+ "name": "CapacitorWatch",
695
+ "slug": "capacitorwatch",
696
+ "docs": "Interact with a watch paired with this app\n\nsendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a CapacitorWatch Watch application.\nThey could be used if a native watch app is developed as a companion app to a Capacitor app",
597
697
  "tags": [],
598
698
  "methods": [],
599
699
  "properties": [
@@ -658,6 +758,111 @@
658
758
  "type": "(options: { data: { [key: string]: string; }; }) => void"
659
759
  }
660
760
  ]
761
+ },
762
+ {
763
+ "name": "CapacitorApp",
764
+ "slug": "capacitorapp",
765
+ "docs": "",
766
+ "tags": [],
767
+ "methods": [],
768
+ "properties": [
769
+ {
770
+ "name": "getState",
771
+ "tags": [],
772
+ "docs": "",
773
+ "complexTypes": [
774
+ "AppState"
775
+ ],
776
+ "type": "() => AppState"
777
+ },
778
+ {
779
+ "name": "getInfo",
780
+ "tags": [],
781
+ "docs": "",
782
+ "complexTypes": [
783
+ "AppInfo"
784
+ ],
785
+ "type": "() => AppInfo"
786
+ }
787
+ ]
788
+ },
789
+ {
790
+ "name": "AppState",
791
+ "slug": "appstate",
792
+ "docs": "",
793
+ "tags": [],
794
+ "methods": [],
795
+ "properties": [
796
+ {
797
+ "name": "isActive",
798
+ "tags": [
799
+ {
800
+ "text": "1.0.0",
801
+ "name": "since"
802
+ }
803
+ ],
804
+ "docs": "Whether the app is active or not.",
805
+ "complexTypes": [],
806
+ "type": "boolean"
807
+ }
808
+ ]
809
+ },
810
+ {
811
+ "name": "AppInfo",
812
+ "slug": "appinfo",
813
+ "docs": "",
814
+ "tags": [],
815
+ "methods": [],
816
+ "properties": [
817
+ {
818
+ "name": "name",
819
+ "tags": [
820
+ {
821
+ "text": "1.0.0",
822
+ "name": "since"
823
+ }
824
+ ],
825
+ "docs": "The name of the app.",
826
+ "complexTypes": [],
827
+ "type": "string"
828
+ },
829
+ {
830
+ "name": "id",
831
+ "tags": [
832
+ {
833
+ "text": "1.0.0",
834
+ "name": "since"
835
+ }
836
+ ],
837
+ "docs": "The identifier of the app.\nOn iOS it's the Bundle Identifier.\nOn Android it's the Application ID",
838
+ "complexTypes": [],
839
+ "type": "string"
840
+ },
841
+ {
842
+ "name": "build",
843
+ "tags": [
844
+ {
845
+ "text": "1.0.0",
846
+ "name": "since"
847
+ }
848
+ ],
849
+ "docs": "The build version.\nOn iOS it's the CFBundleVersion.\nOn Android it's the versionCode.",
850
+ "complexTypes": [],
851
+ "type": "string"
852
+ },
853
+ {
854
+ "name": "version",
855
+ "tags": [
856
+ {
857
+ "text": "1.0.0",
858
+ "name": "since"
859
+ }
860
+ ],
861
+ "docs": "The app version.\nOn iOS it's the CFBundleShortVersionString.\nOn Android it's package's versionName.",
862
+ "complexTypes": [],
863
+ "type": "string"
864
+ }
865
+ ]
661
866
  }
662
867
  ],
663
868
  "enums": [],
@@ -52,6 +52,30 @@ export interface NetworkStatus {
52
52
  connected: boolean;
53
53
  connectionType: string;
54
54
  }
55
+ export interface NotificationBadgeOptions {
56
+ /**
57
+ * The number to set on the application badge count.
58
+ *
59
+ * @since 2.0.0
60
+ */
61
+ count: number;
62
+ /**
63
+ * The **required** title for the associated badge count notification.
64
+ *
65
+ * Only for Android.
66
+ *
67
+ * @since 2.0.0
68
+ */
69
+ notificationTitle: string;
70
+ /**
71
+ * The subtitle for the associated badge count notification.
72
+ *
73
+ * Only for Android.
74
+ *
75
+ * @since 2.0.0
76
+ */
77
+ notificationSubtitle: string;
78
+ }
55
79
  export interface NotificationScheduleOptions {
56
80
  /**
57
81
  * The notification identifier.
@@ -239,6 +263,46 @@ export interface NotificationScheduleOptions {
239
263
  */
240
264
  channelId?: string;
241
265
  }
266
+ export interface AppInfo {
267
+ /**
268
+ * The name of the app.
269
+ *
270
+ * @since 1.0.0
271
+ */
272
+ name: string;
273
+ /**
274
+ * The identifier of the app.
275
+ * On iOS it's the Bundle Identifier.
276
+ * On Android it's the Application ID
277
+ *
278
+ * @since 1.0.0
279
+ */
280
+ id: string;
281
+ /**
282
+ * The build version.
283
+ * On iOS it's the CFBundleVersion.
284
+ * On Android it's the versionCode.
285
+ *
286
+ * @since 1.0.0
287
+ */
288
+ build: string;
289
+ /**
290
+ * The app version.
291
+ * On iOS it's the CFBundleShortVersionString.
292
+ * On Android it's package's versionName.
293
+ *
294
+ * @since 1.0.0
295
+ */
296
+ version: string;
297
+ }
298
+ export interface AppState {
299
+ /**
300
+ * Whether the app is active or not.
301
+ *
302
+ * @since 1.0.0
303
+ */
304
+ isActive: boolean;
305
+ }
242
306
  /**
243
307
  * Get access to device location information.
244
308
  *
@@ -310,14 +374,29 @@ export interface CapacitorNotifications {
310
374
  * @since 1.0.0
311
375
  */
312
376
  schedule: (options: NotificationScheduleOptions[]) => void;
377
+ /**
378
+ * Set the application badge count
379
+ * @example `CapacitorNotifications.setBadge({...})`
380
+ * @param options
381
+ * @returns void
382
+ * @since 2.0.0
383
+ */
384
+ setBadge: (options: NotificationBadgeOptions) => void;
385
+ /**
386
+ * Clears the application badge count
387
+ * @example `CapacitorNotifications.clearBadge()`
388
+ * @returns void
389
+ * @since 2.0.0
390
+ */
391
+ clearBadge: () => void;
313
392
  }
314
393
  /**
315
394
  * Interact with a watch paired with this app
316
395
  *
317
- * sendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a CapactiorWatch Watch application.
396
+ * sendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a CapacitorWatch Watch application.
318
397
  * They could be used if a native watch app is developed as a companion app to a Capacitor app
319
398
  */
320
- export interface CapcacitorWatch {
399
+ export interface CapacitorWatch {
321
400
  /**
322
401
  * Sends a message to the watch with the sendMessage() WCSession delegate method
323
402
  *
@@ -359,10 +438,15 @@ export interface CapcacitorWatch {
359
438
  };
360
439
  }) => void;
361
440
  }
441
+ export interface CapacitorApp {
442
+ getState: () => AppState;
443
+ getInfo: () => AppInfo;
444
+ }
362
445
  export interface CapacitorAPI {
363
446
  CapacitorDevice: CapacitorDevice;
364
447
  CapacitorKV: CapacitorKV;
365
448
  CapacitorNotifications: CapacitorNotifications;
366
449
  CapacitorGeolocation: CapacitorGeolocation;
367
- CapacitorWatch: CapcacitorWatch;
450
+ CapacitorWatch: CapacitorWatch;
451
+ CapacitorApp: CapacitorApp;
368
452
  }
@@ -1 +1 @@
1
- {"version":3,"file":"apis.js","sourceRoot":"","sources":["../../src/apis.ts"],"names":[],"mappings":"","sourcesContent":["export interface GetCurrentPositionResult {\n /**\n * Latitude in decimal degrees\n *\n * @since 1.0.0\n */\n latitude: number;\n /**\n * longitude in decimal degrees\n *\n * @since 1.0.0\n */\n longitude: number;\n /**\n * Accuracy level of the latitude and longitude coordinates in meters\n *\n * @since 1.0.0\n */\n accuracy: number;\n /**\n * The altitude the user is at (if available)\n *\n * @since 1.0.0\n */\n altitude: number | null;\n /**\n * Accuracy level of the altitude coordinate in meters, if available.\n *\n * Available on all iOS versions and on Android 8.0+.\n *\n * @since 1.0.0\n */\n altitudeAccuracy?: number | null | undefined;\n /**\n * The speed the user is traveling (if available)\n *\n * @since 1.0.0\n */\n speed: number | null;\n /**\n * The heading the user is facing (if available)\n *\n * @since 1.0.0\n */\n heading: number | null;\n}\n\nexport interface BatteryStatus {\n batteryLevel: number;\n isCharging: boolean;\n}\n\nexport interface NetworkStatus {\n connected: boolean;\n connectionType: string;\n}\n\nexport interface NotificationScheduleOptions {\n /**\n * The notification identifier.\n * On Android it's a 32-bit int.\n * So the value should be between -2147483648 and 2147483647 inclusive.\n *\n * @since 1.0.0\n */\n id: number;\n /**\n * The title of the notification.\n *\n * @since 1.0.0\n */\n title: string;\n /**\n * The body of the notification, shown below the title.\n *\n * @since 1.0.0\n */\n body: string;\n /**\n * Date to send this notification.\n *\n * @since 1.0.0\n */\n scheduleAt: Date;\n /**\n * Name of the audio file to play when this notification is displayed.\n *\n * Include the file extension with the filename.\n *\n * On iOS, the file should be in the app bundle.\n * On Android, the file should be in res/raw folder.\n *\n * Recommended format is `.wav` because is supported by both iOS and Android.\n *\n * Only available for iOS and Android < 26.\n * For Android 26+ use channelId of a channel configured with the desired sound.\n *\n * If the sound file is not found, (i.e. empty string or wrong name)\n * the default system notification sound will be used.\n * If not provided, it will produce the default sound on Android and no sound on iOS.\n *\n * @since 1.0.0\n */\n sound?: string;\n /**\n * Associate an action type with this notification.\n *\n * @since 1.0.0\n */\n actionTypeId?: string;\n /**\n * Used to group multiple notifications.\n *\n * Sets `threadIdentifier` on the\n * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent).\n *\n * Only available for iOS.\n *\n * @since 1.0.0\n */\n threadIdentifier?: string;\n /**\n * The string this notification adds to the category's summary format string.\n *\n * Sets `summaryArgument` on the\n * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent).\n *\n * Only available for iOS.\n *\n * @since 1.0.0\n */\n summaryArgument?: string;\n /**\n * Used to group multiple notifications.\n *\n * Calls `setGroup()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n group?: string;\n /**\n * If true, this notification becomes the summary for a group of\n * notifications.\n *\n * Calls `setGroupSummary()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android when using `group`.\n *\n * @since 1.0.0\n */\n groupSummary?: string;\n /**\n * Set extra data to store within this notification.\n *\n * @since 1.0.0\n */\n extra?: any;\n /**\n * If true, the notification can't be swiped away.\n *\n * Calls `setOngoing()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n ongoing?: boolean;\n /**\n * If true, the notification is canceled when the user clicks on it.\n *\n * Calls `setAutoCancel()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n autoCancel?: boolean;\n /**\n * Sets a multiline text block for display in a big text notification style.\n *\n * @since 1.0.0\n */\n largeBody?: string;\n /**\n * Used to set the summary text detail in inbox and big text notification styles.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n summaryText?: string;\n /**\n * Set a custom status bar icon.\n *\n * If set, this overrides the `smallIcon` option from Capacitor\n * configuration.\n *\n * Icons should be placed in your app's `res/drawable` folder. The value for\n * this option should be the drawable resource ID, which is the filename\n * without an extension.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n smallIcon?: string;\n /**\n * Set a large icon for notifications.\n *\n * Icons should be placed in your app's `res/drawable` folder. The value for\n * this option should be the drawable resource ID, which is the filename\n * without an extension.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n largeIcon?: string;\n /**\n * Specifies the channel the notification should be delivered on.\n *\n * If channel with the given name does not exist then the notification will\n * not fire. If not provided, it will use the default channel.\n *\n * Calls `setChannelId()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android 26+.\n *\n * @since 1.0.0\n */\n channelId?: string;\n}\n\n/**\n * Get access to device location information.\n *\n * @since 1.0.0\n */\nexport interface CapacitorGeolocation {\n /**\n * Get the device's last known location\n * @since 1.0.0\n */\n getCurrentPosition: () => GetCurrentPositionResult;\n}\n\n/**\n * A simple string key / value store backed by UserDefaults on iOS and Shared Preferences on Android.\n */\nexport interface CapacitorKV {\n /**\n * Set a string value with the given key.\n *\n * @param key\n * @param value\n * @returns\n * @since 1.0.0\n */\n set: (key: string, value: string) => void;\n /**\n * Get a string value for the given key.\n * @param key\n * @returns\n * @since 1.0.0\n */\n get: (key: string) => { value: string };\n /**\n * Remove a value with the given key.\n * @param key\n * @returns\n * @since 1.0.0\n */\n remove: (key: string) => void;\n}\n\n/**\n * Get information on the device, such as network connectivity and battery status.\n */\nexport interface CapacitorDevice {\n /**\n * Get the current battery status for the device.\n *\n * @since 1.0.0\n */\n getBatteryStatus: () => BatteryStatus;\n /**\n * Get the current network status for the device.\n *\n * @since 1.0.0\n */\n getNetworkStatus: () => NetworkStatus;\n}\n\n/**\n * Send basic local notifications.\n */\nexport interface CapacitorNotifications {\n /**\n * Schedule a local notification\n * @example `CapacitorNotifications.schedule()`\n * @param options\n * @returns void\n * @since 1.0.0\n */\n schedule: (options: NotificationScheduleOptions[]) => void;\n}\n\n/**\n * Interact with a watch paired with this app\n *\n * sendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a CapactiorWatch Watch application.\n * They could be used if a native watch app is developed as a companion app to a Capacitor app\n */\nexport interface CapcacitorWatch {\n /**\n * Sends a message to the watch with the sendMessage() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n sendMessage: (options: []) => void;\n /**\n * Sends information to the watch with the transferUserInfo() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n transferUserInfo: (options: []) => void;\n /**\n * Updates the application context on the watch with the updateApplicationContext() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n updateApplicationContext: (options: []) => void;\n /**\n * Checks to see if the compaion watch is reachable\n */\n isReachable: boolean;\n /**\n * Replaces the current UI on the watch with what is specified here.\n * @param options the new WatchUI you want to show on the watch\n * @returns void\n */\n updateWatchUI: (options: { watchUI: string }) => void;\n /**\n * Updates the data the watch is using to display variables in text and button fields\n * @param options the new data to send to the watch\n * @returns void\n */\n updateWatchData: (options: { data: { [key: string]: string } }) => void;\n}\n\nexport interface CapacitorAPI {\n CapacitorDevice: CapacitorDevice;\n CapacitorKV: CapacitorKV;\n CapacitorNotifications: CapacitorNotifications;\n CapacitorGeolocation: CapacitorGeolocation;\n CapacitorWatch: CapcacitorWatch;\n}\n"]}
1
+ {"version":3,"file":"apis.js","sourceRoot":"","sources":["../../src/apis.ts"],"names":[],"mappings":"","sourcesContent":["export interface GetCurrentPositionResult {\n /**\n * Latitude in decimal degrees\n *\n * @since 1.0.0\n */\n latitude: number;\n /**\n * longitude in decimal degrees\n *\n * @since 1.0.0\n */\n longitude: number;\n /**\n * Accuracy level of the latitude and longitude coordinates in meters\n *\n * @since 1.0.0\n */\n accuracy: number;\n /**\n * The altitude the user is at (if available)\n *\n * @since 1.0.0\n */\n altitude: number | null;\n /**\n * Accuracy level of the altitude coordinate in meters, if available.\n *\n * Available on all iOS versions and on Android 8.0+.\n *\n * @since 1.0.0\n */\n altitudeAccuracy?: number | null | undefined;\n /**\n * The speed the user is traveling (if available)\n *\n * @since 1.0.0\n */\n speed: number | null;\n /**\n * The heading the user is facing (if available)\n *\n * @since 1.0.0\n */\n heading: number | null;\n}\n\nexport interface BatteryStatus {\n batteryLevel: number;\n isCharging: boolean;\n}\n\nexport interface NetworkStatus {\n connected: boolean;\n connectionType: string;\n}\n\nexport interface NotificationBadgeOptions {\n /**\n * The number to set on the application badge count.\n *\n * @since 2.0.0\n */\n count: number;\n /**\n * The **required** title for the associated badge count notification.\n *\n * Only for Android.\n *\n * @since 2.0.0\n */\n notificationTitle: string;\n /**\n * The subtitle for the associated badge count notification.\n *\n * Only for Android.\n *\n * @since 2.0.0\n */\n notificationSubtitle: string;\n}\n\nexport interface NotificationScheduleOptions {\n /**\n * The notification identifier.\n * On Android it's a 32-bit int.\n * So the value should be between -2147483648 and 2147483647 inclusive.\n *\n * @since 1.0.0\n */\n id: number;\n /**\n * The title of the notification.\n *\n * @since 1.0.0\n */\n title: string;\n /**\n * The body of the notification, shown below the title.\n *\n * @since 1.0.0\n */\n body: string;\n /**\n * Date to send this notification.\n *\n * @since 1.0.0\n */\n scheduleAt: Date;\n /**\n * Name of the audio file to play when this notification is displayed.\n *\n * Include the file extension with the filename.\n *\n * On iOS, the file should be in the app bundle.\n * On Android, the file should be in res/raw folder.\n *\n * Recommended format is `.wav` because is supported by both iOS and Android.\n *\n * Only available for iOS and Android < 26.\n * For Android 26+ use channelId of a channel configured with the desired sound.\n *\n * If the sound file is not found, (i.e. empty string or wrong name)\n * the default system notification sound will be used.\n * If not provided, it will produce the default sound on Android and no sound on iOS.\n *\n * @since 1.0.0\n */\n sound?: string;\n /**\n * Associate an action type with this notification.\n *\n * @since 1.0.0\n */\n actionTypeId?: string;\n /**\n * Used to group multiple notifications.\n *\n * Sets `threadIdentifier` on the\n * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent).\n *\n * Only available for iOS.\n *\n * @since 1.0.0\n */\n threadIdentifier?: string;\n /**\n * The string this notification adds to the category's summary format string.\n *\n * Sets `summaryArgument` on the\n * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent).\n *\n * Only available for iOS.\n *\n * @since 1.0.0\n */\n summaryArgument?: string;\n /**\n * Used to group multiple notifications.\n *\n * Calls `setGroup()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n group?: string;\n /**\n * If true, this notification becomes the summary for a group of\n * notifications.\n *\n * Calls `setGroupSummary()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android when using `group`.\n *\n * @since 1.0.0\n */\n groupSummary?: string;\n /**\n * Set extra data to store within this notification.\n *\n * @since 1.0.0\n */\n extra?: any;\n /**\n * If true, the notification can't be swiped away.\n *\n * Calls `setOngoing()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n ongoing?: boolean;\n /**\n * If true, the notification is canceled when the user clicks on it.\n *\n * Calls `setAutoCancel()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n autoCancel?: boolean;\n /**\n * Sets a multiline text block for display in a big text notification style.\n *\n * @since 1.0.0\n */\n largeBody?: string;\n /**\n * Used to set the summary text detail in inbox and big text notification styles.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n summaryText?: string;\n /**\n * Set a custom status bar icon.\n *\n * If set, this overrides the `smallIcon` option from Capacitor\n * configuration.\n *\n * Icons should be placed in your app's `res/drawable` folder. The value for\n * this option should be the drawable resource ID, which is the filename\n * without an extension.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n smallIcon?: string;\n /**\n * Set a large icon for notifications.\n *\n * Icons should be placed in your app's `res/drawable` folder. The value for\n * this option should be the drawable resource ID, which is the filename\n * without an extension.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n largeIcon?: string;\n /**\n * Specifies the channel the notification should be delivered on.\n *\n * If channel with the given name does not exist then the notification will\n * not fire. If not provided, it will use the default channel.\n *\n * Calls `setChannelId()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android 26+.\n *\n * @since 1.0.0\n */\n channelId?: string;\n}\n\nexport interface AppInfo {\n /**\n * The name of the app.\n *\n * @since 1.0.0\n */\n name: string;\n\n /**\n * The identifier of the app.\n * On iOS it's the Bundle Identifier.\n * On Android it's the Application ID\n *\n * @since 1.0.0\n */\n id: string;\n\n /**\n * The build version.\n * On iOS it's the CFBundleVersion.\n * On Android it's the versionCode.\n *\n * @since 1.0.0\n */\n build: string;\n\n /**\n * The app version.\n * On iOS it's the CFBundleShortVersionString.\n * On Android it's package's versionName.\n *\n * @since 1.0.0\n */\n version: string;\n}\n\nexport interface AppState {\n /**\n * Whether the app is active or not.\n *\n * @since 1.0.0\n */\n isActive: boolean;\n}\n\n/**\n * Get access to device location information.\n *\n * @since 1.0.0\n */\nexport interface CapacitorGeolocation {\n /**\n * Get the device's last known location\n * @since 1.0.0\n */\n getCurrentPosition: () => GetCurrentPositionResult;\n}\n\n/**\n * A simple string key / value store backed by UserDefaults on iOS and Shared Preferences on Android.\n */\nexport interface CapacitorKV {\n /**\n * Set a string value with the given key.\n *\n * @param key\n * @param value\n * @returns\n * @since 1.0.0\n */\n set: (key: string, value: string) => void;\n /**\n * Get a string value for the given key.\n * @param key\n * @returns\n * @since 1.0.0\n */\n get: (key: string) => { value: string };\n /**\n * Remove a value with the given key.\n * @param key\n * @returns\n * @since 1.0.0\n */\n remove: (key: string) => void;\n}\n\n/**\n * Get information on the device, such as network connectivity and battery status.\n */\nexport interface CapacitorDevice {\n /**\n * Get the current battery status for the device.\n *\n * @since 1.0.0\n */\n getBatteryStatus: () => BatteryStatus;\n /**\n * Get the current network status for the device.\n *\n * @since 1.0.0\n */\n getNetworkStatus: () => NetworkStatus;\n}\n\n/**\n * Send basic local notifications.\n */\nexport interface CapacitorNotifications {\n /**\n * Schedule a local notification\n * @example `CapacitorNotifications.schedule()`\n * @param options\n * @returns void\n * @since 1.0.0\n */\n schedule: (options: NotificationScheduleOptions[]) => void;\n /**\n * Set the application badge count\n * @example `CapacitorNotifications.setBadge({...})`\n * @param options\n * @returns void\n * @since 2.0.0\n */\n setBadge: (options: NotificationBadgeOptions) => void;\n /**\n * Clears the application badge count\n * @example `CapacitorNotifications.clearBadge()`\n * @returns void\n * @since 2.0.0\n */\n clearBadge: () => void;\n}\n\n/**\n * Interact with a watch paired with this app\n *\n * sendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a CapacitorWatch Watch application.\n * They could be used if a native watch app is developed as a companion app to a Capacitor app\n */\nexport interface CapacitorWatch {\n /**\n * Sends a message to the watch with the sendMessage() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n sendMessage: (options: []) => void;\n /**\n * Sends information to the watch with the transferUserInfo() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n transferUserInfo: (options: []) => void;\n /**\n * Updates the application context on the watch with the updateApplicationContext() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n updateApplicationContext: (options: []) => void;\n /**\n * Checks to see if the compaion watch is reachable\n */\n isReachable: boolean;\n /**\n * Replaces the current UI on the watch with what is specified here.\n * @param options the new WatchUI you want to show on the watch\n * @returns void\n */\n updateWatchUI: (options: { watchUI: string }) => void;\n /**\n * Updates the data the watch is using to display variables in text and button fields\n * @param options the new data to send to the watch\n * @returns void\n */\n updateWatchData: (options: { data: { [key: string]: string } }) => void;\n}\n\nexport interface CapacitorApp {\n getState: () => AppState;\n getInfo: () => AppInfo;\n}\n\nexport interface CapacitorAPI {\n CapacitorDevice: CapacitorDevice;\n CapacitorKV: CapacitorKV;\n CapacitorNotifications: CapacitorNotifications;\n CapacitorGeolocation: CapacitorGeolocation;\n CapacitorWatch: CapacitorWatch;\n CapacitorApp: CapacitorApp;\n}\n"]}
@@ -6,22 +6,22 @@ import JavaScriptCore
6
6
  public class BackgroundRunner {
7
7
  public static let shared = BackgroundRunner()
8
8
  public var config: RunnerConfig?
9
-
9
+
10
10
  private var runner = Runner()
11
11
 
12
12
  public init() {
13
13
  do {
14
- config = try self.loadRunnerConfig()
14
+ config = try self.loadRunnerConfig()
15
15
  } catch {
16
16
  print("could not initialize BackgroundRunner: \(error)")
17
17
  }
18
18
  }
19
-
19
+
20
20
  public func scheduleBackgroundTasks() throws {
21
21
  guard let config = config else {
22
22
  throw BackgroundRunnerPluginError.noRunnerConfig
23
23
  }
24
-
24
+
25
25
  if !config.autoSchedule {
26
26
  return
27
27
  }
@@ -52,13 +52,17 @@ public class BackgroundRunner {
52
52
  _ = try BackgroundRunner.shared.execute(config: config)
53
53
 
54
54
  task.setTaskCompleted(success: true)
55
+
56
+ if config.repeats {
57
+ try self.scheduleBackgroundTasks()
58
+ }
55
59
  } catch {
56
60
  print("background task error: \(error)")
57
61
  task.setTaskCompleted(success: false)
58
62
  }
59
63
  }
60
64
  }
61
-
65
+
62
66
  // swiftlint:disable:next cyclomatic_complexity function_body_length
63
67
  public func execute(config: RunnerConfig, inputArgs: [String: Any]? = nil, callbackId: String? = nil) throws -> [String: Any]? {
64
68
  do {
@@ -130,7 +134,6 @@ public class BackgroundRunner {
130
134
  try context.dispatchEvent(event: config.event, details: args)
131
135
 
132
136
  waitGroup.wait()
133
-
134
137
 
135
138
  if let rejection = rejectionErr {
136
139
  throw EngineError.jsException(details: rejection.message)
@@ -13,7 +13,7 @@ public class BackgroundRunnerPlugin: CAPPlugin {
13
13
  name: UIApplication.didEnterBackgroundNotification,
14
14
  object: nil
15
15
  )
16
-
16
+
17
17
  initWatchConnectivity()
18
18
  }
19
19
 
@@ -64,7 +64,7 @@ public class BackgroundRunnerPlugin: CAPPlugin {
64
64
  guard var config = impl.config else {
65
65
  throw BackgroundRunnerPluginError.noRunnerConfig
66
66
  }
67
-
67
+
68
68
  config.event = runnerEvent
69
69
 
70
70
  // swiftlint:disable:next unowned_variable_capture
@@ -116,7 +116,7 @@ public class BackgroundRunnerPlugin: CAPPlugin {
116
116
  completionHandler(.failure(BackgroundRunnerPluginError.invalidArgument(reason: "event is missing or invalid")))
117
117
  return
118
118
  }
119
-
119
+
120
120
  var args: [String: Any] = [:]
121
121
 
122
122
  eventArgs.forEach { (key: AnyHashable, value: Any) in
@@ -0,0 +1,31 @@
1
+ import Foundation
2
+ import UIKit
3
+ import JavaScriptCore
4
+
5
+ @objc protocol CapacitorAppExports: JSExport {
6
+ static func getInfo() -> [String: Any]?
7
+ static func getState() -> [String: Any]
8
+ }
9
+
10
+ class CapacitorApp: NSObject, CapacitorAppExports {
11
+ static func getInfo() -> [String: Any]? {
12
+ if let info = Bundle.main.infoDictionary {
13
+ return [
14
+ "name": info["CFBundleDisplayName"] as? String ?? "",
15
+ "id": info["CFBundleIdentifier"] as? String ?? "",
16
+ "build": info["CFBundleVersion"] as? String ?? "",
17
+ "version": info["CFBundleShortVersionString"] as? String ?? ""
18
+ ]
19
+ }
20
+
21
+ return nil
22
+ }
23
+
24
+ static func getState() -> [String: Any] {
25
+ DispatchQueue.main.sync {
26
+ return [
27
+ "isActive": UIApplication.shared.applicationState == UIApplication.State.active
28
+ ]
29
+ }
30
+ }
31
+ }
@@ -16,7 +16,7 @@ class CapacitorKVStore: NSObject, CapacitorKVStoreExports {
16
16
  guard let value = UserDefaults.standard.string(forKey: key) else {
17
17
  return JSValue(nullIn: JSContext.current())
18
18
  }
19
-
19
+
20
20
  var valueWrapper: [String: String] = [:]
21
21
  valueWrapper["value"] = value
22
22
 
@@ -8,6 +8,18 @@ enum CapacitorNotificationsErrors: Error, Equatable {
8
8
  case permissionDenied
9
9
  }
10
10
 
11
+ struct SetBadgeOption {
12
+ let count: Int
13
+
14
+ init(from dict: [String: Any?]) {
15
+ if let optionsCount = dict["count"] as? Int {
16
+ count = optionsCount
17
+ } else {
18
+ count = 0
19
+ }
20
+ }
21
+ }
22
+
11
23
  struct NotificationOption {
12
24
  let id: Int
13
25
  let title: String
@@ -52,6 +64,8 @@ struct NotificationOption {
52
64
 
53
65
  @objc protocol CapacitorNotificationsExports: JSExport {
54
66
  static func schedule(_ options: JSValue)
67
+ static func setBadge(_ options: JSValue)
68
+ static func clearBadge()
55
69
  }
56
70
 
57
71
  class CapacitorNotifications: NSObject, CapacitorNotificationsExports {
@@ -164,4 +178,50 @@ class CapacitorNotifications: NSObject, CapacitorNotificationsExports {
164
178
  JSContext.current().exception = JSValue(newErrorFromMessage: "\(error)", in: JSContext.current())
165
179
  }
166
180
  }
181
+
182
+ static func setBadge(_ options: JSValue) {
183
+ do {
184
+ if CapacitorNotifications.checkPermission() != "granted" {
185
+ throw CapacitorNotificationsErrors.permissionDenied
186
+ }
187
+
188
+ if options.isUndefined || options.isNull {
189
+ throw CapacitorNotificationsErrors.invalidOptions(reason: "options are null")
190
+ }
191
+
192
+ guard let jsonDict = options.toDictionary() as? [String: Any?] else {
193
+ throw CapacitorNotificationsErrors.invalidOptions(reason: "options must be an valid object")
194
+ }
195
+
196
+ let badgeOptions = SetBadgeOption(from: jsonDict)
197
+
198
+ DispatchQueue.main.sync {
199
+ if #available(iOS 16.0, *) {
200
+ UNUserNotificationCenter.current().setBadgeCount(badgeOptions.count)
201
+ } else {
202
+ UIApplication.shared.applicationIconBadgeNumber = badgeOptions.count
203
+ }
204
+ }
205
+ } catch {
206
+ JSContext.current().exception = JSValue(newErrorFromMessage: "\(error)", in: JSContext.current())
207
+ }
208
+ }
209
+
210
+ static func clearBadge() {
211
+ do {
212
+ if CapacitorNotifications.checkPermission() != "granted" {
213
+ throw CapacitorNotificationsErrors.permissionDenied
214
+ }
215
+
216
+ DispatchQueue.main.sync {
217
+ if #available(iOS 16.0, *) {
218
+ UNUserNotificationCenter.current().setBadgeCount(0)
219
+ } else {
220
+ UIApplication.shared.applicationIconBadgeNumber = 0
221
+ }
222
+ }
223
+ } catch {
224
+ JSContext.current().exception = JSValue(newErrorFromMessage: "\(error)", in: JSContext.current())
225
+ }
226
+ }
167
227
  }
@@ -7,5 +7,6 @@ extension Context {
7
7
  jsContext.setObject(CapacitorWatch(), forKeyedSubscript: "CapacitorWatch" as NSString)
8
8
  jsContext.setObject(CapacitorNotifications.self, forKeyedSubscript: "CapacitorNotifications" as NSString)
9
9
  jsContext.setObject(CapacitorDevice(), forKeyedSubscript: "CapacitorDevice" as NSString)
10
+ jsContext.setObject(CapacitorApp.self, forKeyedSubscript: "CapacitorApp" as NSString)
10
11
  }
11
12
  }
@@ -6,7 +6,7 @@ public struct RunnerConfig {
6
6
  let src: String
7
7
  var autoSchedule: Bool
8
8
  var event: String
9
- let repeats: Bool?
9
+ let repeats: Bool
10
10
  let enableWatchConnectivity: Bool
11
11
 
12
12
  let interval: Int?
@@ -28,7 +28,7 @@ public struct RunnerConfig {
28
28
  self.label = label
29
29
  self.src = src
30
30
  self.event = event
31
- self.repeats = repeats
31
+ self.repeats = repeats ?? false
32
32
  self.interval = interval
33
33
  self.autoSchedule = autoStart ?? false
34
34
  self.enableWatchConnectivity = jsObject["enableWatchConnectivity"] as? Bool ?? false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/background-runner",
3
- "version": "1.1.0",
3
+ "version": "2.0.0",
4
4
  "description": "Capacitor Background Runner",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -49,11 +49,11 @@
49
49
  "postinstall": "node ./scripts/install_libs.js"
50
50
  },
51
51
  "devDependencies": {
52
- "@capacitor/android": "^5.2.2",
53
- "@capacitor/cli": "^5.2.2",
54
- "@capacitor/core": "^5.2.2",
55
- "@capacitor/docgen": "^0.0.18",
56
- "@capacitor/ios": "^5.2.2",
52
+ "@capacitor/android": "^6.0.0",
53
+ "@capacitor/cli": "^6.0.0",
54
+ "@capacitor/core": "^6.0.0",
55
+ "@capacitor/docgen": "^0.2.2",
56
+ "@capacitor/ios": "^6.0.0",
57
57
  "@ionic/eslint-config": "^0.3.0",
58
58
  "@ionic/prettier-config": "^1.0.1",
59
59
  "@ionic/swiftlint-config": "^1.1.2",
@@ -66,7 +66,7 @@
66
66
  "typescript": "^5.1.6"
67
67
  },
68
68
  "peerDependencies": {
69
- "@capacitor/core": "^5.0.0"
69
+ "@capacitor/core": "^6.0.0"
70
70
  },
71
71
  "prettier": "@ionic/prettier-config",
72
72
  "swiftlint": "@ionic/swiftlint-config",
@@ -81,5 +81,5 @@
81
81
  "src": "android"
82
82
  }
83
83
  },
84
- "gitHead": "83f21e30fc631fb22467bf9f46be28e79b33be71"
84
+ "gitHead": "c290f3cd6372453b2679a4255f822fc91664fe77"
85
85
  }