You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XPC服务无法接收客户端数据的技术求助

Troubleshooting XPC Communication Between Swift CLI Client and macOS UI Server

Let's walk through the most common issues and fixes for your XPC communication problem—your CLI app isn't sending messages to the UI server, so we'll break down each potential culprit step by step.

1. Verify Mach Service Registration & Name Consistency

First, double-check the basics:

  • Ensure the Mach service name com.test.xpc is exactly identical in both client and server code (no typos, case mismatches, or extra characters).
  • Your UI app (server) must register the Mach service in its Info.plist to make it visible to the system. Add this entry:
    <key>NSMachServices</key>
    <dict>
        <key>com.test.xpc</key>
        <dict/>
    </dict>
    
  • Confirm the service is registered by running this in Terminal:
    launchctl list | grep com.test.xpc
    
    You should see your UI app's process associated with the service name.

2. Fix Client Connection Lifecycle & Message Timing

Your current CLI client has two critical issues: it sends the message before the connection is fully established, and it exits immediately before asynchronous XPC operations can complete. Here's the corrected code:

import Foundation
import XPC

let queue = DispatchQueue(label: "com.my.queue")
let conn: xpc_connection_t = xpc_connection_create_mach_service("com.test.xpc", queue, 0)

// Set up connection handler to manage state and send messages only when ready
xpc_connection_set_event_handler(conn) { object in
    if let error = xpc_dictionary_get_value(object, XPC_ERROR_KEY) {
        debugPrint("Client connection error:", xpc_copy_description(error))
    } else if xpc_get_type(object) == XPC_TYPE_DICTIONARY {
        // Handle server responses (if you add them)
        debugPrint("Client received response:", xpc_copy_description(object))
    } else {
        // Connection is ready—send your message now
        let message = xpc_dictionary_create(nil, nil, 0)
        xpc_dictionary_set_string(message, "message", "hello world")
        xpc_connection_send_message(conn, message)
        debugPrint("Message sent successfully")
    }
}

// Resume the connection
xpc_connection_resume(conn)

// Keep the CLI app running to handle async XPC events (critical!)
dispatchMain()

Key fixes here:

  • We wait for the connection to be fully established (via the event handler) before sending the message.
  • dispatchMain() prevents the CLI from exiting immediately—XPC operations are asynchronous, so the process needs to stay alive to complete them.

3. Strengthen Server Connection Handling

Your server code works in theory, but adding error handling and confirmation logic will help diagnose issues. Update the event handler in your AppDelegate.swift:

xpc_connection_set_event_handler(conn) { [weak self] client in
    debugPrint("New client connected:", client)
    xpc_connection_set_event_handler(client) { [weak self] object in
        if let error = xpc_dictionary_get_value(object, XPC_ERROR_KEY) {
            debugPrint("Client connection error:", xpc_copy_description(error))
        } else {
            debugPrint("Server received message:", xpc_copy_description(object))
            // Optional: Send a reply to confirm receipt
            let response = xpc_dictionary_create(nil, nil, 0)
            xpc_dictionary_set_string(response, "reply", "Received your hello world!")
            xpc_connection_send_message(client, response)
        }
    }
    xpc_connection_resume(client)
}

This will log any client-side errors and let you confirm if the server is actually receiving connections.

4. Check Sandbox Permissions

If your UI app uses App Sandbox (common for macOS apps), you need to grant permission to use the Mach service in your Entitlements.plist:

<key>com.apple.security.temporary-exception.mach-lookup.global-name</key>
<array>
    <string>com.test.xpc</string>
</array>

Without this, the sandbox will block incoming connections to your service. If your CLI app also has sandbox enabled (uncommon but possible), add the same entitlement there too.

5. Validate Connection State with Logs

Add extra debug logs to confirm connection states:

  • In the client, check the connection state before sending messages:
    let state = xpc_connection_get_state(conn)
    debugPrint("Client connection state:", state.rawValue)
    
    A state value of 2 means XPC_CONNECTION_STATE_CONNECTED—only send messages when you see this.
  • Ensure both apps are running when you test: the UI server must be open before launching the CLI client.

内容的提问来源于stack exchange,提问作者Cornwell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:39:49