OS X: How to invoke methods in containing app from safari app extension

We have an application for macOS platform. We are implementing a safari app extension for this application.


We have a requirement to invoke a method in mentioned application (containing app) from safari app extension. Currently, we are trying to achieve this using NSXPCConnection APIs.


But, shouldAcceptNewConnection method in containing app never gets invoked.


Also, when we try to invoke methods in containing app from safari app extension using proxy object, nothing happens (those methods never get called).


Can anyone please assist me to resolve this issue.

Replies

There currently aren't any APIs for a Safari App Extension to communicate with its containing app - but there are a few ways to achieve that functionality.


https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW1


See the information about "Sharing Data with Your Containing App". Another possibility would be for your app to define a URL scheme, and the extension could communicate with the containing app by opening a URL with that scheme.


What kind of communication are you hoping to achieve?

Thanks bweinstein


What kind of communication are you hoping to achieve?

I want to call methods in containing app from safari app extension.

This method should be able to return value back to the safari app extension.

Please find below the more detailed info about my issue:


I have one application (Containing App) for macOS platform.

I have implemented a safari app extension (Extension) for this application.


I am opening one url in Safari from Containing App.

While this url is opening in Safari, the script mentioned in the web page of this url invokes one method of safari app extension as mentioned below:

safari.extension.dispatchMessage("GetSomeData");


When this is method is called from the script in web page, it invokes following method of safari app extension:

- (void)messageReceivedWithName:(NSString *)messageName fromPage:(SFSafariPage *)page userInfo:(NSDictionary *)userInfo

{

NSXPCConnection *_xpcConnection = [[NSXPCConnection alloc] initWithMachServiceName:@"com.abc.mac.app" options:NSXPCConnectionPrivileged];

// I also tried initWithServiceName in above method

_xpcConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(TestProtocol)];

[_xpcConnection resume];

id _proxy = [[_xpcConnection remoteObjectProxy] retain];


if([messageName isEqualToString:@"GetSomeData"])

{

[_proxy getRequiredData];

}

}


getRequiredData method has been defined in Containing App, because the data to be returned from this method is available in only Containing App.


Containing App is listening for connections as mentioned below:

- (void)awakeFromNib

{

_xpcListener = [[NSXPCListener alloc] initWithMachServiceName:@"com.abc.mac.app"];

_xpcListener.delegate = self;

[_xpcListener resume];

}


- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {

NSLog(@"In method listener:shouldAcceptNewConnection");

newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(TestProtocol)];

newConnection.exportedObject = self;

_xpcConnection = [newConnection retain];

[newConnection resume];

return YES;

}


But this above mentioned callback (shouldAcceptNewConnection) method never gets invoked.

Also, when I try to invoke a method of containing app (getRequiredData) from safari app extension using remote proxy object, nothing happens (this method never get called).

I verified that proxy object is valid. It is not null.


Can anyone please give me some pointers on this issue.