【问题标题】:Xcode+Swift+XPC: How to start and deploy a Swift XPC target on MacOSXcode+Swift+XPC:如何在 MacOS 上启动和部署 Swift XPC 目标
【发布时间】:2018-07-02 22:10:07
【问题描述】:

免责声明:我对 MacOS/Xcode 比较陌生

我想在 Swift 中构建一个简单的 XPC 启动代理(即:~/Library/LaunchAgents),但我找不到太多文档。
我从 Xcode XPC 模板开始,但我不知道这对我的 Swift 项目是否是个好主意。
我注意到我也应该有~/Library/LaunchAgents/com.demo.myservice.plist

版本:
- MacOS:10.13.2
- Xcode:9.2

Xcode XPC 项目创建说明:

  1. 文件 > 新建项目
  2. 我选择了 MacOS 模板:XPC
  3. 我创建了“com.demo.myservice”包
  4. 它为我创建了一个 Objective-C 项目。所以我删除了所有文件(即:myserviceProtocol.hmyservice.hmyservice.mmain.mInfo.plist
  5. 创建文件:

myserviceProtocol.swift

import Foundation

@objc(myserviceProtocol) protocol myserviceProtocol {
    func ping()
}

myservice.swift

import Foundation

class myservice : NSObject, myserviceProtocol {
    func ping() {
        print("ping")
    }
}

main.swift

import Foundation

class ServiceDelegate : NSObject, NSXPCListenerDelegate {
    func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
        newConnection.exportedInterface = NSXPCInterface(with:myserviceProtocol.self)
        let exportedObject = myservice()
        newConnection.exportedObject = exportedObject
        newConnection.resume()
        return true
    }
}

// Create the listener and resume it:
//
let delegate = ServiceDelegate()
let listener = NSXPCListener.service()
listener.delegate = delegate;
listener.resume()

Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>
        <string>com.demo.myservice</string>
        <key>ProgramArguments</key>
        <array>
            <string>myservice</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>
  1. 我构建它:

  2. 我将 Info.plist 复制到 ~/Library/LaunchAgents/ 中:cp ~/Documents/myservice/myservice/Info.plist ~/Library/LaunchAgents/com.demo.myservice.plist
    我用id -u检索我的用户ID

然后我尝试从命令行执行它(因为它似乎没有从 Xcode 执行任何操作):

sudo launchctl debug user/501/com.demo.myservice /Users/olivier/Library/Developer/Xcode/DerivedData/myservice-hbwefcgibyqbajguvblgcmxsnrmd/Build/Products/Debug/myservice.xpc
Configuration failed: 113: Could not find specified service
Could not find service "com.demo.myservice" in domain for uid: 501

我不太确定自己在做什么。我是否正确使用XPC 模板来创建我的 swift XPC。

【问题讨论】:

    标签: swift xcode macos xpc


    【解决方案1】:

    如果您希望您的代理提供 XPC 服务,则需要将其公开为 Mach 服务。

    您初始化侦听器的方式是针对 XPC 服务(注意大写 S),XPC 服务是作为应用程序包的一部分的包,位于 Contents/XPCServices/ 目录内。

    总而言之,您必须:

    1.) 创建一个通过 mach 服务公开 XPC 服务的代理。你的听众看起来像:

    let listener = NSXPCListener(machServiceName: "com.rderik.exampleXPC" )
    

    2.) 要使用代理的服务,您需要建立与该 mach 服务的连接。

    let connection = NSXPCConnection(machServiceName: "com.rderik.exampleXPC")
    

    希望对你有帮助。

    如果你想了解更多,我在这里写了一篇关于如何做到这一点的教程:

    https://rderik.com/blog/creating-a-launch-agent-that-provides-an-xpc-service-on-macos/

    【讨论】:

      【解决方案2】:

      我不确定你的目标是什么。如果你只想要一个由 launchd 管理的守护进程,那么你不需要 XPC。只需创建一个守护进程(可能使用命令行工具项目模板)并创建一个launchd plist 配置文件(参见man launchd.plist)。

      XPC 旨在与主机应用程序通信。服务二进制文件应该嵌入到您的应用程序包中,并且当您的应用程序尝试连接时,launchd 将启动它。您无需为此修改 ~/Library/LaunchAgents。

      您的应用需要设置一个NSXPCConnection 以连接到您创建的 XPCListener。

      类似:

      let connection = NSXPCConnection(serviceName: "com.demo.myservice")
      let interface = NSXPCInterface(with: myserviceProtocol.self)
      connection.remoteObjectInterface = interface
      connection.resume()
      let proxy = connection.remoteObjectProxyWithErrorHandler {(error) in
                  os_log("Connection Error: %{public}@", error.localizedDescription)
              } as! myserviceProtocol
      
      // message proxy here to communicate with service
      

      Daemons and Services Programming Guide 中更详细地介绍了这两种情况

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多