Post

Replies

Boosts

Views

Activity

Reply to NWConnection's connection.receiveMessage method gets breakpoint hit but callback not entered
I found the answer to my problem here - https://www.example.com/ @eskimo said: . TCP is not a message-oriented protocol, and thus  receiveMessage(…) doesn’t make any sense [1]. What you want is  receive(minimumIncompleteLength:maximumLength:completion:) And he is 100% correct, as soon as I changed signatures, the callback was entered: connection.receive(minimumIncompleteLength: 1, maximumLength: 8192) { [weak self](data, context, isComplete, error) in     print("\n*** call back entered *** ")     if let err = error {         print("Recieve error: \(err.localizedDescription)")         return     }     print("databytes", data?.count as Any)     if let data = data, !data.isEmpty {         print("Receive is complete")         self?.received(data, from: connection)     } } The multiple calls is still happening be that's another question that I'll ask in a different post. PS I don't know why I have 3 different usernames under the same account lsamaria - https://developer.apple.com/forums/profile/lsamaria is the same person as ohmannnnnn - https://developer.apple.com/forums/profile/ohmannnnnn who is the same person as lance145 - https://developer.apple.com/forums/profile/lance145
Dec ’20
Reply to NWConnection's connection.receiveMessage method gets breakpoint hit but callback not entered
Here is the reason for the the multiple call problem, which isn't a problem, as explained by @eskimo here: - https://developer.apple.com/forums/thread/654953 Apple’s connect-by-name API uses a fancy algorithm to run multiple connections in parallel to see which one connects first (see RFC 8305 for - https://tools.ietf.org/html/rfc8305 some background on this)
Dec ’20
Reply to How to add a String to NWProtocolTLS.Options()?
Here is the reason for the the multiple call problem, which isn't a problem, as explained by @eskimo here: - https://developer.apple.com/forums/thread/654953 Apple’s connect-by-name API uses a fancy algorithm to run multiple connections in parallel to see which one connects first (see RFC 8305 for - https://tools.ietf.org/html/rfc8305 some background on this)
Dec ’20
Reply to NWConnection connection.stateUpdateHandler .cancelled state doesn't fire
It turns out this seems to be an issue with the simulator. I've been playing around and searching the internet for 12 hrs and nothing. I finally tried it out on my real device and 2 simulators. I sent the real device to the background and the connection.stateUpdateHandler's .failed and .cancelled worked fine on the simulators. On the reverse when I sent either of the simulators to the background the real device's connection.stateUpdateHandler didn't get hit. I don't have another real device on hand to try to see what happens with 2 real devices. This is a strange issue. Any ideas out there?
Dec ’20
Reply to Combine multiple outgoing NISessions with multiple NINearbyPeerConfiguration objects when data is received using Bonjour
I couldn't add these because the Edit button disappeared. 1- For clarity sendDataWhenNewDeviceIsDiscovered() {...} will run every time a new device is discovered but there will only be 20 sessions at a time. This won't stop it from running but the incomingData will never be added if the sessions are at 20. 2- In place of: var sessions = [MyAppUserID: NISession]() I used: var sessions = [String: NISession]() The problem is because the current user's userId is always the key, it will only have one key the will write always over its value self.sessions[currentUserId] = session I wasn't sure what was supposed to happen here. Did you mean: var sessions = [NISession: MyAppUserID]() or var sessions = [NISession: String]()
Dec ’20
Reply to NISessionDelegate -How to convert distance property into meters?
I got the answer from here: - https://github.com/fitomad/NearbyInteraction-Guide/blob/master/NearbyInteraction-Framework-Guide.md The distance is a Float type whose value is measured in meters: func session(_ session: NISession, didUpdate nearbyObjects: [NINearbyObject]) {		 		guard let object = nearbyObjects.first else { return }          		 		guard let distance = object.distance else { return }  		let meters = String(format: "%.2f m", distance) 		print("meters: ", meters) }
Jan ’21
Reply to NWConnection -no Echo from connection.send(content: data, completion : .idempotent)
@eskimo Thanks for the reply. Here are the successful print statements: The Initial Send does not send a color, it just sends some data like a String message : print("Sent") // successful After the Initial Send sends the message and it is first received, I didn't add a print statement for a successful reception but the code inside Receive data and send Echo response is successful, specifically if let data = data, !data.isEmpty { // successful only once } Inside there, the data that is decoded, only has the String message from above, the color isn't sent yet so the colorData decoding is skipped. However once the String message is received, I send an echo with the colorData connection.send(content: colorData, ... { } Inside the completionHandler of the echo, this print statement always runs: print("Color data sent") // successful At that point the other device, the Receive Data receives nothing, there isn't a response whatsoever. Nothing prints, it's as if the connection got cut off after the first reception. I put breakpoints everywhere but none of them get hit.
Apr ’21
Reply to NWConnection endPoint info duplicated
@eskimo ok thanks for the answer. I'll start a new thread about the issue that you just identified. As far as this one, how do I know who is talking to who by using self inside the receive(_:) method? Once a sender sends a message, I used these for the receiver to identify the sender: let endPointDescription = connection.currentPath?.localEndpoint?.debugDescription ... encode then send let remoteEndPoint = connection.currentPath?.remoteEndpoint?.debugDescription ... encode then send // they both get sent together This works fine when detecting when either end is cut off, for example if Device_A is connected to Device_B, if Device_B goes to the background the connection is cut and Device_A immediately knows about it. I haven't had any problems even when using 3 devices and 2 simulators. They all will know that Device_B has left the building and respond accordingly.
Apr ’21
Reply to NWConnection -no Echo from connection.send(content: data, completion : .idempotent)
Yes, they both have the same exact code. Btw neither device receives the echo but they both receive that first message. Here is startOutgoingConnection, actually here is PeerConnection because it is 1 class that has 2 initializers, one for outgoing and one for incoming. I put break points everywhere but nada on that 2nd incoming message. protocol PeerConnectionDelegate: class {     func sendOutgoing(_ connection: NWConnection)     func receivedIncoming(_ connection: NWConnection) } class PeerConnection: Hashable {     static func == (lhs: PeerConnection, rhs: PeerConnection) - Bool {         return lhs.connection?.endpoint.debugDescription == rhs.connection?.endpoint.debugDescription     }     func hash(into hasher: inout Hasher) {         guard let connection = connection else { return }         hasher.combine(connection.endpoint.debugDescription)     }     weak var delegate: PeerConnectionDelegate?     public var connection: NWConnection? // Outgoing     init(endPoint: NWEndpoint, delegate: PeerConnectionDelegate) {         self.delegate = delegate         let tcpOptions = NWProtocolTCP.Options()         tcpOptions.enableKeepalive = true         tcpOptions.keepaliveIdle = 2         let parameters = NWParameters(tls: nil, tcp: tcpOptions)         parameters.includePeerToPeer = true         parameters.allowLocalEndpointReuse = true         connection = NWConnection(to: endPoint, using: parameters)         startOutgoingConnection()     } // Incoming     init(connection: NWConnection, delegate: PeerConnectionDelegate) {         self.delegate = delegate         self.connection = connection         startIncomingConnection()     }     func startIncomingConnection() {         guard let connection = connection else { return }         connection.stateUpdateHandler = { [weak self](nwConnectionState) in             switch nwConnectionState {             case .preparing: print("preparing")             case .setup: print("setting up")             case .waiting(let error): print("\(error.localizedDescription)")             case .ready:                 self?.delegate?.receivedIncoming(connection)             case .cancelled:                 connection.cancel() // remove incoming connection from an array that holds it/them and remove corresponding cell             case .failed(let error):                 connection.cancel()                 // remove incoming connection from an array that holds it/them and remove corresponding cell             default:break             }         }         connection.start(queue: .main)     }     func startOutgoingConnection() {         guard let connection = connection else { return }         connection.stateUpdateHandler = { [weak self](nwConnectionState) in             switch nwConnectionState {             case .preparing: print("preparing")             case .setup: print("setting up")             case .waiting(let error): print(error.localizedDescription)             case .ready:                 self?.delegate?.sendOutgoing(connection)             case .cancelled:                 connection.cancel() // remove outgoing connection from an array that holds it/them             case .failed(let error):                 connection.cancel() // remove outgoing connection from an array that holds it/them             default:break             }         }         connection.start(queue: .main)     } } The connection isn't failing on either end/device because once it is cancelled I remove data from both devices which never happens after they both send and receive messages from each other. For example Device_A sends its info to Device_B and vice versa. I have a cell that shows the connection info String data like connection.endpoint.debugDescription and the uid from the opposite device. Once either device goes to the background and the connection is cancelled then both devices remove the corresponding cell. If the connection was cancelled after the initial send/receive then both cells (the cell on each device) would immediately disappear.
Apr ’21
Reply to NWConnection endPoint info duplicated
Yes, TCP and Websocket, here is the send message: let info = // some String info guard let data = try? NSKeyedArchiver.archivedData(withRootObject: info, requiringSecureCoding: true) else { return } let message = NWProtocolWebSocket.Metadata(opcode: .text) let context = NWConnection.ContentContext(identifier: "send", metadata: [message]) connection.send(content: data, contentContext: context, isComplete: true, completion: .contentProcessed({ (error) in if let error = error { print("\(error.localizedDescription)"); return } print("Success") })) The NWListener, NWBrowser, and NWConnection all are initialized with let tcpOptions = NWProtocolTCP.Options() inside their NWParameters.
Apr ’21
Reply to Disabling Callkit for China Apps
I found this answer - https://stackoverflow.com/a/51319158/4833705 on Stack Overflow. The work around is whatever view controller that is using CallKit you simply make sure that it doesn't get initialized inside that view controller if the country is China. Like this var callObserver: CXCallObserver? override func viewDidLoad() { super.viewDidLoad() if Locale.current.regionCode != "CN" || Locale.current.regionCode != "CHN" { // only init for countries that aren't China callObserver = CXCallObserver()     } }
Apr ’21