我正在寻找的文档
CFStringGetCString
AXUIElementCopyAttributeValue

CFStringGetCString接受参数buffer: UnsafeMutablePointer<Int8>!
AXUIElementCopyAttributeValue接受参数value: UnsafeMutablePointer<CFTypeRef?>

对于后者,我可以这样拨打电话:

var value: CFTypeRef?
let err = AXUIElementCopyAttributeValue(element, attribute as CFString, &value);


这满足了文档要求类型为UnsafeMutablePointerCFTypeRef的要求。

但是我无法通过执行相同的逻辑来应用

let buffer: Int8!
CFStringGetCString(attribute as! CFString, &buffer, 2048, CFStringBuiltInEncodings.UTF8.rawValue)


我也试过

let buffer: Int8?
CFStringGetCString(attribute as! CFString, &buffer!, 2048, CFStringBuiltInEncodings.UTF8.rawValue)


无论哪种方式,它都会在初始化之前抱怨使用buffer,即使它从未在具有类似参数要求的工作方法中抱怨value

我为CFStringGetCString看到的所有工作示例都在*中使用类似于Objective-c的语法。不知道这里有什么合适的快速方法。

我也尝试过这种方法来获得自己想要的价值:

let app = AXUIElementCreateSystemWide();
var valueString = "";

var value: CFTypeRef?
// An exception on execution happens here when passing app
// Passing in the element I clicked instead of app
// yields error -25205 (attributeunsupported)
let err = AXUIElementCopyAttributeValue(app, "AXFocusedApplication" as CFString, &value);
if (err == AXError.success) {
    valueString = value! as! NSString as String;
} else {
    print("ERROR!");
    print(err.rawValue);
}

return valueString;

最佳答案

为什么用CFStringGetCString折磨自己?如果您在Swift中有一个CFString,则可以将其转换为String并从中获取一个C字符串:

let cString: [Int8] = (cfString as String).cString(using: .utf8)!


另请注意,kAXFocusedApplicationAttribute的值不是CFString。这是一个AXUIElement

这是我的游乐场测试:

import Foundation
import CoreFoundation

let axSystem = AXUIElementCreateSystemWide()
var cfValue: CFTypeRef?
AXUIElementCopyAttributeValue(axSystem, kAXFocusedApplicationAttribute as CFString, &cfValue)
if let cfValue = cfValue, CFGetTypeID(cfValue) == AXUIElementGetTypeID() {
    let axFocusedApplication = cfValue
    print(axFocusedApplication)
}


我第一次执行该操场时,出现一个系统对话框,告诉我需要授予Xcode权限来控制我的计算机。我去了系统偏好设置>安全性和隐私>隐私>可访问性,在列表的底部找到了Xcode,并打开了它的复选框。

这是操场的输出:

<AXUIElement Application 0x7fb2d60001c0> {pid=30253}


我假设您使用的是macOS,因为AXUI API仅在macOS上可用。如果只想将前端应用程序的名称作为字符串,则可以执行以下操作:

if let frontAppName = NSWorkspace.shared.frontmostApplication?.localizedName {
    print(frontAppName)
}

10-08 05:24