Skip to content

Commit

Permalink
Release 2.1.0 (#18)
Browse files Browse the repository at this point in the history
* Add new types

* Update versions & Changelog

* Fix typo

* Update Android

* Update iOS
  • Loading branch information
rlepinski authored Sep 16, 2024
1 parent 5c6750d commit 3fb9231
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 43 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Capacitor Plugin Changelog

## Version 2.1.0 September 16, 2024
Minor release that adds `notificationPermissionStatus` to the `PushNotificationStatus` object and a way to specify the fallback when requesting permissions and the permission is already denied.

### Changes
- Updated Airship Android SDK to 18.3.0
- Updated Airship iOS SDK to 18.9.1
- Added `notificationPermissionStatus` to `PushNotificationStatus`
- Added options to `enableUserNotifications` to specify the `PromptPermissionFallback` when enabling user notifications

## Version 2.0.1 July 16, 2024
Patch release that fixes a critical issue with iOS that prevents the Airship library from automatically initializing. Apps using 2.0.0 should update.

Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", branch: "main"),
.package(url: "https://github.com/urbanairship/airship-mobile-framework-proxy.git", from: "7.0.0")
.package(url: "https://github.com/urbanairship/airship-mobile-framework-proxy.git", from: "8.0.0")
],
targets: [
.target(
Expand Down
2 changes: 1 addition & 1 deletion UaCapacitorAirship.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Pod::Spec.new do |s|
s.ios.deployment_target = '14.0'
s.dependency 'Capacitor'
s.swift_version = '5.1'
s.dependency "AirshipFrameworkProxy", "7.0.0"
s.dependency "AirshipFrameworkProxy", "8.0.0"
s.default_subspecs = ["Bootloader", "Plugin"]


Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ext {
airshipProxyVersion = project.hasProperty('airshipProxyVersion') ? rootProject.ext.airshipProxyVersion : '7.0.0'
airshipProxyVersion = project.hasProperty('airshipProxyVersion') ? rootProject.ext.airshipProxyVersion : '8.0.0'
}


Expand Down
57 changes: 32 additions & 25 deletions android/src/main/java/com/airship/capacitor/AirshipPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.airship.capacitor

import android.os.Build
import com.getcapacitor.JSArray
import com.getcapacitor.JSObject
import com.getcapacitor.Plugin
import com.getcapacitor.PluginCall
Expand All @@ -14,6 +13,7 @@ import com.urbanairship.actions.ActionResult
import com.urbanairship.android.framework.proxy.EventType
import com.urbanairship.android.framework.proxy.events.EventEmitter
import com.urbanairship.android.framework.proxy.proxies.AirshipProxy
import com.urbanairship.android.framework.proxy.proxies.EnableUserNotificationsArgs
import com.urbanairship.android.framework.proxy.proxies.FeatureFlagProxy
import com.urbanairship.json.JsonList
import com.urbanairship.json.JsonMap
Expand Down Expand Up @@ -67,7 +67,7 @@ class AirshipPlugin : Plugin() {
}

private fun notifyPendingEvents() {
EventType.values().forEach { eventType ->
EventType.entries.forEach { eventType ->
EventEmitter.shared().processPending(listOf(eventType)) { event ->
val name = EVENT_NAME_MAP[event.type]
if (hasListeners(name)) {
Expand Down Expand Up @@ -118,9 +118,17 @@ class AirshipPlugin : Plugin() {

// Push
"push#setUserNotificationsEnabled" -> call.resolveResult(method) { proxy.push.setUserNotificationsEnabled(arg.requireBoolean()) }
"push#enableUserNotifications" -> call.resolvePending(method) { proxy.push.enableUserPushNotifications() }
"push#enableUserNotifications" -> call.resolveSuspending(method) {
val options = if (arg.isNull) {
null
} else {
EnableUserNotificationsArgs.fromJson(arg)
}
proxy.push.enableUserPushNotifications(options)
}

"push#isUserNotificationsEnabled" -> call.resolveResult(method) { proxy.push.isUserNotificationsEnabled() }
"push#getNotificationStatus" -> call.resolveResult(method) { proxy.push.getNotificationStatus() }
"push#getNotificationStatus" -> call.resolveSuspending(method) { proxy.push.getNotificationStatus() }
"push#getActiveNotifications" -> call.resolveResult(method) {
if (Build.VERSION.SDK_INT >= 23) {
proxy.push.getActiveNotifications()
Expand Down Expand Up @@ -225,28 +233,14 @@ class AirshipPlugin : Plugin() {
}

// Feature Flag
"featureFlagManager#flag" -> call.resolveDeferred(method) { resolveCallback ->
scope.launch {
try {
val flag = proxy.featureFlagManager.flag(arg.requireString())
resolveCallback(flag, null)
} catch (e: Exception) {
resolveCallback(null, e)
}
}
"featureFlagManager#flag" -> call.resolveSuspending(method) {
proxy.featureFlagManager.flag(arg.requireString())
}

"featureFlagManager#trackInteraction" -> {
call.resolveDeferred(method) { resolveCallback ->
scope.launch {
try {
val featureFlagProxy = FeatureFlagProxy(arg)
proxy.featureFlagManager.trackInteraction(flag = featureFlagProxy)
resolveCallback(null, null)
} catch (e: Exception) {
resolveCallback(null, e)
}
}
call.resolveSuspending(method) {
val featureFlagProxy = FeatureFlagProxy(arg)
proxy.featureFlagManager.trackInteraction(flag = featureFlagProxy)
}
}

Expand All @@ -262,14 +256,27 @@ internal fun PluginCall.resolveResult(method: String, function: () -> Any?) {
resolveDeferred(method) { callback -> callback(function(), null) }
}

internal suspend fun PluginCall.resolveSuspending(method: String, function: suspend () -> Any?) {
try {
when (val result = function()) {
is Unit -> {
this.resolve(JSObject())
}
else -> {
this.resolve(jsonMapOf("value" to result).toJSObject())
}
}
} catch (e: Exception) {
this.reject(method, e)
}
}

internal fun <T> PluginCall.resolveDeferred(method: String, function: ((T?, Exception?) -> Unit) -> Unit) {
try {
function { result, error ->
if (error != null) {
this.reject(method, error)
} else {


try {
when (result) {
is Unit -> {
Expand Down
2 changes: 1 addition & 1 deletion example/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions ios/Plugin/AirshipPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,9 @@ public class AirshipPlugin: CAPPlugin, CAPBridgedPlugin {
return nil

case "push#enableUserNotifications":
return try await AirshipProxy.shared.push.enableUserPushNotifications()
return try await AirshipProxy.shared.push.enableUserPushNotifications(
args: try call.optionalCodableArg()
)

case "push#isUserNotificationsEnabled":
return try AirshipProxy.shared.push.isUserNotificationsEnabled()
Expand Down Expand Up @@ -475,7 +477,15 @@ public class AirshipPlugin: CAPPlugin, CAPBridgedPlugin {
}

extension CAPPluginCall {
func requireCodableArg<T: Codable>() throws -> T {
func optionalCodableArg<T: Decodable>() throws -> T? {
guard let value = self.getValue("value") else {
return nil
}

return try AirshipJSON.wrap(value).decode()
}

func requireCodableArg<T: Decodable>() throws -> T {
guard let value = self.getValue("value") else {
throw AirshipErrors.error("Missing argument")
}
Expand Down
2 changes: 1 addition & 1 deletion ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def capacitor_pods
use_frameworks!
pod 'Capacitor', :path => '../node_modules/@capacitor/ios'
pod 'CapacitorCordova', :path => '../node_modules/@capacitor/ios'
pod 'AirshipFrameworkProxy', '6.3.0'
pod 'AirshipFrameworkProxy', '8.0.0'
end

target 'Plugin' do
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ua/capacitor-airship",
"version": "2.0.1",
"version": "2.1.0",
"description": "Airship capacitor plugin",
"main": "dist/plugin.cjs.js",
"module": "dist/esm/index.js",
Expand Down
8 changes: 6 additions & 2 deletions src/AirshipPush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
PushPayload,
PushReceivedEvent,
PushTokenReceivedEvent,
PromptPermissionFallback
} from './types';

/**
Expand Down Expand Up @@ -55,10 +56,13 @@ export class AirshipPush {

/**
* Enables user notifications.
* @param options Optional options.
* @returns A promise with the permission result.
*/
public enableUserNotifications(): Promise<boolean> {
return this.plugin.perform('push#enableUserNotifications');
public enableUserNotifications(options?: {
fallback?: PromptPermissionFallback
}): Promise<boolean> {
return this.plugin.perform('push#enableUserNotifications', options);
}

/**
Expand Down
46 changes: 40 additions & 6 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export interface PushReceivedEvent {
pushPayload: PushPayload;

/**
* Indicates whether the push was received when the application was in the background or foreground.
*/
* Indicates whether the push was received when the application was in the background or foreground.
*/
isForeground: boolean;
}

Expand Down Expand Up @@ -123,6 +123,42 @@ export interface PushNotificationStatus {
* is true but `isOptedIn` is false, that means push token was not able to be registered.
*/
isUserOptedIn: boolean;

/**
* The notification permission status.
*/
notificationPermissionStatus: PermissionStatus;
}

/**
* Enum of permission status.
*/
export enum PermissionStatus {
/**
* Permission is granted.
*/
Granted = 'granted',

/**
* Permission is denied.
*/
Denied = 'denied',

/**
* Permission has not yet been requested.
*/
NotDetermined = 'not_determined',
}

/**
* Fallback when prompting for permission and the permission is
* already denied on iOS or is denied silently on Android.
*/
export enum PromptPermissionFallback {
/**
* Take the user to the system settings to enable the permission.
*/
SystemSettings = "systemSettings"
}

/**
Expand Down Expand Up @@ -382,7 +418,6 @@ export namespace iOS {
}
}


export namespace Android {
/**
* Android notification config.
Expand All @@ -407,7 +442,6 @@ export namespace Android {
}
}


/**
* Airship config environment
*/
Expand Down Expand Up @@ -436,8 +470,8 @@ export interface ConfigEnvironment {
* and redacting logs with string interpolation. `public` will log all configured log levels to the console
* without redacting any of the log lines.
*/
logPrivacyLevel: "private" | "public"
}
logPrivacyLevel?: 'private' | 'public';
};
}

/**
Expand Down

0 comments on commit 3fb9231

Please sign in to comment.