Created
July 30, 2012 19:09
-
-
Save AlanQuatermain/3209230 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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