How do I communicate between system extension and app ?

I have my app in Objective C and system extension written in C. How do I communicate between system extension and app ?

Accepted Reply

Thanks eskimo. Do you have any template which does the same ?

Add a Comment

Replies

The standard approach is to have your Endpoint Security system extension publish an XPC service and then have the client app communicate with that service over XPC. If your system extension is written in C then you can either:

  • Use the low-level XPC API directly. See the xpc man page for details.

  • Create a separate Objective-C (or Swift) subsystem to handle the XPC and then use the higher-level NSXPCConnection API.

Either way, you must set the NSEndpointSecurityMachServiceName property in your Info.plist so that the system let’s it publish the XPC service. See the EndpointSecurity man page for the details.

Share and Enjoy

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

  • Hi Eskimo, I tried low level XPC API. Here is the sample code.

    ``init_dispatch_queue();

    xpc_main(handler); es_client_t *client; es_new_client_result_t result = es_new_client(&client, ^(es_client_t *c, const es_message_t *msg) { handle_event(c, msg); }); if (result != ES_NEW_CLIENT_RESULT_SUCCESS) { os_log_error(OS_LOG_DEFAULT, "Failed to create the ES client: %d", result); return 1; } es_event_type_t events[] = { ES_EVENT_TYPE_AUTH_EXEC, ES_EVENT_TYPE_AUTH_OPEN }; if (es_subscribe(client, events, sizeof(events) / sizeof(events[0])) != ES_RETURN_SUCCESS) { os_log_error(OS_LOG_DEFAULT, "Failed to subscribe to events"); es_delete_client(client); return 1; } dispatch_main();``

    xpc_main() function internally calls dispatch_main. Other extension code didn't execute. I added XPCService dict in info.plist and added RunLoopType as NSRunLoop as given in link. But it still don't work well.

    If I use NSXPCListner that allows extension to function. I can't use this as pyobjc do not support block calls.

    `ServiceDelegate *delegate = [ServiceDelegate new];

    NSXPCListener *listener = [NSXPCListener serviceListener];

        listener.delegate = delegate;

        [listener resume];`

    Can we make low level xpc_main() to execute in second thread and not block extension.

Add a Comment

Thanks eskimo. Do you have any template which does the same ?

Add a Comment

Also what do you mean by subsystem

You said that your ES sysex is written entirely in C. C code cannot use NSXPCConnection directly — that API is only usable from Objective-C [1] [2] — so you’d have to:

  • Write the NSXPCConnection in Objective-C.

  • Have that export its functionality via a C interface so that the rest of your ES sysex can use it.

Share and Enjoy

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

[1] And Swift, but only through Swift’s Objective-C compatibility features.

[2] Oh, and technically you can interact with any Objective-C API from C using the Objective-C runtime, but that’s so not fun.

Here is the sample code.

I’m sorry but the formatting on your comment makes it effectively unreadable. I think it’d be better for you to start a new thread with you specific details. Feel free to reference this thread in your post.

Share and Enjoy

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