macOS和XCode中开发的可访问性权限

Bog*_*dan 7 permissions macos xcode swift

有没有一种方法可以在开发过程中默认授予我正在使用XCode可访问性开发的应用程序权限。我的想法是,我可以按运行键并测试新代码,而不必跳过设置中的障碍。显然,对于部署而言,它是行不通的,但是对于开发而言,有没有一种方法可以将应用程序白名单?

Oth*_*hyn 4

编辑:这是我发现/创建的一种新方法,它正在发挥作用,并且还具有首先提示用户的额外好处,从而改善应用程序的入门体验。不幸的是,原始方法(我留在这篇文章的底部)仍然提示应用程序的每个新版本的可访问性。

我必须在我的 macOS 应用程序中实现此功能,并且有另一种想法和方法来实现它,考虑到用户无论如何都需要执行它,我只需让应用程序在每次运行时显示所需的对话,并且在应用程序构建期间,我运行脚本清除现有权限。

有关参考,请参阅我的Auto Clicker macOS 应用程序v1.3.0,具体如下:

这些链接是指向标记版本的链接,因此不应更改或中断。代码有点多,我在这里总结一下。

首先,我创建了一个新类来管理与权限相关的功能,以保持上下文相关:

//
//  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)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我将以下内容添加到我的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()
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,在我们的 Swift UI 应用程序 init 中,让我们向用户添加一些 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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以看到我在上面的应用程序中制作的阻塞视图Views/Main/PermissionsView.swift

然后,为了在应用程序构建期间自动清除权限,我向项目添加了一个新的构建脚本,该脚本运行以下命令/bin/sh

tccutil reset Accessibility $PRODUCT_BUNDLE_IDENTIFIER
Run Code Online (Sandbox Code Playgroud)

如auto-clicker.xcodeproj/project.pbxproj (第 435 行)所示。

这意味着每个应用程序构建上都会出现系统对话框提示我只需按 + 按钮并添加应用程序。

不幸的是,这是我发现的开发需要这些权限的应用程序的最无摩擦的方法。


过时的答案:

经过一番试验和错误,通过 Xcode(>11,当前 13)新构建系统导航,找到了一种方法来做到这一点。

打开 Xcode 并将其作为前台应用程序(以便它通过其菜单项接管菜单栏),执行以下操作:

  1. 从菜单栏中选择“Xcode”
  2. 如果您的项目还没有工作区,请单击列表底部附近的“另存为工作区...”,并将工作区与您的项目一起保存,*.xcodeproj以便它们应位于同一目录中。从现在开始,您将通过新的*.xcworkspace工作区而不是您的*.xcodeproj项目打开您的项目。
  3. 从菜单栏中,再次选择“Xcode”
  4. 单击列表底部附近的“工作区设置...”
  5. 在“派生数据”下选择“工作空间相对位置”,如果您想自定义路径,请立即执行此操作
  6. 点击右下角的“完成”

这会将二进制文件的构建位置*.app放在项目中,以便于查找,同时还允许我们将更改签入源代码管理,因为我们现在已将工作区设置存储在文件中*.xcworkspace

接下来,我们现在需要将权限指向上述构建二进制文件位置,因此:

  1. 打开系统偏好设置
  2. 点击“安全与隐私”
  3. 单击右下角的挂锁进行更改
  4. 从左侧列表中选择“辅助功能”
  5. 单击列表左下角的加号按钮,找到该*.app文件将其添加到我们放在项目目录中的列表中,这应该类似于$PROJECT_DIR/DerivedData/$PROJECT/Build/Products/Debug/*.app
  6. 如果尚未选中,请单击应用程序左侧的复选框进行选中
  7. 重新启动应用程序

任何构建现在都应该具有相关权限。

但要注意的是,这将覆盖任何存档/产品版本的权限,因为应用程序名称和二进制文件是相同的。不过,它们很容易添加回来,只需删除构建应用程序的权限,然后将其指向您的产品应用程序,通常在/Applications.