Как получать уведомления от AXObserver с помощью swift 5 - PullRequest
0 голосов
/ 28 июня 2019

Я использую API AXUIElement для управления другим приложением на моем Mac. Я хотел бы получать уведомления, когда этим приложением открывается новое окно.

Прежде всего, я добавил свое приложение в список приложений, которые могут управлять моим компьютером, в настройках конфиденциальности в системных настройках и отключил изолированную программную среду приложений в XCode. Я уже могу делать такие вещи, как перемещение приложения по экрану или нажатие кнопок в приложении.

У меня есть то, что я считаю полным набором для создания наблюдателя и назначения уведомлений. Однако, когда я запускаю программу, я не получаю никаких уведомлений или ошибок инициализации.

Вот с чем я работаю ...

// Use CGWindowList... to get a list of all the windows on screen.
if let windows = CGWindowListCopyWindowInfo(CGWindowListOption.optionOnScreenOnly, kCGNullWindowID) as? [[ String: Any ]] {
    for window in windows {
        if let windowOwnerName = window["kCGWindowOwnerName"]{
            if windowOwnerName as? String == "Finder"{

                // Get the pid
                let pid = window["kCGWindowOwnerPID"] as? Int32

                // Find the app
                let appRef = AXUIElementCreateApplication(pid!)

                var windows: AnyObject?
                AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute as CFString, &windows);

                 if let windowList = windows as? [AXUIElement] {

                    // Create the observer
                    var observer: AXObserver?
                    let axErr = AXObserverCreate(pid!, { (observer: AXObserver,
                        element: AXUIElement,
                        notificationName: CFString,
                        userData: UnsafeMutableRawPointer?) -> Void in

                        print("notified!")
                        print(notificationName)


                    }, &observer)

                    guard axErr == .success else {
                        print("error making observer")
                        return
                    }


                    let selfPtr = UnsafeMutableRawPointer(Unmanaged.passRetained(self).toOpaque())

                    // Add some notifications
                    addAXObserverNotification(observer!, appRef, kAXWindowCreatedNotification, selfPtr)
                    addAXObserverNotification(observer!, appRef, kAXSheetCreatedNotification, selfPtr)
                    addAXObserverNotification(observer!, appRef, kAXWindowMovedNotification, selfPtr)
                    addAXObserverNotification(observer!, appRef, kAXWindowResizedNotification, selfPtr)
                    addAXObserverNotification(observer!, appRef, kAXWindowMiniaturizedNotification, selfPtr)

                    CFRunLoopAddSource(CFRunLoopGetCurrent(), AXObserverGetRunLoopSource(observer!), .defaultMode)

                }



            }
        }
    }
}

И моя функция добавления уведомлений ...

func addAXObserverNotification(_ observer: AXObserver, _ element: AXUIElement, _ notification: String, _ refcon: UnsafeMutableRawPointer?) {
        let error = AXObserverAddNotification(observer, element, notification as CFString, refcon)
        guard error == .success || error == .notificationAlreadyRegistered else {
            print("AXObserverAddNotification error: \(notification)")
            return
        }
}

Может ли более опытный глаз указать, что я здесь делаю неправильно? Я просто использую Finder в качестве тестового приложения, но не получаю уведомлений независимо от того, какое приложение я пытаюсь посмотреть.

...