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
}
}