XPC 在工作空间中的两个可可应用程序之间,NSXPCConnection 立即失效

Posted

技术标签:

【中文标题】XPC 在工作空间中的两个可可应用程序之间,NSXPCConnection 立即失效【英文标题】:XPC Between two cocoa applications in workspace, the NSXPCConnection is immediately being invalidated 【发布时间】:2017-01-27 19:23:22 【问题描述】:

我有两个 Cocoa 应用程序,在这个 XPC 关系中,一个是发送者,另一个是接收者。

在sender中applicationDidFinishLaunching,我先打开第二个receiver应用

  NSError* error = nil;
  NSURL* url = [[NSBundle mainBundle] bundleURL];
  url = [url URLByAppendingPathComponent:@"Contents" isDirectory:YES];
  url = [url URLByAppendingPathComponent:@"MacOS" isDirectory:YES];
  url = [url URLByAppendingPathComponent:@"TestXPCHelper.app" isDirectory:YES];

  [[NSWorkspace sharedWorkspace] launchApplicationAtURL:url
                                                options:NSWorkspaceLaunchWithoutActivation
                                          configuration:[NSDictionary dictionary]
                                                  error:&error];

  if ( error )
  
     NSLog(@"launchApplicationAtURL:%@ error = %@", url, error);
     [[NSAlert alertWithError:error] runModal];
  

然后我创建我的NSXPCConnection

  assert([NSThread isMainThread]);
  if (self.testConnection == nil) 
     self.testConnection = [[NSXPCConnection alloc] initWithMachServiceName:NEVER_TRANSLATE(@"com.TechSmith.TestXPCHelper") options:NSXPCConnectionPrivileged];
     self.testConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(TestXPCProtocol)];

     self.testConnection.interruptionHandler = ^
        NSLog(@"Connection Terminated");
     ;

     self.testConnection.invalidationHandler = ^

        self.testConnection.invalidationHandler = nil;
        [[NSOperationQueue mainQueue] addOperationWithBlock:^
           self.testConnection = nil;
        ];
     ;

     [self.testConnection resume];
  

然后我尝试通过连接发送消息(连接已在此处失效)

  id<TestXPCProtocol> testRemoteObject= [self.testConnection remoteObjectProxy];
  [testRemoteObject testXPCMethod2];

  [[self.testConnection remoteObjectProxyWithErrorHandler:^(NSError * proxyError)
     NSLog(@"%@", proxyError);
  ] testXPCMethod:^(NSString* reply) 
     NSLog(@"%@", reply);
  ];

这是我的接收器应用程序的应用程序委托:

@interface AppDelegate () <NSXPCListenerDelegate, TestXPCProtocol>

@property (weak) IBOutlet NSWindow *window;

@property NSXPCListener *xpcListener;

@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
   // Insert code here to initialize your application
   NSLog(@"TESTING123");

   self.xpcListener = [[NSXPCListener alloc] initWithMachServiceName:@"com.TechSmith.TestXPCHelper"];
   self.xpcListener.delegate = self;
   [self.xpcListener resume];


- (void)applicationDidBecomeActive:(NSNotification *)notification 
   NSLog(@"ACTIVE234");



- (void)applicationWillTerminate:(NSNotification *)aNotification 
   // Insert code here to tear down your application


- (void)run

   NSLog(@"RUNNING");
   // Tell the XPC listener to start processing requests.

   [self.xpcListener resume];

   // Run the run loop forever.

   [[NSRunLoop currentRunLoop] run];


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

   NSLog(@"LISTENING");
   assert(listener == self.xpcListener);
#pragma unused(listener)
   assert(newConnection != nil);

   newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(TestXPCProtocol)];
   newConnection.exportedObject = self;
   [newConnection resume];

   return YES;


- (void)testXPCMethod:(void(^)(NSString * version))reply

   NSLog(@"HEY");
   reply(@"REPLY HERE");


- (void)testXPCMethod2

   NSLog(@"TWO!");

这是我尝试通过连接发送消息时的proxyError

Error Domain=NSCocoaErrorDomain Code=4099 "连接到服务 名为 com.TechSmith.TestXPCHelper 已失效。" UserInfo=NSDebugDescription=The 与名为 com.TechSmith.TestXPCHelper 的服务的连接无效。

所以我认为我对NSXPCConnection 的实例化做错了。我找不到两个应用程序相互通信的好例子——它总是一个应用程序和一个服务。这就是我的问题吗?我需要在应用程序之间提供服务吗?

有什么方法可以获取有关此连接为何无效的更多信息?这也会有很大帮助

【问题讨论】:

【参考方案1】:

这里的问题非常简单, 原来initWithMachServiceName 明确地在寻找一个马赫服务。我正在使用另一个应用程序进程的标识符。

如果我真的使用了一个有效的 mach 服务的标识符,就没有问题

请注意,还有两种其他方法可以创建NSXPCConnection

带有NSXPCEndpoint 或带有XPCService 标识符

【讨论】:

但是如何创建有效的 mach 服务? 时间太久我不记得了,不过,我确实将我的项目上传到了这里的一个独立实验室:github.com/MattyAyOh/XPCLab/search?q=mach&unscoped_q=mach 啊我也找到了这个旧资源github.com/brenwell/EvenBetterAuthorizationSample

以上是关于XPC 在工作空间中的两个可可应用程序之间,NSXPCConnection 立即失效的主要内容,如果未能解决你的问题,请参考以下文章

XPC 到 XPC 通信

NSX 简介— 网络虚拟化

XPC remoteObjectWithErrorHandler 不会抛出错误

XPC 服务:提高工作线程上的堆栈大小

“面向多云架构的NSX高级负载均衡”网络论坛,精彩点播回放!

从 XPC 服务创建 NSXPCConnection