Skip to content

v2.8.0

Latest

Choose a tag to compare

@github-actions github-actions released this 29 Jul 18:17

Full Changelog: https://github.com/jaywcjlove/PermissionFlow/commits/v2.8.0

  • .calendars: Requests calendar authorization and opens Privacy & Security > Calendars. ✅ Status Detection Supported (no floating panel; host Info.plist required)
  • .reminders: Requests reminders authorization and opens Privacy & Security > Reminders. ✅ Status Detection Supported (no floating panel; host Info.plist required)
PermissionFlowButton(title: "Calendars", pane: .calendars)
PermissionFlowButton(title: "Reminders", pane: .reminders)

Manual Reminders authorization

Same flow as Calendars, with RemindersPermissionStatusProvider and the Reminders settings pane. Host setup first (see Reminders).

import AppKit
import PermissionFlow
import SystemSettingsKit
import SwiftUI

struct ManualRemindersPermissionView: View {
    @State private var authorizationState: PermissionAuthorizationState = .checking

    private let didBecomeActive = NotificationCenter.default.publisher(
        for: NSApplication.didBecomeActiveNotification
    )

    var body: some View {
        Button {
            requestRemindersAccess()
        } label: {
            let buttonState = PermissionFlowButtonState.make(from: authorizationState)
            Label(title(for: authorizationState), systemImage: buttonState.systemImage)
                .foregroundStyle(buttonState.isGranted ? .green : .primary)
        }
        .onAppear(perform: refreshStatus)
        .onReceive(didBecomeActive) { _ in
            refreshStatus()
        }
    }

    private func refreshStatus() {
        authorizationState = PermissionStatusRegistry
            .provider(for: .reminders)
            .authorizationState()

        // Or:
        // authorizationState = RemindersPermissionStatusProvider().authorizationState()
    }

    private func requestRemindersAccess() {
        authorizationState = .checking

        RemindersPermissionStatusProvider().requestAuthorization { state in
            Task { @MainActor in
                authorizationState = state
                SystemSettings.open(.privacy(anchor: .privacyReminders))
                // Equivalent:
                // PermissionFlow.makeController().authorize(pane: .reminders)
            }
        }
    }

    private func title(for state: PermissionAuthorizationState) -> String {
        switch state {
        case .granted:
            "Granted"
        case .notGranted:
            "Request Reminders"
        case .unknown:
            "Open Reminders Settings"
        case .checking:
            "Checking..."
        }
    }
}

Minimal non-UI version:

import PermissionFlow
import SystemSettingsKit

func openRemindersPermission() {
    RemindersPermissionStatusProvider().requestAuthorization { _ in
        DispatchQueue.main.async {
            SystemSettings.open(.privacy(anchor: .privacyReminders))
        }
    }
}

func isRemindersGranted() -> Bool {
    RemindersPermissionStatusProvider().hasFullAccess()
}