Yes, the summary is correct. The purpose of the connection is solely to obtain the remote endpoint's IP address. But I'm considering having the remote device send its "real" address over. The connection has a protocol framer already, so it wouldn't be a big change.
The team that owns the sync API has made some changes to accept and parse the interface. That makes it work, some of the time. Most of the time, sync times out or gets "connection refused".
Post
Replies
Boosts
Views
Activity
Sorry, I should have provided more context. My API (doSync) needs an IP address. So I pass the endpoint to an NWConnection to resolve the address. But the address is not directly reachable:
% ping6 fe80::908d:59ff:fe60:8858
ping6: UDP connect: No route to host
Interestingly, adding the interface suffix works.
% ping6 fe80::908d:59ff:fe60:8858%en9
PING6(56=40+8+8 bytes) fe80::908d:59ff:fe60:88a7%en9 --> fe80::908d:59ff:fe60:8858%en9
16 bytes from...
But my API doesn't understand this address format.
The timeout issue is now resolved. The connection class has an optional timeout property, so it can be cancelled either by timeout, or manually.
The second issue of not being able to connect is still open, though. The IP address resolved by the Bonjour is link-local, e.g. fe80::908d:59ff:fe60:8858%en9. Connecting to this address fails with "no route to host". If I ask the device for its own address (using the getifaddrs function), it returns a fd60:... address, which I can connect to.
The address is resolved like this:
func connectionReady(_ connection: NWConnection) throws {
guard let remoteEndpoint = connection.currentPath?.remoteEndpoint else {
throw NWError.posix(.EADDRNOTAVAIL)
}
// Connected: get address, and sync with peer
switch remoteEndpoint {
case .hostPort(let host, _):
var addr = "\(host)"
print(addr) // prints fe80:...%en9
doSync(with: addr)
default:
throw NWError.posix(.EDESTADDRREQ)
}
}
Huh... I assumed any error would translate into a stateUpdateHandler call with a .failed(error) case. But okay, I can add a timeout.
There is a listener on the other device - that's where the endpoint is coming from. I'm not sure why they can't connect to each other, if they can see one another via Bonjour. The participants are: a simulator running iOS 16.2, and an iPhone running 16.3.1.
It was because the exportOptions.plist method was set to development. Set it to app-store, and it will sign with a distribution profile.
FWIW, the Provisioning Profile under Build Settings is also Automatic.
I tried adding CODE_SIGN_IDENTITY="Apple Distribution" to the xcodebuild command, but that failed with "MyApp is automatically signed for development, but a conflicting code signing identity Apple Distribution has been manually specified".
This looks like a bug. You can see from the following output that xcodebuild is clearly ignoring the -derivedDataPath setting:
Command line invocation:
/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -project MyProj.xcodeproj -scheme "MyProj (iOS)" -destination "name=iPhone 12" -derivedDataPath=/Users/alpe77/myproj/MyProj/Build build
User defaults from command line:
derivedDataPath = /Users/alpe77/myproj/MyProj/Build
IDEPackageSupportUseBuiltinSCM = YES
note: Using new build system
note: Building targets in parallel
note: Planning build
note: Analyzing workspace
note: Using build description from disk
note: Build preparation complete
CodeSign /Users/alpe77/Library/Developer/Xcode/DerivedData/MyProj-aozsidihjyumkvevtfoqflhumohn/Build/Products/Debug-iphonesimulator/MyProj.app (in target 'MyProj (iOS)' from project 'MyProj')
cd /Users/alpe77/myproj/MyProj
export CODESIGN_ALLOCATE\=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate
Signing Identity: "-"
/usr/bin/codesign --force --sign - --entitlements /Users/alpe77/Library/Developer/Xcode/DerivedData/MyProj-aozsidihjyumkvevtfoqflhumohn/Build/Intermediates.noindex/MyProj.build/Debug-iphonesimulator/MyProj\ \(iOS\).build/MyProj.app.xcent --timestamp\=none /Users/alpe77/Library/Developer/Xcode/DerivedData/MyProj-aozsidihjyumkvevtfoqflhumohn/Build/Products/Debug-iphonesimulator/MyProj.app
/Users/alpe77/Library/Developer/Xcode/DerivedData/MyProj-aozsidihjyumkvevtfoqflhumohn/Build/Products/Debug-iphonesimulator/MyProj.app: replacing existing signature
** BUILD SUCCEEDED ** [0.771 sec]
I swear -derivedDataPath was working for a while, but then it stopped. After a git clean -dfx, xcodebuild started ignoring the -derivedDataPath setting, and writing to ~/Library/Xcode/Developer/DerivedData again.
Why can't xcodebuild just do the same thing as Xcode's build button?