如何在 swift 中正确使用 CFStringGetCString?
How to properly use CFStringGetCString in swift?
我正在查看文档
CFStringGetCString
和 AXUIElementCopyAttributeValue.
CFStringGetCString
接受参数 buffer: UnsafeMutablePointer<Int8>!
AXUIElementCopyAttributeValue
接受参数 value: UnsafeMutablePointer<CFTypeRef?>
对于后者,我可以这样调用:
var value: CFTypeRef?
let err = AXUIElementCopyAttributeValue(element, attribute as CFString, &value);
这满足文档要求 CFTypeRef
类型的 UnsafeMutablePointer
。
但是我无法通过
获得相同的逻辑来应用
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 类似于 *
的语法。不确定这里的正确 swift 方法是什么。
我也试过这种方式得到我想要的值:
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)
}
我第一次执行这个 playground 时,出现了一个系统对话框,告诉我需要授予 Xcode 权限才能控制我的计算机。我转到系统偏好设置 > 安全和隐私 > 隐私 > 辅助功能,在列表底部找到 Xcode,然后打开它的复选框。
这是 playground 的输出:
<AXUIElement Application 0x7fb2d60001c0> {pid=30253}
我假设您使用的是 macOS,因为 AXUI API 仅在 macOS 上可用。如果你只是想把前台应用的名称作为一个字符串,你可以这样做:
if let frontAppName = NSWorkspace.shared.frontmostApplication?.localizedName {
print(frontAppName)
}
我正在查看文档 CFStringGetCString 和 AXUIElementCopyAttributeValue.
CFStringGetCString
接受参数 buffer: UnsafeMutablePointer<Int8>!
AXUIElementCopyAttributeValue
接受参数 value: UnsafeMutablePointer<CFTypeRef?>
对于后者,我可以这样调用:
var value: CFTypeRef?
let err = AXUIElementCopyAttributeValue(element, attribute as CFString, &value);
这满足文档要求 CFTypeRef
类型的 UnsafeMutablePointer
。
但是我无法通过
获得相同的逻辑来应用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 类似于 *
的语法。不确定这里的正确 swift 方法是什么。
我也试过这种方式得到我想要的值:
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)
}
我第一次执行这个 playground 时,出现了一个系统对话框,告诉我需要授予 Xcode 权限才能控制我的计算机。我转到系统偏好设置 > 安全和隐私 > 隐私 > 辅助功能,在列表底部找到 Xcode,然后打开它的复选框。
这是 playground 的输出:
<AXUIElement Application 0x7fb2d60001c0> {pid=30253}
我假设您使用的是 macOS,因为 AXUI API 仅在 macOS 上可用。如果你只是想把前台应用的名称作为一个字符串,你可以这样做:
if let frontAppName = NSWorkspace.shared.frontmostApplication?.localizedName {
print(frontAppName)
}