Search code examples
iosiphonegamekitgkturnbasedmatch

GKTurnBasedMatch after creating/joining a match prints 2nd player status as matching?


By using GKTurnbaseMatch default matchmaking scenario, I'm able to connect to a match. I can also create a new match both programmatically and using default view controller. I can also find out list of matches created the local user in the Game Centre both programmatically and with default view controller. But there's always my turn is mentioned, because I haven't called end turn with next participant. 1. After match being connected, didFindMatch is called and the received match object doesn't print the expected 2nd player's ID, whereas it prints the status of that player as 'matching'.

 //#3
func turnBasedMatchmakerViewController(_ viewController: GKTurnBasedMatchmakerViewController,
didFind match: GKTurnBasedMatch)
{
    print(match)
    match.loadMatchData { (d, e) in

        print(d)
        print(e)

    }


    self.dismiss(animated: true, completion: nil)
    //performSegue(withIdentifier: "GamePlayScene", sender: match)
}

This match prints as follows.

[
<GKTurnBasedParticipant 0x60000000c430 - playerID:G:25153527799 (local player) status:Active matchOutcome:None lastTurnDate:(null) timeoutDate:(null)>,
<GKTurnBasedParticipant 0x60000000cd50 - playerID:(null)   status:Matching matchOutcome:None lastTurnDate:(null) timeoutDate:(null)>

]

How could I connect the two players.

  1. I can find all the matches created by local player, is there any way of finding list of empty matches created by anyone in the game centre.

  2. How to join a match with match ID?


Solution

  • This answer states some of the very basic issues as been interrogated in the above statement, specifically for those who may face similar hurdles in future. At the very first, its really important to mention, that GKTurnBasedMatchs wouldn't fill up the empty places in the match participants array for a new match, except you end up your turn. That's why I really got into trouble where I was creating new matches on both the devices, but couldn't able to match the both. Therefore participants array on both the sides was printing what actually I was asking in the above question. It was printing first participant as local player for both the devices. Fortunately, after reading out This Tutorial, I've found that creator of the match must have to resign by ending its turn in order to make the match opened for other seekers. In this way only a new participant could find out your match's empty slot.

    Now before ending your turn, you must have to select participant for the next turn, although your match.participants array will have dummy participants with statuses as matching for each and playerIDs of definitely null, but you have to assume them as the other players of your match.

    Therefore, you have to assign next participant to index 0 of the array you would put in with ending your turn. Also you have to create a new data object with your match status for the first time, because before this there will be match data also null.

    Here is the myMatch.endTurn in my case with dummy data of Dictionary type.

     @IBAction func endMyTurn(_ sender: Any) {
    
        // This is sincerely for Ending Turn
        var dictionaryExample = [String:Any]()
        dictionaryExample = ["name": "Asim", "value": 2]
    
    
    
        let dataToSend: Data = NSKeyedArchiver.archivedData(withRootObject: dictionaryExample)
    
    
    
        if (myMatch?.participants?.count)! > 0
        {
    
            // Match is started
            var pArray : [GKTurnBasedParticipant] = myMatch!.participants!
            let currenParticipantIndex : Int = (myMatch!.participants?.index(of: myMatch!.currentParticipant!))!
    
            pArray.remove(at: currenParticipantIndex)
    
            let currentParticipant = myMatch?.currentParticipant
            pArray.append(currentParticipant!)
    
            myMatch?.endTurn(withNextParticipants: pArray, turnTimeout: GKTurnTimeoutDefault, match: dataToSend, completionHandler: { (e) in
                print(e ?? "No Error:")
            })
    
        }
        else
        {
            // No Match
    
    
        }
    
    
    
    
    
    }
    

    Now after ending your turn, for the first time your find match will start showing Their Turn for this match, and won't allow you to play till further end turn by your opponent. enter image description here

    Asim K. is the other player allotted to your match's empty slot.

    NOTE: This will be shown after finding out the next player by Game Centre and may take a while in real matches, but in testing it would only happens if you test your app with different Game Centre account.

    **NOTE: This will remain as it is till the next player won't his/her turn. **

    For player 2 finding a match, this gonna happen. turnBasedMatchmakerViewController(_ viewController: GKTurnBasedMatchmakerViewController, didFind match: GKTurnBasedMatch) will be called when match is found/selected from the list, with match data and completely filled array of participants(in my case only 2).

    //#3
    func turnBasedMatchmakerViewController(_ viewController: GKTurnBasedMatchmakerViewController,
    didFind match: GKTurnBasedMatch)
    {
        print(match)
        myMatch = match
        match.loadMatchData { (d, e) in
    
            print(d ?? "No Data:")
            let recievedData: [String: Any] = (NSKeyedUnarchiver.unarchiveObject(with: d!) as? [String : Any])!
    
    
            // Check if data contains : "name" .. "value"
            if recievedData["name"] != nil && recievedData["value"] != nil
            {
    
                let name = recievedData["name"] as! String
                let val = recievedData["value"] as! Int
    
                print("First Item: \(name)")
                print("Second Item: \(val)")
    
            }
    
    
            print(e ?? "No Error:")
    
        }
    
    
        self.dismiss(animated: true, completion: nil)
        //performSegue(withIdentifier: "GamePlayScene", sender: match)
    }
    

    Here is the final output in player 2's case. enter image description here