列出Swift中的所有窗口名称

问题描述 投票:-2回答:2

我正在学习斯威夫特。如何修复以下代码以列出窗口名称?

import CoreGraphics

let windows = CGWindowListCopyWindowInfo(CGWindowListOption.optionAll, kCGNullWindowID)
for i in 0..<CFArrayGetCount(windows) {
  if let window = CFArrayGetValueAtIndex(windows, i) {
    print(CFDictionaryGetValue(window, kCGWindowName))
  }
}

错误:

main.swift:6:32: error: cannot convert value of type 'UnsafeRawPointer' to expected argument type 'CFDictionary?'
    print(CFDictionaryGetValue(window, kCGWindowName))
                               ^~~~~~
                                      as! CFDictionary
swift macos core-graphics
2个回答
2
投票

如果您避免使用Core Foundation类型和方法,并且尽可能早地将值桥接到本机Swift类型,则会变得更容易。

在这里,CGWindowListCopyWindowInfo()返回CFArray的可选CFDictionaries,并且可以桥接到相应的Swift类型[[String : Any]]。然后,您可以使用通常的Swift方法(数组枚举和字典下标)访问其值:

if let windowInfo = CGWindowListCopyWindowInfo(.optionAll, kCGNullWindowID) as? [[ String : Any]] {
    for windowDict in windowInfo {
        if let windowName = windowDict[kCGWindowName as String] as? String {
            print(windowName)
        }
    }
}

1
投票

您可以使用unsafeBitCast(_:to:)将不透明的原始指针转换为CFDictionary。请注意,您还需要将第二个参数转换为原始指针:

CFDictionaryGetValue(unsafeBitCast(window, to: CFDictionary.self), unsafeBitCast(kCGWindowName, to: UnsafeRawPointer.self))

unsafeBitCast(_:to:)告诉编译器将该变量视为另一种类型,但它不是非常安全(因此unsafe前缀),建议阅读文档以获取更多详细信息,尤其是以下注释:

警告

调用此函数会破坏Swift类型系统的保证;小心使用。

在您的特定情况下,使用该函数应该没有任何问题,因为您正在使用适当的类型,如您正在调用的Foundation函数的文档中所声明的那样。

完整,可行的代码可能如下所示:

import CoreGraphics

let windows = CGWindowListCopyWindowInfo(CGWindowListOption.optionAll, kCGNullWindowID)
for i in 0..<CFArrayGetCount(windows) {
    let windowDict = unsafeBitCast(CFArrayGetValueAtIndex(windows, i), to: CFDictionary.self)
    let rawWindowNameKey = unsafeBitCast(kCGWindowName, to: UnsafeRawPointer.self)
    let rawWindowName = CFDictionaryGetValue(windowDict, rawWindowNameKey)
    let windowName = unsafeBitCast(rawWindowName, to: CFString?.self) as String?
    print(windowName ?? "")
}
© www.soinside.com 2019 - 2024. All rights reserved.