swift 3 gamecenter: number of participants are always 4 - ios

I made a TurnBased game that was working perfectly with swift 2.
I could successfully change the code to swift 3.2 and correct all the errors about 400, but there is one issue with the game centre that I can not figure out how to fix it.
When through gamecenter viewcontroler I set the number of the participant to “2Player” and then push “Invite Friends” the number of Player that I get is 4 instead of 2!
the gamecenter send a text message to the next participant in which the number of participant is 4 too.
This of course affect the rest of the program a problem that I didn’t have in Swift 2.
This is part of my code:
func joinTurnBasedMatch()
{
let request = GKMatchRequest()
request.minPlayers = 2
request.maxPlayers = 4
request.defaultNumberOfPlayers = 2
let tbvc = GKTurnBasedMatchmakerViewController(matchRequest: request)
tbvc.turnBasedMatchmakerDelegate = self
present(tbvc, animated: true, completion: nil)
}
func turnBasedMatchmakerViewController(_ viewController: GKTurnBasedMatchmakerViewController, didFind match: GKTurnBasedMatch)
{
self.dismiss(animated: true, completion: nil)
self.performSegue(withIdentifier: "To_ViewC_CG", sender: match)
print("*** Number OF Players ***")
print(match.participants!.count)
}
Do I need to add anything to my code or change anything in it?

The problem has been solved in the latest ios update.
Now it works perfectly.

Related

Firebase Phone Authentication - Long Delay & Multiple OTPs

I'm working on an iOS app project that involves Firebase's phone authentication. I have it working fine on simulator, my iPhone, and my iPad. However, now that I am in the TestFlight stage , my external testers are experiencing long delays in receiving their OTPs as well as receiving duplicates when they reach the ViewController where they enter the OTP code (This is probably due to them hitting the button multiple times).
I also have APNs enabled and working properly.
I don't have much code to share as I followed Firebase's documentation.
What could be some reasons for a long delay in receiving the OTP code from Firebase? I will be including an activity spinner in the project when users tap the sign-in button. However, I also don't want it to be spinning for a minute as users wait for their OTP.
#objc func phoneSignIn() {
guard let phoneNumber = startVerificationView.phoneNumberTextField.text else { return }
let completePhoneNumber = "+1\(phoneNumber)"
Auth.auth().settings?.isAppVerificationDisabledForTesting = isVerificationDisabled
PhoneAuthProvider.provider().verifyPhoneNumber(completePhoneNumber, uiDelegate: nil) { (verificationId, error) in
if error == nil {
guard let verifyId = verificationId else { return }
UserDefaults.standard.set(verifyId, forKey: "verificationId")
let vc = CheckVerificationViewController()
vc.modalPresentationStyle = .fullScreen
vc.completePhoneNumber = completePhoneNumber
self.navigationController?.pushViewController(vc, animated: true)
}
}
}
Also isVerificationDisabled is set to false.

Incoming GameCenter invite contains no players

I’m trying to get my game to allow 1 device (iPhone) to use GameCenter to invite a friend to play (iPad). I’m using the standard/default MatchMaker interface. The iPhone sends the invitation to the iPad which presents a notification.
When I press this notification the iPad’s ‘player(GKPlayer, didAccept: GKInvite)’ routine DOES get called.
#objc func player(_ playerMe: GKPlayer, didAccept invite: GKInvite) {
print("\n\n\t\tplayer \(playerMe.displayName)(\(playerMe.playerID)) did accept INVITE sent by \(invite.sender.displayName)(\(invite.sender.playerID))")
GKMatchmaker.shared().match(for: invite, completionHandler: {(InvitedMatch, error) in
print("\t\tplayers.count = \(InvitedMatch!.players.count)")
if error != nil {
print("INVITE ERROR: \(error.debugDescription)")
}
if InvitedMatch != nil {
print("\t\tSetting current match. (\(InvitedMatch.debugDescription))")
self.currentMatch = InvitedMatch
self.currentMatch?.delegate = self
// self.prepareMatch()
}
})
}
Output:
player Me(G:25139341913) did accept INVITE sent by ‎“-----”(G:12453976)
players.count = 0
Setting current match. (Optional(<GKMatch 0x282d39970 expected count: 1 seqnum: 0
G:12453976:unknown
reinvitedPlayers:(
)>))
The players array is EMPTY! Shouldn’t it at least have the inviter in there? The ‘expectedPlayerCount’ properly reflects 2 person matchRequest where 1 player (the inviter) is already a participant)
At no point was the ‘player(GKPlayer, didRequestMatchWithRecipients: [GKPlayer])’ called by either end.
So the iPad doesn’t have access to the players to setup the match, but the iPhone sees that the invitation was accepted, has 2 players, and moves on. The iPhone code:
func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFind match: GKMatch) {
print("\n\n\t\tMATCH FOUND\n\n")
viewController.dismiss(animated: true, completion: nil)
GKMatchmaker.shared().stopBrowsingForNearbyPlayers()
currentMatch = match
match.delegate = self
if Globals.gameState?.currentState is StateWaitingForMatch {
if currentMatch?.expectedPlayerCount == 0 {
prepareMatch()
}
}
}
So how do I get the iPad (recipient of the invitation) to see/include the players?
In the player(GKPlayer, invite: GKInvite) method create a GKMatchMakerViewController via
let mmvc = GKMatchmakerViewController(invite: invite!)
and then present it:
viewController.present(mmvc!, animated: true, completion: nil)

