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.
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.
How to join a match with match ID?
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.
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)
}