Skip to content

Instantly share code, notes, and snippets.

@AlanQuatermain
Created July 30, 2012 19:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlanQuatermain/3209230 to your computer and use it in GitHub Desktop.
Save AlanQuatermain/3209230 to your computer and use it in GitHub Desktop.
@protocol APRemoteAddressBook <NSObject>
- (void) allPeople: (void (^)(NSArray *, NSError *)) reply;
- (void) mailingAddressesForPersonWithIdentifier: (NSString *) identifier
reply: (void (^)(NSArray *, NSError *)) reply;
- (void) emailAddressesForPersonWithIdentifier: (NSString *) identifier
reply: (void (^)(NSArray *, NSError *)) reply;
- (void) phoneNumbersForPersonWithIdentifier: (NSString *) identifier
reply: (void (^)(NSArray *, NSError *)) reply;
@end
@protocol APRemoteCommandHandler <NSObject>
- (void) handleCommand: (NSDictionary *) command
returningResult: (void (^)(NSDictionary *packagedResult)) handler;
@end
@protocol APRemoteAddressBookBrowser <NSObject>
- (void) setCommandHandler: (id<APRemoteCommandHandler>) commandHandler
errorHandler: (void (^)(NSError *)) errorHandler;
- (void) availableServiceNames: (void (^)(NSArray *, NSError *)) reply;
- (void) connectToServiceWithName: (NSString *) name
replyHandler: (void (^)(id<APRemoteAddressBook>, NSError *)) replyHandler;
@end
@interface APRemoteAddressBook : NSObject <APRemoteAddressBook>
// ...
@end
@interface APRemoteAddressBookBrowser : NSObject <APRemoteAddressBookBrowser>
// ...
@end
@implementation APRemoteAddressBookBrowser
// ...
- (void) connectToServiceWithName: (NSString *) name
replyHandler: (void (^)(id<APRemoteAddressBook>, NSError *)) replyHandler
{
// copy the reply block onto the heap
void (^replyCopy)(id<APRemoteAddressBook>, NSError *) = [replyHandler copy];
// ...
NSLog(@"Resolved successfully");
APRemoteAddressBook * book = [[APRemoteAddressBook alloc] initWithResolvedService: selected];
replyCopy(book, nil); // this is definitely the returned invocation
}
// ...
@end
// XPC endpoint set up like so:
- (BOOL) listener: (NSXPCListener *) listener shouldAcceptNewConnection: (NSXPCConnection *) newConnection
{
NSXPCInterface * myInterface = [NSXPCInterface interfaceWithProtocol: @protocol(APRemoteAddressBookBrowser)];
// add proxy details for the return value of -connectToServiceWithName:
NSXPCInterface * bookInterface = [NSXPCInterface interfaceWithProtocol: @protocol(APRemoteAddressBook)];
// first argument of the reply block is to be sent as a proxy
[myInterface setInterface: bookInterface
forSelector: @selector(connectToServiceWithName:replyHandler:)
argumentIndex: 0
ofReply: YES];
// proxy details for the commandHandler object sent to -setCommandHandler:
NSXPCInterface * commandHandlerInterface = [NSXPCInterface interfaceWithProtocol: @protocol(APRemoteCommandHandler)];
// first argument to the function is a proxy object
[myInterface setInterface: commandHandlerInterface
forSelector: @selector(setCommandHandler:errorHandler:)
argumentIndex: 0
ofReply: NO];
newConnection.exportedInterface = myInterface;
newConnection.exportedObject = self;
[newConnection resume];
return ( YES );
}
// when I attempt to actually return an APRemoteAddressBook proxy, the receiving
// application complains that it doesn't expect it. If I change the interface declaration
// above, it fails to encode, because APRemoteAddressBook doesn't implement NSSecureCoding.
// So it's definitely the right thing being passed as a proxy, so that's fine.
// What else is going wrong? The error here is damned near *useless*.
/*
2012-07-30 14:45:06.924 Core Data Contacts[7388:8623] Warning: Exception caught during decoding of received reply to message 'connectToServiceWithName:replyHandler:', dropping incoming message and calling failure block.
Exception: Exception while decoding argument 1 of invocation:
<NSInvocation: 0x101b76740>
return value: {v} void
target: {@?} 0x0 (block)
argument 1: {@} 0x0
argument 2: {@} 0x0
Exception: value for key '(no key, possibly an argument to a message)' was of unexpected class '_NSXPCDistantObject'. Allowed classes are '{(
)}'.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment