- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一对简单的“客户端应用程序”和“XPC 服务”。我能够从客户端启动 xpc 服务(即我可以看到在事件监视器进程列表中运行的服务),但是当我尝试发送任何具有响应块的请求时,我收到一个错误:“无法与一个辅助应用程序。”
这里最糟糕的事情是错误没有给我任何关于出了什么问题的信息。而且我也无法正确调试服务。据我了解,正确的方法是将调试器附加到进程(调试->附加到进程,另见 here)。我在一个工作区中同时拥有客户和服务项目。
当我从 xcode 运行客户端并尝试将调试器附加到启动的服务时,以“无法附加到 pid:X”错误结束。
如果我存档客户端应用程序从应用程序文件运行它,然后尝试将调试器附加到服务,结果是相同的。
从我可以想象的服务中记录某些内容的唯一方法是编写一个记录器类,它将数据写入某个文件。还没有尝试过这种方法,但这对我来说看起来很疯狂。
所以我的问题是:
a) 当收到诸如“无法与辅助应用程序通信”之类的非信息性响应时,如何找出问题所在?
b) 而且,首先调试 xpc 服务的正确方法是什么?上面的链接从现在起已有 5 年历史,但是我可以看到有些人说“附加到调试器”不起作用。
代码本身相当简单:
XPC 服务,监听器实现:
#import "ProcessorListener.h"
@implementation ProcessorListener
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
{
[newConnection setExportedInterface: [NSXPCInterface interfaceWithProtocol:@protocol(TestServiceProtocol)]];
[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) sendMessageWithResponse:(NSString *)receivedString reply:(void (^)(NSString *))reply
{
reply = @"This is a response";
}
- (void) sendMessageWithNoResponse:(NSString *)mString
{
// no response here, dummy method
NSLog(@"%@", mString);
}
#import <Foundation/Foundation.h>
#import "TestService.h"
@interface ServiceDelegate : NSObject <NSXPCListenerDelegate>
@end
@implementation ServiceDelegate
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
// This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection.
// Configure the connection.
// First, set the interface that the exported object implements.
newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(TestServiceProtocol)];
// Next, set the object that the connection exports. All messages sent on the connection to this service will be sent to the exported object to handle. The connection retains the exported object.
TestService *exportedObject = [TestService new];
newConnection.exportedObject = exportedObject;
// Resuming the connection allows the system to deliver more incoming messages.
[newConnection resume];
// Returning YES from this method tells the system that you have accepted this connection. If you want to reject the connection for some reason, call -invalidate on the connection and return NO.
return YES;
}
@end
int main(int argc, const char *argv[])
{
// [NSThread sleepForTimeInterval:10.0];
// Create the delegate for the service.
ServiceDelegate *delegate = [ServiceDelegate new];
// Set up the one NSXPCListener for this service. It will handle all incoming connections.
NSXPCListener *listener = [NSXPCListener serviceListener];
listener.delegate = delegate;
// Resuming the serviceListener starts this service. This method does not return.
[listener resume];
return 0;
}
- (IBAction)buttonSendMessageTap:(id)sender {
if ([daemonController running])
{
[self executeRemoteProcessWithName:@"NoResponse"];
}
else
{
[[self.labelMessageResult cell] setTitle: @"Error"];
}
}
- (IBAction)buttonSendMessage2:(id)sender {
if ([daemonController running])
{
[self executeRemoteProcessWithName:@"WithResponse"];
}
else
{
[[self.labelMessageResult cell] setTitle: @"Error"];
}
}
- (void) executeRemoteProcessWithName: (NSString*) processName
{
// Create connection
NSXPCInterface * myCookieInterface = [NSXPCInterface interfaceWithProtocol: @protocol(Processor)];
NSXPCConnection * connection = [[NSXPCConnection alloc] initWithServiceName: @"bunldeID"]; // there's a correct bundle id there, really
[connection setRemoteObjectInterface: myCookieInterface];
connection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(Progress)];
connection.exportedObject = self;
[connection resume];
// NOTE that this error handling code is not called, when debugging client, i.e connection seems to be established
id<Processor> theProcessor = [connection remoteObjectProxyWithErrorHandler:^(NSError *err)
{
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle: @"OK"];
[alert setMessageText: err.localizedDescription];
[alert setAlertStyle: NSAlertStyleWarning];
[alert performSelectorOnMainThread: @selector(runModal) withObject: nil waitUntilDone: YES];
}];
if ([processName containsString:@"NoResponse"])
{
[theProcessor sendMessageWithNoResponse:@"message"];
}
else if ([processName containsString:@"WithResponse"])
{
[theProcessor sendMessageWithResponse:@"message" reply:^(NSString* replyString)
{
[[self.labelMessageResult cell] setTitle: replyString];
}];
}
}
最佳答案
乔纳森·莱文 XPoCe当您无法附加调试器时,该工具很有用。
您可以添加日志记录 NSLog()
或 fprintf(stderr,...)
给您的服务和客户,特别是状态代码。你只需要指定文件的路径来写入标准输出和标准错误。 <key>StandardErrorPath</key> <string>/tmp/mystderr.log</string>
有一个关于 Debugging Daemons 的部分在这篇关于 objc.io 的文章中。
关于objective-c - 如何在 OSX 中调试 XPC 服务和客户端应用程序之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42764618/
我带着为 OSX 编写 PAM 模块的永无休止的传奇再次回来了。我已经写好了模块。它在使用 ssh 或启动新的终端窗口或 su 时有效。我真正真正想要的只是 ssh 和登录窗口。 我的 PAM 模块在
我们有一个类似于Soundflower的虚拟音频设备驱动程序。该虚拟设备将在声音系统首选项中列出。每当我们的设备在系统偏好设置中被选择时,它就会阻止空闲 sleep 。如果我们将选择切换为默认输出设备
我带着为 OSX 编写 PAM 模块的永无止境的传奇又回来了。我已经编写了模块。它在使用 ssh 或启动新的终端窗口或 su 时有效。我真的、真的、真的想要的只是 ssh 和登录窗口。 我的 PAM
我想在 osx lion 上安装 pyaudio,但我无法做到。每次我尝试使用 pkg 时,它都不会安装任何东西。当我尝试使用 pip 安装它时,出现以下错误(以及许多其他行): lipo: can'
我使用 Java 进行开发已有很长时间了,但直到最近才从 Windows 切换到 OSX。在 Windows 中,我发现一切都足够简单易懂。我可以将 JDK 安装到一个选择的位置,其中还包括一个 JR
运行 Mac OSX 10.7.5 我想在 USB3 外部硬盘上启用 NTFS 并需要 UUID 来执行此操作( http://ntfsonmac.com ),但 diskutil 拒绝给我 UUID
我正在尝试为 Finder 创建服务,但我的应用程序不需要有 UI。好吧,我只需要一个 UI 来请求用户提供更多信息,我的应用程序有时可能需要这些信息。 但是应用程序应该在没有任何 UI 且 Dock
我正在尝试在我的 mac 上使用本地服务器,但它似乎忽略了/etc/hosts 文件中的 localhost 设置。找到了几个页面,其中解决方案是重新安装,并将 localhost 放在/etc/ho
这是一个 OSX 链接器问题。我不认为 OSX(BSD 或 Mach 层)在乎零页有多大,或者它是否真的存在。我认为这是一个工具的事情。但这是我的意见,这就是我问的原因。 -pagezero_size
我正在构建一个将在 iOS/OSX 应用中使用的模块。 客户坚持认为该模块可以在 iOS 和 OSX 上运行。 我需要检查我在 iOS 和 OSX 上使用 UIDevice 时使用的系统版本 FTWD
我尝试在 OSX 10.8.2 中使用 gnuplot,并看到 x11 是不明确或未知的终端类型。一些研究表明 x11 不受支持,我下载了 XQartz,但我仍然收到相同的错误消息。 我使用 expo
我从官方网站下载了 PostgreSQL 并运行了 .dmg 安装程序。之后我下载了 pgadmin3,我确实能够连接到数据库。 当我运行“psql”时,出现以下错误: psql: could not
自从升级到 OSX Catalina 以来,我一直遇到 UnsatisfiedLinkErrors 问题,尝试在 java 下运行 JNI 包装的库,其中包含多个 native 库引用,这些引用在早期
在 OSX 10.6 上使用 make 构建 C++ 项目时,我确定预处理器定义 __LP64__ 似乎始终自动由编译器(即,它没有在任何头文件中定义)(参见 Where is __LP64__ de
我正在尝试将我的 iOS 应用程序移植到 Mac OS X SDK,并且发现我收到以下错误消息:'Collection' redeclared as a different kind of symbo
我一直在 OSX 10.14 中成功使用我的代码生成 Metal 纹理: let textureLoaderOptions = [MTKTextureLoader.Option.origin : MT
我对编码有些陌生,想用 MySQL 后端启动我的第一个 Django 应用程序。我已经在我的 Windows 机器上使用这个设置将近一年了,但它是一个继承的代码库——不幸的是,我从未尝试过从头开始构建
我正在迁移到一台新计算机,同时从雪豹迁移到狮子。 phpunit 似乎没有进行迁移,所以我重新安装了它。然而,pear 的标准安装似乎不适用于我的 php 家庭brew 安装。这是错误: phpuni
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 已关闭 7 年前。 Improve
我在 OSX10.9 上为我的应用程序构建了一个 Java 7 bundle ,一切看起来都很好,但是当我在 OSX 10.7 上尝试它时,它在启动时崩溃,它已经在 10.7.3 和 10.7.5 上
我是一名优秀的程序员,十分优秀!