1

Can an AXObserverCallback be converted to Swift? The problem I am having seems to be with the void* which I know is not a valid type in Swift.

I am attempting to convert Obj-C code to Swift and I am unable to get the code to compile. I am uncertain if the AXObserverCallback can be converted or not. The Objective-C declaration is:

typedef void (*AXObserverCallback)( AXObserverRef observer, AXUIElementRef element, CFStringRef notification, void *refcon);

There is no Swift declaration for AXObserverCallback. The other relevant function for setting up an AXObserver is AXObserverCreate, for which there are declarations for both Obj-C and Swift.

A simplified version of the working Obj-C code is:

- (AXError)installWindowCreatedAXObserver { 
    pid_t pid = 0;
    AXObserverRef observer = NULL; 
    AXError axErr = AXObserverCreate(pid, windowCreatedCallback, &observer); 
    return axErr; 
}

void windowCreatedCallback(AXObserverRef observer, AXUIElementRef element, CFStringRef notificationName, void *refCon) { 
    NSLog(@"windowCreatedCallback"); 
} 

My attempt to convert to Swift is:

func installWindowCreatedAXObserver() -> AXError { 
    let pid:pid_t = 0; 
    var observer: AXObserverRef; 
    var axErr:AXError = AXObserverCreate(application:pid, callback:windowCreatedCallback, outObserver:&observer); 
    return axErr; 
} 

func windowCreatedCallback(observer:AXObserverRef, element:AXUIElementRef, notificationName:CFStringRef, refcon:void*) -> Void { 
    println("windowCreatedCallback"); 
} 

The initial error with the above Swift code is at windowCreatedCallback and says "Expected ',' separator". I know this error is due to the void* which is not a type in Swift.

I have tried changing the void* to: voidPtr, UnsafePointer<AnyObject>, UnsafeMutablePointer<Void>, and AnyObject. None of these correct the error. When I use anything except void*, then the error moves to the AXObserverCreate call as "Cannot convert the expression's type to type AXError".

So, although I realize I cannot use void*, the declaration for the callback is only in Obj-C and it uses a void*. It seems odd that there is not a Swift declaration for AXObserverCallback yet there is for AXObserverCreate.

I have researched the issue and have been unable to resolve the problem. I understand that the Swift callback I am attempting to use does not have a declaration, but when I try to use the Obj-C declaration format, that does not work because AXObserverCreate does not see the callback function.

Any assistance would be greatly appreciated!

RGB World
  • 399
  • 1
  • 6
  • 19

2 Answers2

2

For those coming across this in the future, I needed to change a few things to work with Swift 5.

var observer: AXObserver? 
let axErr = AXObserverCreate(pid, { (observer: AXObserver, element: AXUIElement, notificationName: CFString, refcon: UnsafeMutableRawPointer?) -> Void in print(notificationName) }, &observer)
aferriss
  • 914
  • 9
  • 20
1

It seems that closures work (tested with Swift 2.2):

let axErr = AXObserverCreate(pid, { (observer: AXObserver, element: AXUIElement, notificationName: CFString, refcon: UnsafeMutablePointer<Void>) -> Void in
    print(notificationName)
}, &observer)
olivier
  • 1,007
  • 8
  • 14