mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-06-06 13:53:54 +02:00
feat(notification): implement Android and iOS APIs (#340)
This commit is contained in:
committed by
GitHub
parent
1397172e95
commit
be1c775b8d
@@ -1,24 +1,209 @@
|
||||
import UIKit
|
||||
import WebKit
|
||||
import Tauri
|
||||
import SwiftRs
|
||||
import Tauri
|
||||
import UIKit
|
||||
import UserNotifications
|
||||
import WebKit
|
||||
|
||||
enum ShowNotificationError: LocalizedError {
|
||||
case noId
|
||||
case make(Error)
|
||||
case create(Error)
|
||||
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case .noId:
|
||||
return "notification `id` missing"
|
||||
case .make(let error):
|
||||
return "Unable to make notification: \(error)"
|
||||
case .create(let error):
|
||||
return "Unable to create notification: \(error)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func showNotification(invoke: Invoke, notification: JSObject)
|
||||
throws -> UNNotificationRequest
|
||||
{
|
||||
guard let identifier = notification["id"] as? Int else {
|
||||
throw ShowNotificationError.noId
|
||||
}
|
||||
|
||||
var content: UNNotificationContent
|
||||
do {
|
||||
content = try makeNotificationContent(notification)
|
||||
} catch {
|
||||
throw ShowNotificationError.make(error)
|
||||
}
|
||||
|
||||
var trigger: UNNotificationTrigger?
|
||||
|
||||
do {
|
||||
if let schedule = notification["schedule"] as? JSObject {
|
||||
try trigger = handleScheduledNotification(schedule)
|
||||
}
|
||||
} catch {
|
||||
throw ShowNotificationError.create(error)
|
||||
}
|
||||
|
||||
// Schedule the request.
|
||||
let request = UNNotificationRequest(
|
||||
identifier: "\(identifier)", content: content, trigger: trigger
|
||||
)
|
||||
|
||||
let center = UNUserNotificationCenter.current()
|
||||
center.add(request) { (error: Error?) in
|
||||
if let theError = error {
|
||||
invoke.reject(theError.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
class NotificationPlugin: Plugin {
|
||||
@objc public func requestPermission(_ invoke: Invoke) throws {
|
||||
invoke.resolve(["permissionState": "granted"])
|
||||
}
|
||||
let notificationHandler = NotificationHandler()
|
||||
let notificationManager = NotificationManager()
|
||||
|
||||
@objc public func permissionState(_ invoke: Invoke) throws {
|
||||
invoke.resolve(["permissionState": "granted"])
|
||||
}
|
||||
override init() {
|
||||
super.init()
|
||||
notificationManager.notificationHandler = notificationHandler
|
||||
notificationHandler.plugin = self
|
||||
}
|
||||
|
||||
@objc public func show(_ invoke: Invoke) throws {
|
||||
let request = try showNotification(invoke: invoke, notification: invoke.data)
|
||||
notificationHandler.saveNotification(request.identifier, invoke.data)
|
||||
invoke.resolve([
|
||||
"id": Int(request.identifier) ?? -1
|
||||
])
|
||||
}
|
||||
|
||||
@objc public func batch(_ invoke: Invoke) throws {
|
||||
guard let notifications = invoke.getArray("notifications", JSObject.self) else {
|
||||
invoke.reject("`notifications` array is required")
|
||||
return
|
||||
}
|
||||
var ids = [Int]()
|
||||
|
||||
for notification in notifications {
|
||||
let request = try showNotification(invoke: invoke, notification: notification)
|
||||
notificationHandler.saveNotification(request.identifier, notification)
|
||||
ids.append(Int(request.identifier) ?? -1)
|
||||
}
|
||||
|
||||
invoke.resolve([
|
||||
"notifications": ids
|
||||
])
|
||||
}
|
||||
|
||||
@objc public override func requestPermissions(_ invoke: Invoke) {
|
||||
notificationHandler.requestPermissions { granted, error in
|
||||
guard error == nil else {
|
||||
invoke.reject(error!.localizedDescription)
|
||||
return
|
||||
}
|
||||
invoke.resolve(["permissionState": granted ? "granted" : "denied"])
|
||||
}
|
||||
}
|
||||
|
||||
@objc public override func checkPermissions(_ invoke: Invoke) {
|
||||
notificationHandler.checkPermissions { status in
|
||||
let permission: String
|
||||
|
||||
switch status {
|
||||
case .authorized, .ephemeral, .provisional:
|
||||
permission = "granted"
|
||||
case .denied:
|
||||
permission = "denied"
|
||||
case .notDetermined:
|
||||
permission = "default"
|
||||
@unknown default:
|
||||
permission = "default"
|
||||
}
|
||||
|
||||
invoke.resolve(["permissionState": permission])
|
||||
}
|
||||
}
|
||||
|
||||
@objc func cancel(_ invoke: Invoke) {
|
||||
guard let notifications = invoke.getArray("notifications", NSNumber.self),
|
||||
notifications.count > 0
|
||||
else {
|
||||
invoke.reject("`notifications` input is required")
|
||||
return
|
||||
}
|
||||
|
||||
UNUserNotificationCenter.current().removePendingNotificationRequests(
|
||||
withIdentifiers: notifications.map({ (id) -> String in
|
||||
return id.stringValue
|
||||
})
|
||||
)
|
||||
invoke.resolve()
|
||||
}
|
||||
|
||||
@objc func getPending(_ invoke: Invoke) {
|
||||
UNUserNotificationCenter.current().getPendingNotificationRequests(completionHandler: {
|
||||
(notifications) in
|
||||
let ret = notifications.compactMap({ [weak self] (notification) -> JSObject? in
|
||||
return self?.notificationHandler.makePendingNotificationRequestJSObject(notification)
|
||||
})
|
||||
|
||||
invoke.resolve([
|
||||
"notifications": ret
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
@objc func registerActionTypes(_ invoke: Invoke) throws {
|
||||
guard let types = invoke.getArray("types", JSObject.self) else {
|
||||
return
|
||||
}
|
||||
try makeCategories(types)
|
||||
invoke.resolve()
|
||||
}
|
||||
|
||||
@objc func removeActive(_ invoke: Invoke) {
|
||||
if let notifications = invoke.getArray("notifications", JSObject.self) {
|
||||
let ids = notifications.map { "\($0["id"] ?? "")" }
|
||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ids)
|
||||
invoke.resolve()
|
||||
} else {
|
||||
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
|
||||
DispatchQueue.main.async(execute: {
|
||||
UIApplication.shared.applicationIconBadgeNumber = 0
|
||||
})
|
||||
invoke.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func getActive(_ invoke: Invoke) {
|
||||
UNUserNotificationCenter.current().getDeliveredNotifications(completionHandler: {
|
||||
(notifications) in
|
||||
let ret = notifications.map({ (notification) -> [String: Any] in
|
||||
return self.notificationHandler.makeNotificationRequestJSObject(
|
||||
notification.request)
|
||||
})
|
||||
invoke.resolve([
|
||||
"notifications": ret
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
@objc func createChannel(_ invoke: Invoke) {
|
||||
invoke.reject("not implemented")
|
||||
}
|
||||
|
||||
@objc func deleteChannel(_ invoke: Invoke) {
|
||||
invoke.reject("not implemented")
|
||||
}
|
||||
|
||||
@objc func listChannels(_ invoke: Invoke) {
|
||||
invoke.reject("not implemented")
|
||||
}
|
||||
|
||||
@objc public func notify(_ invoke: Invoke) throws {
|
||||
// TODO
|
||||
invoke.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
@_cdecl("init_plugin_notification")
|
||||
func initPlugin(name: SRString, webview: WKWebView?) {
|
||||
Tauri.registerPlugin(webview: webview, name: name.toString(), plugin: NotificationPlugin())
|
||||
func initPlugin() -> Plugin {
|
||||
return NotificationPlugin()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user