NSPOSIXErrorDomain when binding to socket on macOS 10.12

1.8k Views Asked by At

I am playing with CocoaAsyncSocket in Swift to bind to a UDP socket and receive messages over the local network.

I am initialising a socket, and trying to bind to a port but am getting a NSPOSIXErrorDomain error. Perhaps indicating some sort of permissions issue?

My code:

import Cocoa
import CocoaAsyncSocket

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, GCDAsyncUdpSocketDelegate {
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        let socket = GCDAsyncUdpSocket.init(delegate: self, delegateQueue: DispatchQueue.main)
        do {
            try socket.bind(toPort: 53401)
        } catch let msg {
            NSLog("Error....\(msg)")
        }
    }
}

Full error:

Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" UserInfo={NSLocalizedDescription=Operation not permitted, NSLocalizedFailureReason=Error in bind() function}
3

There are 3 best solutions below

2
Jan On BEST ANSWER

I believe it's the generated Xcode entitlements that prevent from binding. I changed those values to false and now the bind works

<?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>com.apple.security.app-sandbox</key>
    <false/>
    <key>com.apple.security.files.user-selected.read-only</key>
    <false/>
</dict>
</plist>
0
black_pearl On

You should enable its network capability

in macOS Catalina Version 10.15.3:

enter image description here

2
Lerk On

You should not disable the App Sandboxing.

This will at least result in your App being rejected when you try to distribute it to AppStoreConnect.

The proper values to add to the entitlements file are these two:

<key>com.apple.security.network.client</key>
<true/>

<key>com.apple.security.network.server</key>
<true/>

You can also use the GUI:

  1. Go to the target settings of the App
  2. Go to "Signing & Capabilities" in the App target settings
  3. Check the "Incoming network connections (server)" and/or "Outgoing network connections (client)" according to your needs

Note that this will simply create the entries in the entitlements file, so it's probably easier to edit it directly.