Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 如何从XPC helper应用程序向主应用程序发送消息?_Macos_Cocoa_Xpc_Nsxpcconnection - Fatal编程技术网

Macos 如何从XPC helper应用程序向主应用程序发送消息?

Macos 如何从XPC helper应用程序向主应用程序发送消息?,macos,cocoa,xpc,nsxpcconnection,Macos,Cocoa,Xpc,Nsxpcconnection,我成功地创建了XPC服务,并通过从主应用程序发送消息与XPC服务通信。但我想知道的是,是否可以启动从XPC服务到主应用程序的通信。表示XPC是双向的。如果有人能举个例子给我指出正确的方向,我将不胜感激 请注意 我想从主应用程序启动XPC 从主应用程序与XPC通信 当一些事件发生时,XPC应该向主应用程序发送一条消息 前两个我都成功了,但第三个我找不到任何资源 谢谢。:) 把一切都弄明白了。以下是一个不错的例子: ProcessorListener.h(包括在客户端和服务器中): @协议处理器

我成功地创建了XPC服务,并通过从主应用程序发送消息与XPC服务通信。但我想知道的是,是否可以启动从XPC服务到主应用程序的通信。表示XPC是双向的。如果有人能举个例子给我指出正确的方向,我将不胜感激

请注意

  • 我想从主应用程序启动XPC
  • 从主应用程序与XPC通信
  • 当一些事件发生时,XPC应该向主应用程序发送一条消息
前两个我都成功了,但第三个我找不到任何资源


谢谢。:)

把一切都弄明白了。以下是一个不错的例子:

ProcessorListener.h(包括在客户端和服务器中):

@协议处理器
-(void)数据处理:(void(^)(NSString*response))应答;
@结束
@协议进展
-(void)updateProgress:(双)currentProgress;
-(无效)已完成;
@结束
@接口处理器Listener:NSObject
@属性(弱)NSXPCConnection*xpcConnection;
@结束
ProcessorListener.m:(仅包含在服务器中)

