XPC: Can an NSXPCInterface have a throwing method?

I can't seem to find any references to this in the docs, which is odd because it seems like it would be a fairly common consideration.

When defining an NSXPCInterface for an object to be proxied, can XPC support methods that throw exceptions - coding and passing those exceptions back to the peer?

Given NSError does not implement NSSecureCoding, I can't see how it would work. But perhaps there is some other approach I don't know about.

And assuming there is no support for propagating exceptions across XPC, how does one typically handle the need to return errors from XPC interfaces?

Accepted Reply

Not really. XPC methods are either one-way or async:

  • In the one-way case there’s no response that could throw. The only thing that can fail is sending the message, and that’s handled by the error handler you pass to -remoteObjectProxyWithErrorHandler.

  • In the async case, you supply a reply block. That reply block can handle multiple parameters, and it’s common to include an NSError parameter in that list.

Given NSError does not implement NSSecureCoding

While that’s true, NSXPCConnection has special magic for the pattern discussed above.

All of the above assumes you’re using Objective-C or the Objective-C view of the protocol from Swift. If you’re using a sufficiently modern version of Swift it will automatically provide both a reply block and async variant of your XPC protocol method. For example, if you have this method in your protocol:

- (void)asyncVarnishWithFinish:(NSString *)finish completionHandler:(void (^)(NSError * _Nullable error))completionHandler;

Swift will give you these two variants:

func asyncVarnish(withFinish finish: String, completionHandler: @escaping (Error?) -> Void)

func asyncVarnish(withFinish finish: String) async throws

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Replies

Not really. XPC methods are either one-way or async:

  • In the one-way case there’s no response that could throw. The only thing that can fail is sending the message, and that’s handled by the error handler you pass to -remoteObjectProxyWithErrorHandler.

  • In the async case, you supply a reply block. That reply block can handle multiple parameters, and it’s common to include an NSError parameter in that list.

Given NSError does not implement NSSecureCoding

While that’s true, NSXPCConnection has special magic for the pattern discussed above.

All of the above assumes you’re using Objective-C or the Objective-C view of the protocol from Swift. If you’re using a sufficiently modern version of Swift it will automatically provide both a reply block and async variant of your XPC protocol method. For example, if you have this method in your protocol:

- (void)asyncVarnishWithFinish:(NSString *)finish completionHandler:(void (^)(NSError * _Nullable error))completionHandler;

Swift will give you these two variants:

func asyncVarnish(withFinish finish: String, completionHandler: @escaping (Error?) -> Void)

func asyncVarnish(withFinish finish: String) async throws

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"