Issue connecting to play game using game center

I am facing the issue of Multiplayer Invitation endless Processing below is the detail.
open func player(_ player: GKPlayer, didAccept inviteToAccept: GKInvite) {
print("player is \(player) \nInvite is \(inviteToAccept)")
EGC.guestPlayerIdentifier = player.playerID
guard let gkmv = GKMatchmakerViewController(invite: inviteToAccept) else {
EGCError.error("GKMatchmakerViewController invite to accept nil").errorCall()
return
}
gkmv.matchmakerDelegate = self
var delegeteParent:UIViewController? = EGC.delegate.parent
if delegeteParent == nil {
delegeteParent = EGC.delegate
}
delegeteParent!.present(gkmv, animated: true, completion: nil)
}
On average only 1 out of 5 tries would they be able to connect & play a
full match.
If one of them invited another who had the game open on his phone
he would get the invite and game would start but for the other, the game
would be blank or endlessly processing. However, if the invited didn't
have his game opened already it seemed to work more often. any help would be appreciated
.

iOS turn based match, push notifications not working, GKTurnBasedEventListener functions not called

In my iOS turn based match, I'm trying to receive notifications and to get the
public func player(_ player: GKPlayer, receivedTurnEventFor match: GKTurnBasedMatch, didBecomeActive: Bool)
to be called, with no success.
I register my view model to the local player
GKLocalPlayer.localPlayer().register(self)
and I would expect that to fire after the other player executes
func endTurn(withNextParticipants nextParticipants: [GKTurnBasedParticipant], turnTimeout timeout: TimeInterval, match matchData: Data, completionHandler: ((Error?) -> Swift.Void)? = nil)
but no success.
If I force a reload of the matchData then I will get the data the second player just submitted. So the endTurn works correctly.
Is there something I'm doing wrong?
Update:
So I create a new project, copied all my files over,
in the capabilities only Game Center was enabled.
When developing it was working perfect, I had two devices attached (with different apple IDs). Notifications were working and Turnbasedlistener was firing.
As soon as I released it for internal testing it stopped working!!!
I had very similar issue. My solution was to manually recheck my status while waiting for my turn.
FIrst, I defined global variable var gcBugTimer: Timer
In endTurn(withNextParticipants:turnTimeOut:match:completionHan‌​dler:) completion handler:
let interval = 5.0
self.gcBugTimer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(self.isMatchActive), userInfo: nil, repeats: true)
self.gcBugTimer.tolerance = 1.0
Code above also should be called in case when a player is joying to a new match and other player in a turn.
Then timer method:
func isMatchActive() {
// currentMatch - global variable contains information about current match
GKTurnBasedMatch.load(withID: currentMatch.matchID!) { (match, error) in
if match != nil {
let participant = match?.currentParticipant
let localPlayer = GKLocalPlayer.localPlayer()
if localPlayer.playerID == participant?.player?.playerID {
self.player(localPlayer, receivedTurnEventFor: match!, didBecomeActive: false)
}
} else {
print(error?.localizedDescription ?? "")
}
}
}
And I add following code at the very beginning of player(_:receivedTurnEventFor:didBecomeActive):
if gcBugTimer != nil && gcBugTimer.isValid {
gcBugTimer.invalidate()
}
What ended up working for me, was to test on an actual device, rather than in simulator. The receivedTurnEvents function doesn't seem to work in simulator.
Grigory's work around is great for testing with simulator.

Updating to Xcode 7 Beta 5 & Swift 2 produced multiple errors

I updated Xcode to the new Xcode 7 beta 5. In doing so, it converted to Swift 2, but then created even more errors. Right now, I am completely stuck, and don't know what to do, because although all my errors are gone, my app will not work correctly.
My problem is this:
if(self.myOutput3 as? NSObject == true) {
print("IT IS TRUE")
PFUser.logInWithUsernameInBackground(self.myOutput1 as! String, password: "xxx") { (user: PFUser?, error: NSError?) -> Void in
if error == nil {
print("It Worked!")
// self.presentViewController(destViewController, animated: true, completion: nil)
let instillation = PFInstallation.currentInstallation()
instillation["user"] = PFUser.currentUser()
instillation.saveInBackgroundWithBlock(nil)
self.performSegueWithIdentifier("toTimeline", sender: self)
} else {
// self.enterButton.enabled = false
self.errorAlert()
print("Couldn't log in...")
}
}
} else {
print("IT IS FALSE")
self.performSegueWithIdentifier("continueTheSignIn", sender: self)
// self.move()
}
The program will perform the toTimeline segue, but not the continueTheSignIn . I don't see any logical reason that this is not working. Could anyone point me in the right direction?
Also, I am having an error in my messages feature.
cell.textView!.linkTextAttributes = [NSForegroundColorAttributeName:cell.textView!.textColor]
This is giving me the error "Cannot assign a value of type '[String : UIColor?]' to a value of type '[String: AnyObject]!'
I was not previously getting this error in Swift / Xcode 6.4, so I don't know how to fix it.
Additionally, once I bypass this to get into my app to see if my other features are working, most of my UITableViews are not displaying any information. One is, however the rest load the correct amount of rows, but display nothing. What could this be? Also, no Parse pictures are being displayed correctly either. These are even more concerning than the other problems...
Here is the picture after I deleted and re added the segue under a diff. name.
Parse wont support the beta version . it needs a full version . I have contacted them based on a similar issue . They said they will update the parse to work with xcode7 once the full version of xcode7 is released.

Resources