#导入“ProcessorListener.h”
@实现处理器Listener
-(BOOL)侦听器:(NSXPCListener*)侦听器应接受新连接:(NSXPCConnection*)新连接
{
[新连接集导出接口:[NSXPCInterface interface interface with protocol:@protocol(Processor)];
[新连接设置导出对象:self];
self.xpcConnection=newConnection;
newConnection.remoteObjectInterface=[NSXPCInterface Interface WithProtocol:@protocol(Progress)];
//默认情况下,连接开始挂起,因此请继续并开始接收它们
[新连接恢复];
返回YES;
}
-(void)数据处理:(void(^)(NSString*g))回复
{
调度异步(调度获取全局队列(0,0)^{
对于(int索引=0;索引<60;++索引)
{
[NSThread sleepWithTimeInterval:1];
[[self.xpcConnection remoteObjectProxy]updateProgress:(双)索引/(双)60*100];
}
[[self.xpcConnection remoteObjectProxy]完成];
}
//nil是一个有效的返回值。
答复(@“这是答复!”);
}
@结束
MainApplication.m(您的主应用程序):

#导入“ProcessorListener.h”
-(void)ExecuteMoteProcess
{
//建立我们的联系
NSXPCInterface*myCookieInterface=[NSXPCInterface interfaceWithProtocol:@协议(处理器)];
NSXPCConnection*连接=[[NSXPCConnection alloc]initWithServiceName:kServiceName];
[connection setRemoteObjectInterface:MyOkieInterface];
connection.exportedInterface=[NSXPCInterface interface interface with protocol:@protocol(Progress)];
connection.exportedObject=self;
[连接恢复];
id处理器=[connection remoteObjectProxyWithErrorHandler:^(n错误*错误)
{
NSAlert*警报=[[NSAlert alloc]init];
[标题为@“确定”的警报添加按钮];
[alert setMessageText:err.localizedDescription];
[警报设置警报样式:NSWarningAlertStyle];
[alert performSelectorOnMainThread:@selector(runModal)with object:nil waitUntilDone:YES];
}];
[处理器数据处理:^(NSString*响应)
{
NSLog(@“收到的响应:%@”,响应);
}];
}
#布拉格标记-
#布拉格语标记进展
-(void)updateProgress:(双)currentProgress
{
NSLog(@“进行中:%f”,currentProgress);
}
-(无效)完成
{
NSLog(@“已完成!”);
}
@结束

请注意,此代码是基于我的工作代码的浓缩版本。它可能不会100%编译,但显示了使用的关键概念。在示例中,
doProcessing
运行异步,以显示即使在初始方法返回且
收到响应后,
Progress
协议中定义的回调仍会执行onse:这是一个回复!
已被记录。

您在回调主程序方面做了哪些尝试?您是否尝试使用主程序中的
exportedMethods
exportedObject
?是的,我正在尝试使用XPC服务中的
remoteObjectInterface
和主应用程序中的
ExportedObject
上。如果您能提供一个示例,我将非常高兴。向我们展示您尝试过的内容,我们将尝试帮助您修复。如果处理器有多个连接,该怎么办?我如何知道哪个连接称为
doProcessing
,以便我可以向其报告进度?@pointum您可以将另一个标识进程的参数传递到
doProcessing
。这是一个很好的答案,但为什么不在定义不同的部分和内容时讨论应用程序和服务,而不是客户端和服务器呢?其中的秘密在于“服务器”必须在特定的上下文中运行。我的意思是,如果您从gdb或命令行运行服务器,这是行不通的。
@protocol Processor

- (void) doProcessing: (void (^)(NSString *response))reply;

@end

@protocol Progress

- (void) updateProgress: (double) currentProgress;
- (void) finished;

@end

@interface ProcessorListener : NSObject<NSXPCListenerDelegate, Processor>

@property (weak) NSXPCConnection *xpcConnection;

@end
#import "ProcessorListener.h"

@implementation ProcessorListener

- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
{
    [newConnection setExportedInterface: [NSXPCInterface interfaceWithProtocol:@protocol(Processor)]];
    [newConnection setExportedObject: self];
    self.xpcConnection = newConnection;

    newConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol: @protocol(Progress)];

    // connections start suspended by default, so resume and start receiving them
    [newConnection resume];

    return YES;
}

- (void) doProcessing: (void (^)(NSString *g))reply
{
    dispatch_async(dispatch_get_global_queue(0,0), ^{
      for(int index = 0; index < 60; ++index)
      {
         [NSThread sleepWithTimeInterval: 1];
         [[self.xpcConnection remoteObjectProxy] updateProgress: (double)index / (double)60 * 100];
      }

      [[self.xpcConnection remoteObjectProxy] finished];
    }

    // nil is a valid return value.
    reply(@"This is a reply!");
}

@end
#import "ProcessorListener.h"

- (void) executeRemoteProcess
{
    // Create our connection
    NSXPCInterface * myCookieInterface = [NSXPCInterface interfaceWithProtocol: @protocol(Processor)];

    NSXPCConnection * connection = [[NSXPCConnection alloc] initWithServiceName: kServiceName];

    [connection setRemoteObjectInterface: myCookieInterface];

    connection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(Progress)];
    connection.exportedObject = self;

    [connection resume];

    id<Processor> theProcessor = [connection remoteObjectProxyWithErrorHandler:^(NSError *err)
                       {
                           NSAlert *alert = [[NSAlert alloc] init];
                           [alert addButtonWithTitle: @"OK"];
                           [alert setMessageText: err.localizedDescription];
                           [alert setAlertStyle: NSWarningAlertStyle];

                           [alert performSelectorOnMainThread: @selector(runModal) withObject: nil waitUntilDone: YES];
                       }];

    [theProcessor doProcessing: ^(NSString * response)
     {
        NSLog(@"Received response: %@", response);
     }];
}

#pragma mark -
#pragma mark Progress

- (void) updateProgress: (double) currentProgress
{
    NSLog(@"In progress: %f", currentProgress);
}

- (void) finished
{
    NSLog(@"Has finished!");
}

@end