In Xcode 10, there was a button for the Object Library located left of the "inspector" buttons. After the upgrade to Xcode 11 occurred, this button no logner exists. Where did it go?
Post
Replies
Boosts
Views
Activity
When Game Center determines a player is forced to disconnect from a match, Game Center sends a disconnect message via the "didChange state" function. However, not all devices connected to the match are receiving the disconnect state change message. One device will think the player is disconnected, but there is still messaging passing from the (supposedly) disconnected player to the other players in the match.The only way I can think to resolve this issue is have all players poll Game Center to obtain updated match information. Based on this updated match information then all players can determine what players are truly still connected properly or not.Can Game Center be polled to obtained updated match information? If so, how?Any other ideas how to resolve the issue when all players do not receive the same disconnect state chaneg from Game Center?
I have an imageView which has a top constraint IBOutlet called imageViewTopConstraint. In viewWillLayoutSubviews( ) I set the imageViewTopConstraint.constant value. The imageView displays properly for all iPhone models while in portrait mode, which is good.When I switch to landscape mode, I want to disable the imageViewTopConstraint, so the viewWillLayoutSubviews( ) has the following code:if UIDevice.current.orientation.isPortrait {
imageViewTopConstraint.constant = (2 * screenHeight) / 3
imageViewTopConstraint.isActive = true
}
else if UIDevice.current.orientation.isLandscape {
imageViewTopConstraint.isActive = false
}IssueWhen I run the application it is initially in portrait mode. When I switch to landscape mode I receive the following fatal error at the line where I set "imageViewTopConstraint.isActive = false" to disable the constraint (line 6 above) Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional valueAny idea what is going on or what this means?
I discovered the Game Center playerID has been deprecated in iOS 13.0 and we should use teamPlayerID or gamePlayerID instead. I started to play around with teamPlayerID value since Apple indicated in most cases we would be using the teamPlayerID value.A) Once a match has been created, the teamPlayerID can be obtained for each player by looping through each player in the match (myMatch).for player in myMatch.players
{
print("teamPlayerID = \(player.teamPlayerID)")
}B) The teamPlayerID can also be obtained by calling the GKPlayer.loadPlayers(forIdentifiers:) function to obtain all player information. You can then loop through the player information to obtain the teamPlayerID for each player.(Note: Creating the player map array using $0.teamPlayerID does not result in any data being returned)let playerIDs = myMatch!.players.map { $0.playerID } as [String]
GKPlayer.loadPlayers(forIdentifiers: playerIDs) { (players, error) in ...
for player in players
{
print("teamPlayerID = \(player.teamPlayerID)")
}Issues Found:1) If Player1 performs (A) and (B) then they will notice the teamPlayerID values from (A) are not the same values as the ones from (B)2) If Player1 performs (A) and Player2 performs (A), then both players will have different teamPlayerID associated with them both? Meaning ...Player1 sees a different teamPlayerID value for Player2 than Player2 sees for themselvesPlayer2 sees a different teamPlayerID value for Player1 than Player1 sees for themselvesAs a result of these two issues, it does not seem the teamPlayerID value can be used to uniquely specify a particular "player" in Game Center. I confirmed one player cannot send data to another player since both players do not have the same teamPlayerID values that represent each player in the match. (Note: The same issue exist for the gamePlayerID value as well)How can we use teamPlayerID to associate with a specific player in a match, when each player in the match has different teamPlayerID values for the players in the match?
Does reloading new images into a UIImage view increase the memory usage each time a new image is loaded, thus potentially leading to a memory leak? If so, then do I need to release the memory used for the currently loaded image before reloading the UIImage with a new image?
I would like to wrap a certain function call, which performs UI updates, inside of a Dispatch.Queue.main.async call. This function can eventually call other functions which might call other functions, etc.. so code execution might hit another area of code which also has another Dispatch.Queue.main.async call. Will it do any harm have two or more Dispatch.Queue.main.async calls being call in the same code execution path?
My card game application has been released in the App Store and various friends are now downloading it wanting to play. Most people can download the game, send invites to each other and start playing, however, there are two friends who are having trouble. I can send an invite to them to join a game or they can send an invite to me to join the game. In both cases the GKMatchmaker View Controller is displayed for the host player, then initially reports "Matching" and eventually reports "Connecting". However, the GKMatchmaker ViewController simply spins and spins indicating "Connecting" status only and the game never starts.Using the iOS simulator I was able to verify the "didFind match" function is being called, however, the expectedPlayerCount is not 0 so the match never starts. Also, the "didChange state" function is never called to indicate the other player has "connected", so the match still never startsHas anyone experience this issue and might know how to resolve it?Notes:1) Both friends can invite each other and play the game together, however, neither friend can invite me and play2) My iPhone 8 has iOS 13.4 and both friends have iPhone 6 (iOS 12.4.5)3) Using my iPhone 8, I can invite a third (different) player who has an iPhone 6 (iOS 12.4.5) succcessfully4) Using an iPhone11 (iOS 13.3) I can invite either of the two friends successfully
Throughout the testing of my game, I have noticed multiple unexpected message events provided by Game Center which required me to add special code handling to overcome. I confirmed all of these issues occur more often then I would have thought.Has anyone else experienced these issues as well?Issues1) Game Center sends CONNECTED for all players then immediately sends DISCONNECT for one player before the match even had a chance to startGame Center sends a "match(didChange state)" CONNECTED indication for each non-GKLocalPlayer in the match (as expected) and eventually indicates the expectedPlayerCount is 0 so match start processing can begin (as expected), which involves loading all other player information via GKPlayer.loadPlayers(forIdentifiers: ) method. However, Game Center will then sometimes immediately send a "match(didChange state)" DISCONNECT, indicating one of the other players has disconnected from the match, even though that player never quit/disconnected from the match themselves. Also, no other player in the match receives this same DISCONNECT event either. The player who was disconnected from Game Center still maintains two-way network connections to other players and a one-way network connection to the player who did receive the disconnect event, so the player is clearly not totally disconnected.This quick DISCONNECT event arrives before "match start" processing has even completed (ie: before GKPlayer.loadPlayers completion handler is called). This has been experienced in 3 and 4 player matches2) Game Center sends a separate CONNECTED state change event for both players and both CONNECTED events indicate expectedPlayerCount = 0In a three player game, the GKLocalPlayer, who requested the match to be created, will receive a separate "match(didChange state)" CONNECTED indication for each of the other two players in the match (as expected), however, both individual CONNECTED events will have expectedPlayerCount = 0. I was under the impression only the last CONNECTED event would indicate expectedPlayerCount = 0 (ie: all players are ready), but that is no the case. This has been experienced in 3 player matches.3) Game Center sends two DISCONNECT state changes for the same player back to backWhen a player quits from my game, then I ensure the match is disconnected by calling "myMatch.disconnect( )". When this occurs, it is expected that all other players still in the match will receive one DISCONNECT state change event from Game Center, indicating one of the players have quit/disconnected from the game. However, I see Game Center sometimes sends two "match(didChange state)" DISCONNECT events one after the next. This has been experienced in 3 and 4 player matches4) Messages never arrive at the intended player destinationMessages sent from one player, using the following ".reliable" protocol, results in the message never arriving at the intended player. This is very annoying when the message which never arrives is the initial "game init data" message which includes all of the information required to sync up the game between all players before it starts. This has been experienced in 3 and 4 player matches. myMatch?.send(data, to: playerArray, dataMode: .reliable)
I noticed invite requests never time out in the GKMatchmakerViewController window and thus spin forever with "Invitation Sent"Say I requested to start a 4-player game and the GKMatchmakerViewController is displayed. I clicked "Invite Friends" and only invited one friend to play. The other two players, requried for the game, are to be selected randomly by Game Center matchmaking. If the one invited player never accepts the invite request, then the GKMatchmakerViewController spins forever with "Invitation Sent".Is there a way to have GKMatchmakerViewController fill the invited player slot with a random player (OR) perhaps I just have to manually cancel the GKMatchmakerViewController when I decided enough time has passed if the invite has not been accepted?If I sent out 2 invites and only one player accepted their invite, then am I forced to cancel the complete match and start from scratch by sending a reInvite to the one friend who wants to play? I guess all of this discussion would be handled by text messaging, outside the game, to inform any players that I will restart the invite process again?
I placed a GKMessageImage.png image file into the Assets.xcassets folder in my Xcode project and then reloaded each iPhone, which I use for testing, with my new application via XCode. When one iPhone sends an Invite text message to the other iPhone, I do not see my GKMessageImage.png being presented. The Game Center default colored bubbles are still being presented.What am I doing wrong?Does the GKMessageImage.png have to be a specific size ?
I recently upgraded to iOS 13.4 and discovered my current XCode 11.3 version must be upgraded to 11.4 to work with the iPhone 13.4 iOS. That being said, I cannot find XCode 11.4 on the AppStore. I also tried looking around developer.apple.com, but cannot find where a Xcode 11.4 download option might exist.If someone can please point me to the proper location to grab XCode 11.4 I would be most grateful.
Will someone please tell me ...What does the "finishMatchmaking(for: )" function actually do?What circumstances should this function be called?GKMatchmaker.shared().finishMatchmaking(for: myMatch!)
I am testing my peer-to-peer game application by starting a 4-player game (3 real iPhones + 1 simulator iPhone) and I am experiencing an issue where Game Center sends a CONNECT for each player in the match, via the "didChange state" function (as expected), but then immediately sends a DISCONNECT for one of the players. It seems the DISCONNECT is only received by one of the players in the game. In addition, the player who Game Center disconnected, is still available in the game with the remaining players. I would have assumed that if Game Center is going to send a disconnect to one player then it would send the same disconnect to all other players, but this is not the case. Player 1 = Xcode simulator player (didChange state) Player 2 CONNECT (didChange state) Player 3 CONNECT (didChange state) Player 4 CONNECT (didChange state) Player 2 DISCONNECT Player 1 no longer has a network connection to Player 2 Player 1, Player 3 and Player 4 maintain a network connection with each other Player 2, Player 3 and Player 4 maintain a network connection with each otherThis occurs about 1 out of every 13-15 times I attempt to create a 4-player game.Is there anything which I might be doing that might be causing Game Center to behave this way or is Game Center known to act this way sometimes?
I use GameKItHelper as a base to process information sent from Game Center.I just discovered the "match (didChange state: )" function is immediately being called twice, back to back at the same exact time, to indicate two other players in the match have connected. In addition, both separate function calls indicate "expectedPlayerCount = 0" so my match processing starts twice, thus resulting in bad things happening.I experienced this in the past and added a "myMatchStarted" boolean flag to indicate when the match really started, so I could stop the match from starting a second time (see code below). This code was confirmed to be working for many various cases which would have originally failed, so I thought I resolved this issue.However, I just experienced this issue one more time where my code updates (below) were still not good enough to block two simutaneous calls to the "match (didChange state: )" function if these functions occurred really really close to each other.Please refer to the debug output (provided below the code snippet) to see how the function is being called twice extremely fast and how the "myMatchStarted" boolean flag did not even have a chance to be set for the first function call, thus could not stop the second call from being processed.How should I process Game Center function calls which occur at the same time?func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState)
{
print("(GAMEKIT) ENTER match() didChange state")
switch (state)
{
case GKPlayerConnectionState.connected:
print("(GAMEKIT) PLAYER CONNECTED! = \(player.displayName)")
if (myMatchStarted == false)
{
print("(GAMEKIT) (match didChange) Match DID NOT start yet")
if (match.expectedPlayerCount == 0)
{
print("(GAMEKIT) (match didChange) START THE MATCH!")
startMatch()
}
}
etc..
}
func startMatch()
{
print("(GAMEKIT) ENTER startMatch()")
if (myMatchStarted == true)
{
print("(GAMEKIT) ** MATCH ALREADY STARTED, DO NOT START AGAIN !! **")
return
}
myMatchStarted = true
loadOtherPlayerInfo()
print("(GAMEKIT) EXIT startMatch()")
}LOG OUTPUT(GAMEKIT) ENTER match() didChange state(GAMEKIT) ENTER match() didChange state(GAMEKIT) PLAYER CONNECTED! = Bob(GAMEKIT) PLAYER CONNECTED! = Mary(GAMEKIT) (match didChange) Match DID NOT start yet(GAMEKIT) (match didChange) START THE MATCH!(GAMEKIT) (match didChange) Match DID NOT start yet(GAMEKIT) (match didChange) START THE MATCH!(GAMEKIT) ENTER startMatch()(GAMEKIT) ENTER startMatch()(GAMEKIT) ENTER loadOtherPlayerInfo(GAMEKIT) ENTER loadOtherPlayerInfo(GAMEKIT) EXIT startMatch()(GAMEKIT) EXIT match() didChange state(GAMEKIT) EXIT startMatch()(GAMEKIT) EXIT match() didChange state
When canceling a match request, I call the "GKMatchmaker.shared().cancel( )" functionWhen disconnecting from a match already created, I call the "myMatch.disconnect( )" functionAfter calling either one of these functions must I wait a certain number of seconds to allow Game Center time to "clean up" before trying to request a new match be created/start?