Search code examples
swiftgame-centergamekit

fatal error: can't unsafeBitCast between types of different sizes (using gamekit)


Using GameKit Multiplayer feature (EasyGameCenter) found here: https://github.com/DaRkD0G/Easy-Game-Center-Swift

Upon two players connecting I get a crash on this line

let playerIDs = match.players.map { $0 .playerID } as! [String]

With this in console

fatal error: can't unsafeBitCast between types of different sizes

Any ideas? Here is full function for easy reference:

 @available(iOS 8.0, *)
    private func lookupPlayers() {

        guard let match =  EGC.sharedInstance.match else {
            EGC.printLogEGC("No Match")
            return
        }

        let playerIDs = match.players.map { $0 .playerID } as! [String]

        /* Load an array of player */
        GKPlayer.loadPlayersForIdentifiers(playerIDs) {
            (players, error) in

            guard error == nil else {
                EGC.printLogEGC("Error retrieving player info: \(error!.localizedDescription)")
                EGC.disconnectMatch()
                return
            }

            guard let players = players else {
                EGC.printLogEGC("Error retrieving players; returned nil")
                return
            }
            if EGC.debugMode {
                for player in players {
                    EGC.printLogEGC("Found player: \(player.alias)")
                }
            }

            if let arrayPlayers = players as [GKPlayer]? { self.playersInMatch = Set(arrayPlayers) }

            GKMatchmaker.sharedMatchmaker().finishMatchmakingForMatch(match)
            (Static.delegate as? EGCDelegate)?.EGCMatchStarted?()

        }
    }

Solution

  • The problem is that your map statement is resulting in a type of Array<String?> because playerID is a String?, which you can't cast directly to Array<String>.

    If you're certain you will always have a playerID value, you could change the statement

    match.players.map { $0.playerID }
    

    to:

    match.players.map { $0.playerID! }
    

    If you're not certain of that, then you can either use the Array<String?> value with appropriate optional handling or strip out the nil values by switching from map to flatMap:

    match.players.flatMap { $0.playerID }