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?
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?
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):
(The Turn on Accessibility
button simply opens the System Preferences to the correct place, as mentioned above)
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)
}
}