gpt4 book ai didi

macos - 是否可以将 pyobjc 与特权 XPC 帮助工具和 XPCInterface API 一起使用?

转载 作者:行者123 更新时间:2023-12-03 16:20:06 26 4
gpt4 key购买 nike

我相信这个问题的答案是“否”,但我将其发布给社区,以防有人比我更成功。

我有一个特权帮助工具,客户端 Cocoa 应用程序将其与 NSXPCConnection 和 NSXPCInterface 一起使用。该接口(interface)本身包含一个通过完成处理程序 block 提供返回代码的方法。

在 Objective-C 中,客户端代码如下所示:

NSXPCConnection * xpcConn = [NSXPCConnection alloc] 
initWithMachServiceName:kSvcName
options:NSXPCConnectionPrivileged];

// MyProtocol defines an instance method runCommand:(NSString*) withReply:^(int result)
NSXPCInterface * mySvcIF = [NSXPCInterface interfaceWithProtocol:@protocol(MyProtocol)];

xpcConn.remoteObjectInterface = mySvcIF;
[xpcConn resume];
if (nil == xpcConn.remoteObjectProxy) {
NSLog(@"ERROR - remote interface is nil, can't communicate with service");
}

[[xpcConn remoteObjectProxy] runCommand:nsstrCmd withReply:^(int result) {
NSLog(@"service result is: %d", result);
if (result != 0) {
self.svcResult = result;
self.svcCommandComplete = YES;
}
}];

我还有一个 pyobjc/py2app Mac 应用程序需要使用此帮助工具的功能。我已将该工具内置到 pyobjc 应用程序包中,并通过 SMJobBless 进行了签名和授权,但看起来存在几个问题,导致该 API 的实际使用不受支持:

1) 似乎不支持桥接 runCommand:withReply:^ 的调用 - 如果我理解正确的话, block 仅支持 NS* 框架方法调用,而不支持“自定义”(即用户定义)方法?请注意,如果这是唯一的阻塞问题,我可以制作一个没有返回代码的方法版本,但尝试并不太有效,因为......

2) 为了以 Objective-C 的方式使用 API,我需要创建一个对 runCommand: 的 @selector 引用:它实际上没有任何 python 函数实现 - 它只需是一个定义了的函数对象由动态创建的remoteProxy 提供的函数签名。我没有在 python 中定义 RemoteProxy 实现。这似乎不受支持 - 如果没有 python 函数通过 objc.selector() 工作,我无法获得选择器声明。

3) 我不确定即使我能让 2) 工作,正式协议(protocol)的构建也会按照预期的方式工作,作为来自 python 的 interfaceWithProtocol: 的参数 - 它需要成为 native 自定义NSXPCInterface 可以在其工厂方法中使用@protocol 来创建remoteProxy。

如果您已经弄清楚如何在 pyobjc 中执行此操作,或者根据您的知识确定此内容是不可能的,感谢您提供任何提示。

最佳答案

前两个子问题很容易回答:可以使用 block 调用 API,即使是非 Apple 框架的库中的 API。这确实需要在 python 代码中进行更多工作,因为 Objective-C 运行时没有公开足够的信息来完全自动地执行正确的操作。

对于这个特定的示例,您可以执行以下操作:

objc.registerMetaDataForSelector(b'NSObject', b'runCommand:withReply:', {
'arguments': {
3: {
'callable': {
'retval': {'type': b'@'},
'arguments': {
0: {'type': b'^v'},
1: {'type': b'i'},
},
},
}
}
})

这会注册方法“-[NSObject runCommand:withReply:]”的附加信息。 block 参数是数字 3:从 0 开始计数,Objective-C 方法的前两个参数是“self”和“_sel”(后者不暴露给 Python)。

您通常使用实现该方法的实际类,但我希望这是一个甚至可以动态生成的隐藏类。只要不与其他类冲突,仅在 NSObject 上注册元数据应该是安全的。

也可以在 Python 中创建协议(protocol):

MyProtocol = objc.formal_protocol('MyProtocol', (), [
objc.selector(None, b"runCommand:withReply:", signature=b"v@:@@?"),
])

并使用以下命令创建 XPC 界面:

mySvcIF = Foundation.NSXPCInterface.interfaceWithProtocol_(MyProtocol)

遗憾的是,后一步不起作用,因为 NSXPCInterface 引发异常:NSInvalidArgumentException - NSXPCInterface:无法从协议(protocol)数据获取扩展方法签名(MyProtocol/runCommand:withReply :)。 NSXPCInterface 需要使用 clang。

我已在 PyObjC 的跟踪器中为此提交了一个问题:https://github.com/ronaldoussoren/pyobjc/issues/256 .

此问题的解决方法是创建一个 Python 扩展,其中包含协议(protocol)定义以及使用该协议(protocol)的未使用函数(例如,请参阅 https://github.com/ronaldoussoren/pyobjc/blob/415d8a642a1af7f2bd7285335470098af4962dae/pyobjc-framework-Cocoa/Modules/_AppKit_protocols.m 了解后一部分)。导入扩展后,您可以使用 objc.protocolNamed("MyProtocol") 来访问协议(protocol),然后该协议(protocol)将引用由 clang 创建的完整协议(protocol)对象,并且应该与 NSXPCInterface 一起使用。

此解决方案现已记录在官方文档中,此处:https://pyobjc.readthedocs.io/en/latest/notes/using-nsxpcinterface.html

附注我很少访问 stackoverflow,通过邮寄到 pyobjc-dev@lists.sourceforge.net(PyObjC 邮件列表)通常更容易引起我的注意。

关于macos - 是否可以将 pyobjc 与特权 XPC 帮助工具和 XPCInterface API 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52284089/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com