ios_local_notification 1.0.1

Send local notifications on iOS.
Documentation
import Foundation
import SwiftRs
import UserNotifications

// sorry for the shitty code I am no swift developer...

// MARK: - Permissions

// Request default permission (all options)
@_cdecl("request_notification_permission_default")
public func request_notification_permission_default() {
    UNUserNotificationCenter.current().requestAuthorization(
        options: [.alert, .sound, .badge, .carPlay, .criticalAlert, .provisional]
    ) { _, error in
        if let error = error {
            print("❌ Permission error: \(error.localizedDescription)")
        }
    }
}

// Request custom permission (pass bitmask from Rust)
@_cdecl("request_notification_permission")
public func request_notification_permission(_ options: Int32) {
    var opts: UNAuthorizationOptions = []
    if options & 1 != 0 { opts.insert(.alert) }
    if options & 2 != 0 { opts.insert(.sound) }
    if options & 4 != 0 { opts.insert(.badge) }
    if options & 8 != 0 { opts.insert(.carPlay) }
    if options & 16 != 0 { opts.insert(.criticalAlert) }
    if options & 32 != 0 { opts.insert(.provisional) }

    UNUserNotificationCenter.current().requestAuthorization(options: opts) { _, error in
        if let error = error {
            print("❌ Permission error: \(error.localizedDescription)")
        }
    }
}

// MARK: - Scheduling

@_cdecl("schedule_notification")
public func schedule_notification(
    _ id: SRString, _ title: SRString, _ body: SRString, _ seconds: Int
) {
    let content = UNMutableNotificationContent()
    content.title = title.toString()
    content.body = body.toString()
    content.sound = .default

    let trigger = UNTimeIntervalNotificationTrigger(
        timeInterval: TimeInterval(seconds), repeats: false)
    let request = UNNotificationRequest(
        identifier: id.toString(), content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}

@_cdecl("schedule_repeat_notification")
public func schedule_repeat_notification(
    _ id: SRString, _ title: SRString, _ body: SRString, _ seconds: Int
) {
    let content = UNMutableNotificationContent()
    content.title = title.toString()
    content.body = body.toString()
    content.sound = .default

    let trigger = UNTimeIntervalNotificationTrigger(
        timeInterval: TimeInterval(seconds), repeats: true)
    let request = UNNotificationRequest(
        identifier: id.toString(), content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}

// MARK: - Attachments

@_cdecl("schedule_image_notification")
public func schedule_image_notification(
    _ id: SRString, _ title: SRString, _ body: SRString, _ image: SRString, _ seconds: Int
) {
    let content = UNMutableNotificationContent()
    content.title = title.toString()
    content.body = body.toString()
    content.sound = .default

    if let url = Bundle.main.url(forResource: image.toString(), withExtension: "png") {
        if let attachment = try? UNNotificationAttachment(
            identifier: "image", url: url, options: nil)
        {
            content.attachments = [attachment]
        }
    }

    let trigger = UNTimeIntervalNotificationTrigger(
        timeInterval: TimeInterval(seconds), repeats: false)
    let request = UNNotificationRequest(
        identifier: id.toString(), content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}

// MARK: - Management

@_cdecl("remove_all_pending_notifications")
public func remove_all_pending_notifications() {
    UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
}

@_cdecl("remove_all_delivered_notifications")
public func remove_all_delivered_notifications() {
    UNUserNotificationCenter.current().removeAllDeliveredNotifications()
}

@_cdecl("remove_notification_by_id")
public func remove_notification_by_id(_ id: SRString) {
    UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [
        id.toString()
    ])
    UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [id.toString()]
    )
}

@_cdecl("get_pending_notifications")
public func get_pending_notifications() -> SRObjectArray {
    let semaphore = DispatchSemaphore(value: 0)
    var results: [NotificationRequest] = []

    UNUserNotificationCenter.current().getPendingNotificationRequests { requests in
        for r in requests {
            results.append(NotificationRequest(from: r))
        }
        semaphore.signal()
    }

    semaphore.wait()
    return SRObjectArray(results)
}

@_cdecl("get_delivered_notifications")
public func get_delivered_notifications() -> SRObjectArray {
    let semaphore = DispatchSemaphore(value: 0)
    var results: [NotificationRequest] = []

    UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
        for r in notifications {
            results.append(NotificationRequest(from: r.request))
        }
        semaphore.signal()
    }

    semaphore.wait()
    return SRObjectArray(results)
}

@objc
public class NotificationRequest: NSObject {
    private let _identifier: SRString
    private let _title: SRString
    private let _subtitle: SRString
    private let _body: SRString

    // Init from UNNotificationRequest
    @objc public init(from request: UNNotificationRequest) {
        self._identifier = SRString(request.identifier)
        self._title = SRString(request.content.title)
        self._subtitle = SRString(request.content.subtitle)
        self._body = SRString(request.content.body)
    }
}