ios – Multipeer Connectivity Issue: Peer is lost when sending invite

[ad_1]

I am trying to establish a connection between two iOS devices using multiplier connectivity framework. I am able to find the nearby devices and add them to an array.
What I want to do is, allow a user to see all nearby connections and tap on anyone to connect with. For example, I find two nearby available Peers PeerA and PeerB. If I tap on PeerA then it should send an invite to PeerA. I am doing all of this on custom UI. So what happens is when I send the invite to any peer, the peer gets disconnected & the below function gets called.

func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
    print("Peer lost \(peerID.displayName)")
    if let p = self.availablePeers[peerID.displayName] as? CustomPeer{
        self.availablePeers[peerID.displayName] = nil
        print("Remove from list")
    }
    print("Lost Peer")
}

Here is my complete connection.swift file that have to logic to connect with peers.

//  Connection.swift
//  Prevue
//
//  Created by Prevue on 29/08/2022.
//

import Foundation
import MultipeerConnectivity

class CustomPeer{
    var info: [String: Any]?
    var peerID: MCPeerID!
}


class Connection: NSObject{
    
    static let ServiceType = AppStrings.ConnectionServiceType
    
    var peerID: MCPeerID!
    var session: MCSession!
    var advertiser: ServiceAdvertiser!
    var browser: BrowserService!
    
    var availablePeers = [String: CustomPeer]()
    
    
    var didReceiveFrame: ((UIImage)-> Void)?
    

    // just for testing.
    func startDiscoveryAndAdvertising(with displayName: String){
        peerID = MCPeerID(displayName: displayName)
        
        var info = ["name": displayName, "id": displayName + "_" + String(Int.random(in: 1..<400)), "email": displayName + "@gmail.com"]
        self.advertiser = ServiceAdvertiser(peerID: peerID, serviceType: "Prevue", discoverInfo: info, delegate: self)
//        advertiser
        self.session = MCSession(peer: peerID, securityIdentity: nil,    encryptionPreference: .none)
        self.browser = BrowserService(peerID: peerID, serviceType: "Prevue", delegate: self)
        advertiser.advertiser.startAdvertisingPeer()
        browser.browser.startBrowsingForPeers()
    }
    
    
    func startDiscoveryAndAdvertising(with user: Profile){
        peerID = MCPeerID(displayName: "\(user.id)")
        
        var info = ["name": user.name, "id": String(user.id), "email": user.email]
        self.advertiser = ServiceAdvertiser(peerID: peerID, serviceType: "Prevue", discoverInfo: info, delegate: self)
//        advertiser
        self.session = MCSession(peer: peerID, securityIdentity: nil,    encryptionPreference: .none)
        self.browser = BrowserService(peerID: peerID, serviceType: AppStrings.ConnectionServiceType, delegate: self)
        advertiser.advertiser.startAdvertisingPeer()
        browser.browser.startBrowsingForPeers()
    }
    
    func sendData(data: Data){
        guard let session = self.session else{
            return
        }
        do{
            try session.send(data, toPeers: self.session.connectedPeers, with: .reliable)
        }
        catch let error {
        }
    }
    
    func sendInvite(to user: Profile){
        guard let customPeer = self.availablePeers["\(user.id)"] as? CustomPeer, let peerID = customPeer.peerID else{
            return
        }
        guard let user = UserDefaultsService.getProfileDataFromDefaults()?.profile else{
            return
        }
        let d = ["user_id": user.id, "name": user.name, "persona": currentPersona.rawValue]
        as [String : Any]
        self.browser.browser.invitePeer(peerID, to: self.session, withContext: nil, timeout: TimeIntervals.Interval0)

    }
    
    
    func isUserReachable(user: Profile)-> CustomPeer?{
        print("Available peers ")
        print(self.availablePeers)
        if let p = self.availablePeers["\(user.id)"] as? CustomPeer{
            return p
        }
        
        return nil
    }
    
}


extension Connection: MCSessionDelegate{
    func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
        switch state {
            case .connected: print ("connected \(peerID)")
            case .connecting: print ("connecting \(peerID)")
            case .notConnected: print ("not connected \(peerID)")
            default: print("unknown status for \(peerID)")
          }
    }
    func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
        
        
        
        if let dict = NSKeyedUnarchiver.unarchiveObject(with: data) as? [String:Any]  {
            // first check for captured photo
            if let photoData = dict["capturedPhoto"] as? Data, let image = UIImage(data: photoData) {

            }
            else{
                guard let imageData = dict["image"] as? Data else {
                    return
                }
                guard let image = UIImage.init(data: imageData, scale: 2.0) else {
                    return
                }
                if self.didReceiveFrame != nil{
                    self.didReceiveFrame!(image)
                }
                print(peerID.displayName)
                
            }
            

        }
        else{
            let commandString = String.init(data: data, encoding: String.Encoding.utf8)
            if commandString == "raiseFramerate" {

            } else if (commandString == "lowerFramerate") {
                
            }
        }
        
        
    }
    func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
        
    }
    func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) {
        
    }
    func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL?, withError error: Error?) {
        
    }
    func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
        
    }
    func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
        
    }
}

//Browser delegate
extension Connection: MCNearbyServiceBrowserDelegate{
    func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) {
        print("Peer available \(peerID.displayName)")
        print(info)
        let p = MCPeerID(displayName: peerID.displayName)
        var customPeer = CustomPeer()
        customPeer.info = info
        customPeer.peerID = p

        self.availablePeers[p.displayName] = customPeer
        print("Found Peer \(p.displayName)")
    }
    
    
    func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {
        print("Peer lost \(peerID.displayName)")
        if let p = self.availablePeers[peerID.displayName] as? CustomPeer{
            self.availablePeers[peerID.displayName] = nil
            print("Remove from list")
        }
        print("Lost Peer")
    }
    
    
}

extension Connection: MCNearbyServiceAdvertiserDelegate{
    
    
    func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
        // when a peer sends an invitation to connect. We show the custom dialogue here
        if let d = context{
            do{
                let json = try JSONSerialization.jsonObject(with: d) as? [String: Any]
                print(json)
                print("Someone wants to connect")
            }
            catch let error{
                print(error.localizedDescription)
            }
        }
        
            
    }
    func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: Error) {
            NSLog("%@", "didNotStartAdvertisingPeer: \(error)")
    }
}

[ad_2]

Source link

Leave a Reply

Your email address will not be published.