10

The below code doesn't work since Mojave without Accessibility permission

KeyMap keyStatesBig; GetKeys(keyStatesBig);

But is there a key to put in info.plist to ask users permission on app launch?

2 Answers2

9

It's not possible with the info.plist.

You can ask the user yourself, on startup. Use AXIsProcessTrusted to determine whether accessibility is enabled or not.

If it's not enabled, you can show a dialog asking the user to switch it on.

You can open the relevant preferences for the user also:

NSString* prefPage = @"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility";
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:prefPage]];

See how Dropbox does it (this is custom UI):

enter image description here

(The Turn on Accessibility button simply opens the System Preferences to the correct place, as mentioned above)

TheNextman
  • 12,428
  • 2
  • 36
  • 75
1

2022, swift, SwiftUI samples

To check that app have Accessability permission:

var a = AXIsProcessTrusted()

To open Accessability window properties you should use ( More details here ):

NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility")!)

custom modifier:

import Foundation
import SwiftUI
import Combine

@available(OSX 11.0, *)
public extension View {
    func checkAccessability(interval: TimeInterval, access: Binding<Bool>) -> some View {
        self.modifier( AccessabilityCheckMod(interval: interval, access: access) )
    }
    
    func checkAcessabilityOnAppear(access: Binding<Bool>) -> some View {
        self.onAppear{
            access.wrappedValue = AXIsProcessTrusted()
        }
    }
}

@available(OSX 11.0, *)
public struct AccessabilityCheckMod: ViewModifier {
    let timer: Publishers.Autoconnect<Timer.TimerPublisher>
    @Binding var access: Bool
    
    init(interval: TimeInterval, access: Binding<Bool>) {
        self.timer = Timer.publish(every: interval, on: .current, in: .common).autoconnect()
        _access = access
    }
    
    public func body(content: Content) -> some View {
        content
            .onReceive(timer) { _ in
                let privAccess = AXIsProcessTrusted()
                
                if self.access != privAccess {
                    self.access = privAccess
                }
            }
    }
}

Sample of use in SwiftUI:

struct AccesibilityCheckView: View {
    @State var access = false

    var body: some View {
        VStack{ 
            Text("AccessabilityAccess: \(access)")

            Button("Open AccessabilityConfig") {
                 NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility")!)
            }
        }
        .checkAccessability(interval: 1, access: $access)
    }
}
Andrew_STOP_RU_WAR_IN_UA
  • 9,318
  • 5
  • 65
  • 101