EDIT:这是我发现/创建的一种新方法,它很有效,并且还具有首先提示用户的额外好处,可以改善应用程序的入门体验。不幸的是,原始方法(我留在这篇文章的底部)仍然提示应用程序的每个新版本的可访问性。
我必须在我的 macOS 应用程序中实现此功能,并且有另一种想法和方法来实现它,考虑到用户无论如何都需要执行它,我只需让应用程序在每次运行时显示所需的对话,并且在应用程序构建期间,我运行脚本清除现有权限。
作为参考,请参阅v1.3.0 https://github.com/othyn/macos-auto-clicker/tree/v1.3.0 of my 自动答题器 macOS 应用 https://github.com/othyn/macos-auto-clicker, 具体来说:
- Services/PermissionsService.swift(整个类) https://github.com/othyn/macos-auto-clicker/blob/v1.3.0/auto-clicker/Services/PermissionsService.swift
- Init/AppDelegate.swift(第 21 行) https://github.com/othyn/macos-auto-clicker/blob/v1.3.0/auto-clicker/Init/AppDelegate.swift#L21
- Init/AutoClickerApp.swift(第 32 和 40 行) https://github.com/othyn/macos-auto-clicker/blob/v1.3.0/auto-clicker/Init/AutoClickerApp.swift#L32
- auto-clicker.xcodeproj/project.pbxproj(第 435 行) https://github.com/othyn/macos-auto-clicker/blob/v1.3.0/auto-clicker.xcodeproj/project.pbxproj#L435
这些链接是指向标记版本的链接,因此不应更改或中断。代码有点多,我在这里总结一下。
首先,我创建了一个新类来管理与权限相关的功能,以保持上下文相关:
//
// PermissionsService.swift
// auto-clicker
//
// Created by Ben on 10/04/2022.
//
import Cocoa
final class PermissionsService: ObservableObject {
// Store the active trust state of the app.
@Published var isTrusted: Bool = AXIsProcessTrusted()
// Poll the accessibility state every 1 second to check
// and update the trust status.
func pollAccessibilityPrivileges() {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.isTrusted = AXIsProcessTrusted()
if !self.isTrusted {
self.pollAccessibilityPrivileges()
}
}
}
// Request accessibility permissions, this should prompt
// macOS to open and present the required dialogue open
// to the correct page for the user to just hit the add
// button.
static func acquireAccessibilityPrivileges() {
let options: NSDictionary = [kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true]
let enabled = AXIsProcessTrustedWithOptions(options)
}
}
然后,我将以下内容添加到我的AppDelegate
(记住这是在 Swift UI 中):
//
// AppDelegate.swift
// auto-clicker
//
// Created by Ben on 30/03/2022.
//
import Foundation
import Cocoa
final class AppDelegate: NSObject, NSApplicationDelegate {
// When the application finishes launching, request the
// accessibility permissions from the service class we
// made earlier.
func applicationDidFinishLaunching(_ notification: Notification) {
PermissionsService.acquireAccessibilityPrivileges()
}
}
最后,在您的 Swiftui 应用程序初始化中,让我们向用户添加一些 UI 反馈,告知我们正在等待权限并听取该反馈isTrusted
我们之前在权限服务类中设置的已发布属性,当用户授予所需权限时,每秒都会轮询以解锁 UI:
//
// AutoClickerApp.swift
// auto-clicker
//
// Created by Ben on 12/05/2021.
//
import Foundation
import SwiftUI
import Defaults
@main
struct AutoClickerApp: App {
// Create an instance of the permissions service class that we
// can observe for the trusted state change.
@StateObject private var permissionsService = PermissionsService()
var body: some Scene {
// Wait for trust permissions being granted from the user,
// displaying a blocking permissions view telling the user
// what to do and then presenting the main application view
// automatically when the required trust permissions are granted.
WindowGroup {
if self.permissionsService.isTrusted {
MainView()
} else {
PermissionsView()
}
.onAppear(perform: self.permissionsService.pollAccessibilityPrivileges)
}
}
}
你可以看到我在上面的应用程序中制作的阻塞视图,Views/Main/PermissionsView.swift https://github.com/othyn/macos-auto-clicker/blob/v1.3.0/auto-clicker/Views/Main/PermissionsView.swift.
然后,为了在应用程序构建期间自动清除权限,我向项目添加了一个新的构建脚本,该脚本针对以下内容运行/bin/sh
:
tccutil reset Accessibility $PRODUCT_BUNDLE_IDENTIFIER
正如所见auto-clicker.xcodeproj/project.pbxproj(第 435 行) https://github.com/othyn/macos-auto-clicker/blob/v1.3.0/auto-clicker.xcodeproj/project.pbxproj#L435.
这意味着每个应用程序构建上都会出现系统对话框提示我只需按 + 按钮并添加应用程序。
不幸的是,这是我发现的开发需要这些权限的应用程序的最无摩擦的方法。
过时的答案:
经过一番试验和错误,通过 Xcode(>11,当前 13)新构建系统导航,找到了一种方法来做到这一点。
打开 Xcode 并将其作为前台应用程序(以便它通过其菜单项接管菜单栏),执行以下操作:
- 从菜单栏中选择“Xcode”
- 如果您的项目还没有工作区,请单击列表底部附近的“另存为工作区...”,然后将工作区保存在您的项目旁边。
*.xcodeproj
所以它们应该位于同一目录中。从现在开始,您将通过新的方式打开您的项目*.xcworkspace
工作空间instead你的*.xcodeproj
项目。
- 从菜单栏中,再次选择“Xcode”
- 单击列表底部附近的“工作区设置...”
- 在“派生数据”下选择“工作空间相对位置”,如果您想自定义路径,请立即执行此操作
- 点击右下角的“完成”
这使得我们的构建位置*.app
项目中的二进制文件,因此很容易找到,同时还允许我们检查源代码管理中的更改,因为我们现在将工作区设置存储在*.xcworkspace
file.
接下来,我们现在需要将权限指向上述构建二进制文件位置,因此:
- 打开系统偏好设置
- 点击“安全与隐私”
- 单击右下角的挂锁进行更改
- 从左侧列表中选择“辅助功能”
- 单击列表左下角的加号按钮,找到
*.app
文件将其添加到我们放在项目目录中的列表中,这应该类似于$PROJECT_DIR/DerivedData/$PROJECT/Build/Products/Debug/*.app
- 如果尚未选中,请单击应用程序左侧的复选框进行选中
- 重新启动应用程序
任何构建现在都应该具有相关权限。
但要注意的是,这将覆盖任何存档/产品版本的权限,因为应用程序名称和二进制文件是相同的。不过,它们很容易添加回来,只需删除构建应用程序的权限,然后将其指向您的产品应用程序,通常在/Applications
.