Post

Replies

Boosts

Views

Created

NISessionDelegate -How to convert distance property into meters?
In the delegate method below, distance is of type Float: func session(_ session: NISession, didUpdate nearbyObjects: [NINearbyObject]) { 		guard let object = nearbyObjects.first else { return }           guard let distance = object.distance else { return }           print("distance is of type Float but I need to convert to meters: ", distance) } How do I convert distance into meters so that I can find out exactly how far the peers are from one another?
1
0
727
Jan ’21
Combine multiple outgoing NISessions with multiple NINearbyPeerConfiguration objects when data is received using Bonjour
Because of the 8 peer limit I'm using NWListener, NWBrowser, NWConnection, and Bonjour for up to 20 peer-to-peer concurrent connections. I followed this answer - https://developer.apple.com/forums/thread/652180 and this answer - https://developer.apple.com/forums/thread/661148 which are both from Apple engineers. The first one said to create multiple concurrent NISessions: All NISessions are peer-to-peer and as a result, creating multiple NISession objects is necessary to have multiple concurrent sessions. One approach is to create a dictionary between an identifier for the peer (i.e. a user identifier provided by your app MyAppUserID) and the NISession objects while also keeping track of the NIDiscoveryToken for each peer identifier:  var sessions = [MyAppUserID: NISession]() var peerTokensMapping = [NIDiscoveryToken: MyAppUserID]() And the second answer said to perform interactions with multiple iPhones: Create an NISession for each peer you would like to interact with. For example, if you are interacting with two peers, create 2 * NISession objects. Each NISession will have a unique NIDiscoveryToken associated with it. Share discovery token #1 with peer #1, and share discovery token #2 with peer #2. When you receive discovery tokens from peers #1 and #2, create 2 * NINearbyPeerConfiguration objects and use them to run sessions #1 and #2, respectively. The problem is when sending out a NIDiscoveryToken via NWConnection, I can't find a way to link to the NISession from the sent out data to the token that is received from the incoming data after I initialize a NINearbyPeerConfiguration object: eg. User object which is sent and received when other devices are discovered class User: NSObject, NSSecureCoding { 		var uid: String? 		var peerToken: NIDiscoveryToken? = nil 		init(uid: String, peerToken: NIDiscoveryToken) {...} 		// ... encoder for uid and peerToken 		// ... decoder for uid and peerToken } Send current user's NIDiscoveryToken data via NWBrowser and NWConnection and save it to the peerTokensMapping dictionary and save the session to the sessionsArr let currentUserId = "qwerty" var sessionsArr = [NISession]() var sessions = [String: NISession]() var peerTokensMapping = [NIDiscoveryToken: String]() func sendDataWhenNewDeviceIsDiscovered() { 		let session = NISession() 		session.delegate = self 		guard let myToken = session.discoveryToken else { return } 		let user = User(uid: currentUserId, peerToken: myToken) 		guard let outgoingData = try? NSKeyedArchiver.archivedData(withRootObject: user, 																														 requiringSecureCoding: true) 		else { return } 		let message = NWProtocolWebSocket.Metadata(opcode: .text) 		let context = NWConnection.ContentContext(identifier: "send", metadata: [message]) 		connection.send(content: outgoingData, contentContext: context, isComplete: true, completion: .contentProcessed({ [weak self](error) in             		if let error = error { return } 				self?.sessionsArr.append(session) 				self?.peerTokensMapping[myToken] = self!.currentUserId     		print("Successfully Sent") 		})) } Receive other user's NIDiscoveryToken data via NWListener and NWConnection. connection.receive(minimumIncompleteLength: 1, maximumLength: 65535) { 		[weak self](data, context, isComplete, error) in 		if let err = error { return } 		if let data = data, !data.isEmpty { 				self?.decodeReceived(data) 		} } func decodeReceived(_ data: Data) { 		guard let incomingData = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? User 		else { return } 		guard let uid = incomingData.uid, let peerToken = incomingData.peerToken 		else { return } 		let config = NINearbyPeerConfiguration(peerToken: peerToken) 		/* not sure what to do here to get the session that was created when the data was sent out */ 		for (key,_) in peerTokensMapping { 				if key.??? == peerToken.??? { 						session.run(config) 						self.sessions[currentUserId] = session 						break 				} 		} 		/* or try this but this is the other user's peerToken so this will never work */ 		for session in self.sessionsArr { 				if session.discoveryToken ?? "" == peerToken { 						session.run(config) 						self.sessions[currentUserId] = session 						break 				} 		} } Once the NINearbyPeerConfiguration is initialized how do I connect the incoming peerToken with the correct one that was sent out above that is currently inside the peerTokensMapping dict or the sessionsArr so that I can get the session and call session.run(config)
1
0
1.7k
Dec ’20