Post

Replies

Boosts

Views

Activity

Reply to NWMulticastGroup returns POSIXErrorCode error
This code worked for me using dispatch source as pointed out by DTS Engineer. Hopefully it will help out other developers. final class UDPConnection { private var socketDescriptor: Int32 = -1 private let port: UInt16 private var dispatchSource: DispatchSourceRead? init(port: UInt16) { self.port = port } func start() { socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) guard socketDescriptor > 0 else { print("Failed to create socket") return } var broadcastEnable = Int32(1) setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, socklen_t(MemoryLayout<Int32>.size)) var address = sockaddr_in() address.sin_family = sa_family_t(AF_INET) address.sin_port = in_port_t(port).bigEndian address.sin_addr = in_addr(s_addr: INADDR_ANY) let bindResult = withUnsafePointer(to: &address) { pointer in pointer.withMemoryRebound(to: sockaddr.self, capacity: 1) { sockaddrPointer in bind(socketDescriptor, sockaddrPointer, socklen_t(MemoryLayout<sockaddr_in>.size)) } } guard bindResult == 0 else { print("Failed to bind socket") close(socketDescriptor) return } print("Started receiving on port \(port)") // Set up the DispatchSource to monitor the socket for read events dispatchSource = DispatchSource.makeReadSource(fileDescriptor: socketDescriptor, queue: DispatchQueue.global()) dispatchSource?.setEventHandler { [weak self] in self?.handleSocketEvent() } dispatchSource?.setCancelHandler { close(self.socketDescriptor) } dispatchSource?.resume() } private func handleSocketEvent() { var buffer = [UInt8](repeating: 0, count: 1500) var address = sockaddr_in() var addressLength = socklen_t(MemoryLayout<sockaddr_in>.size) let bytesRead = withUnsafeMutablePointer(to: &address) { pointer in pointer.withMemoryRebound(to: sockaddr.self, capacity: 1) { sockaddrPointer in recvfrom(self.socketDescriptor, &buffer, buffer.count, 0, sockaddrPointer, &addressLength) } } if bytesRead > 0 { let message = String(bytes: buffer[..<bytesRead], encoding: .utf8) ?? "Invalid UTF-8 message" print("Received message: \(message)") } else if bytesRead == -1 { print("Error receiving message: \(String(cString: strerror(errno)))") } } }
Jun ’24
Reply to NWMulticastGroup returns POSIXErrorCode error
Thanks Quinn for replying. Really appreciate you taking the time to write your response. I have discovered a lot in the meantime. I now understand that are different broadcasting modes for UDP: Unicast, Broadcast en Multicast. TN3151: Choosing the right networking API - Explained: Network framework supports UDP multicast using the NWConnectionGroup class, but that support has limits and, specifically, it does not support UDP broadcast. If you need something that’s not supported by Network framework, use BSD Sockets. The game on console was using broadcast mode to broadcast data using UDP. I wrongfully assumed it was the same as multicast. As has been mentioned in TN3151 Apple does not support UDP broadcast. Hopefully this will change in the future. Having said that, coming back to your questions: Are all the peers Apple devices? Or do you have a hardware accessory involved? A game broadcasts data via UDP. So other than my app that is reading and visualizing that data to the user no Apple devices are involved. What is role of each peer? The role of each peer is just to receive the data being broadcasted by the game and processing it in different ways. Is all traffic multicast? Or do you switch to unicast at some point? Traffic is broadcast. I made a mistake. The game is able to switch between unicast and broadcast. Unicast works with the Network Framework, broadcast doesn't. Which is a shame, would be incredibly useful if it were. Is this IPv4? Or IPv6? Or both? This is IPv4. What multicast address do you plan to use? And port? The source (game) will broadcast the data to ALL machines on a local area network on a specific port. And do you use the same port for both the source and destination? Correct. I was able to create code that made it work without the Network Framework. class UDPBroadcastReceiver { private var socketDescriptor: Int32 = -1 private let port: UInt16 private let queue = DispatchQueue(label: "UDPBroadcastReceiverQueue") init(port: UInt16) { self.port = port setupSocket() } private func setupSocket() { socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) guard socketDescriptor > 0 else { print("Failed to create socket") return } var broadcastEnable: Int32 = 1 let broadcastEnableSize = socklen_t(MemoryLayout.size(ofValue: broadcastEnable)) setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, broadcastEnableSize) var address = sockaddr_in( sin_len: __uint8_t(MemoryLayout<sockaddr_in>.size), sin_family: sa_family_t(AF_INET), sin_port: in_port_t(port.bigEndian), sin_addr: in_addr(s_addr: INADDR_ANY), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0) ) let bindResult = withUnsafePointer(to: &address) { $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { bind(socketDescriptor, $0, socklen_t(MemoryLayout<sockaddr_in>.size)) } } guard bindResult == 0 else { print("Failed to bind socket") close(socketDescriptor) return } print("Socket setup and bound to port \(port)") receive() } private func receive() { queue.async { var buffer = [UInt8](repeating: 0, count: 1024) while true { let bytesRead = recv(self.socketDescriptor, &buffer, buffer.count, 0) if bytesRead > 0 { let data = Data(buffer[0..<bytesRead]) // To Do: Parse data } else if bytesRead == 0 { print("Socket closed by peer") break } else { print("Error receiving data: \(String(cString: strerror(errno)))") break } } } } deinit { if socketDescriptor > 0 { close(socketDescriptor) } } }
Jun ’24
Reply to Apple Watch cannot reconnect
Xcode 15 Beta 8 the issue has not been resolved. Updated iPhone en Watch to the latest developer version Unpaired the Watch and then pair it again Turned Wifi off on the Mac, Turned it back on Opened the Watch app on the iPhone Turned airplane mode on all and back on Deleted everything in the cache (~/Library/Developer/Xcode) Nothing works.
Aug ’23
Reply to Apple Watch cannot reconnect
Seeing the same issue with Xcode 15 Beta 7 even though it says watchOS connectivity has been resolved. It says Waiting to reconnect to Apple Watch van Mark, Xcode will continue when the operation completes. (See image) I tried: Completly erasing the Apple Watch Update iPhone to the latest Public Beta version Update Apple Watch to latest Public Beta version Repair the Apple Watch with the iPhone Connecting the iPhone with a cable Nothing helped.
Aug ’23
Reply to How can an app be deminimized when clicking on its app icon in a full SwiftUI app?
Appearantly no Apple engineer or community member knew the answer. I finally found a work-around and I am happy to share it with the people also struggling with the same issue which still exists in the latest Xcode Beta. import SwiftUI @main struct YourApp: App {   @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate       var body: some Scene {     WindowGroup {       MainView()     }   } } class AppDelegate: NSObject, NSApplicationDelegate {      func applicationDidBecomeActive(_ notification: Notification) {     if let window = NSApp.windows.first {       window.deminiaturize(nil)     }   }       func applicationDidChangeOcclusionState(_ notification: Notification) {     if let window = NSApp.windows.first, window.isMiniaturized {       NSWorkspace.shared.runningApplications.first(where: {         $0.activationPolicy == .regular       })?.activate(options: .activateAllWindows)     }   } }
Jun ’22
Reply to Dynamic call blocking
We are now in the year 2021 where Apple just introduced iOS 15. Looking at the CallKit documentation there is has not been an update. I really don't understand why you have to enter a list of numbers while patterns can be so much more efficient. Unwanted phone calls are a growing pain. Please Apple LISTEN to the feedback of your customers! If you want to block certain country codes you need to generate and add millions of phone numbers in the way the current API is build up. It's awkward.
Oct ’21
Reply to How should I access @AppStorage and @SceneStorage values outside of views?
I don't really understand your question, but I wrote an article about everything you should about @AppStorage and @SceneStorage on Medium, which might answer your question better. Perhaps you don't realize that with defining @AppStorage you defined a source-of-truth. If you need to access it "outside" the views perhaps its better to place the @AppStorage somewhere higher in the view hierarchy and pass it with bindings. Links: Introducing @AppStorage in SwiftUI (medium.com/swlh/introducing-appstorage-in-swiftui-470a56f5ba9e) Introducing @SceneStorage in SwiftUI: (medium.com/@crystalminds/introducing-scenestorage-in-swiftui-5a4ec1a90ca3)
Oct ’20
Reply to How to add UISearchController in SwiftUI?
UISearchController works when attached to a List. It becomes buggy when you use something other like a ScrollView or VStack. I have reported this in Apple's Feedback app and I hope others will do the same. Never the less if you like to include a UISearchController in your App. I created a Swift Package at Github named NavigationSearchBar. - https://github.com/markvanwijnen/NavigationSearchBar
Sep ’20