App is crashing on first run, but works on sequential ones. And UserState text is not working

40 Views Asked by At

Why is my app crashing whenever I press the host button for the first time. It happens when the invite function is called. It works when I close the app and try again. I am not sure why, because shouldn't it work every time, if it works sequentially? Also, I can't get the user.userState text to show up.

import SwiftUI
import MultipeerConnectivity

class userState {
    @State var userStatus: String = ""
}

var user = userState()


class synkeMultipeerSession: NSObject, ObservableObject {
    
    var peerID: MCPeerID
    var session: MCSession
    var nearbyServiceAdvertiser: MCNearbyServiceAdvertiser?
    
    override init() {
        peerID = MCPeerID(displayName: UIDevice.current.name)
        session = MCSession(peer: peerID, securityIdentity: nil, encryptionPreference: .required)
        super.init()
        session.delegate = self
        
    }
    
    func advertise() {
        nearbyServiceAdvertiser = MCNearbyServiceAdvertiser(peer: peerID, discoveryInfo: nil, serviceType: "gt-synke")
        nearbyServiceAdvertiser?.delegate = self
        nearbyServiceAdvertiser?.startAdvertisingPeer()
    }
    
    func invite() {
        let browser = MCBrowserViewController(serviceType: "gt-synke", session: session)
        browser.delegate = self
        UIApplication.shared.rootViewController?.present(browser, animated: true)
        
    }
}

var mpSession: synkeMultipeerSession  = synkeMultipeerSession()

struct SelectionScreenView: View {
    var isHosting = false
    var isJoining = false
    var body: some View {
        ZStack{
            skyBlue
                .ignoresSafeArea()
            Text("Choose to either host, or join others ")
                .foregroundColor(.white)
                .offset(x:10, y:-145)
                .frame(width: 385, height: 200, alignment: .topLeading)
                .font(.system(size:40).bold())
            Button("Host") {
                mpSession.advertise()
                user.userStatus = "You are now hosting."
            }
            .offset(x:-75)
            .foregroundColor(.red)
            .font(.system(size: 35).bold().italic())
            .padding(.all)
            .buttonStyle(.bordered)
            
            Button("Join") {
                user.userStatus = "Joining"
                mpSession.invite()
            }
            .offset(x:74)
            .foregroundColor(.blue)
            .font(.system(size: 35).bold().italic())
            .padding(.all)
            .buttonStyle(.bordered)
            
            Text(user.userStatus)
                .foregroundColor(.white)
                .offset(x:10, y:200)
                .frame(width: 385, height: 200, alignment: .topLeading)
                .font(.system(size:40).bold())
        }
    }
    
    
    struct SelectionScreenView_Previews: PreviewProvider {
        static var previews: some View {
            SelectionScreenView()
        }
    }
    
}


extension synkeMultipeerSession: MCSessionDelegate {
    func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {
        switch state {
        case .connecting:
            print("\(peerID) state: Connecting...")
        case .connected:
            print("\(peerID) state: Connected.")
            user.userStatus = "You are now successfully connected as a peer."
        case .notConnected:
            print("\(peerID) state: Not Connected.")
        @unknown default:
            print("\(peerID) state: Unknown.")
        }
    }
    
    func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
        
    }
    
    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?) {
        
    }
}

extension synkeMultipeerSession: MCNearbyServiceAdvertiserDelegate {
    func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
        invitationHandler(true, session)
        
    }
}

extension synkeMultipeerSession: MCBrowserViewControllerDelegate {
    func browserViewControllerDidFinish(_ browserViewController: MCBrowserViewController) {
        browserViewController.dismiss(animated: true)
    }
    
    func browserViewControllerWasCancelled(_ browserViewController: MCBrowserViewController) {
        browserViewController.dismiss(animated: true)
    }
    
    
}


extension UIApplication {
    var currentKeyWindow: UIWindow? {
        UIApplication.shared.connectedScenes
            .filter { $0.activationState == .foregroundActive }
            .map { $0 as? UIWindowScene }
            .compactMap { $0 }
            .first?.windows
            .filter { $0.isKeyWindow }
            .first
    }
    
    var rootViewController: UIViewController? {
        currentKeyWindow?.rootViewController
    }
}



0

There are 0 best solutions below