In my SceneKit game I'm able to connect two players with GKMatchmakerViewController. Now I want to support the scenario where one of them disconnects and wants to reconnect. I tried to do this with this code:
nonisolated public func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState) {
Task { @MainActor in
switch state {
case .connected:
break
case .disconnected, .unknown:
let matchRequest = GKMatchRequest()
matchRequest.recipients = [player]
do {
try await GKMatchmaker.shared().addPlayers(to: match, matchRequest: matchRequest)
} catch {
}
@unknown default:
break
}
}
}
nonisolated public func player(_ player: GKPlayer, didAccept invite: GKInvite) {
guard let viewController = GKMatchmakerViewController(invite: invite) else {
return
}
viewController.matchmakerDelegate = self
present(viewController)
}
But after presenting the view controller with GKMatchmakerViewController(invite:), nothing else happens. I would expect matchmakerViewController(_:didFind:) to be called, or how would I get an instance of GKMatch?
Here is the code I use to reproduce the issue, and below the reproduction steps.
Code
Run the attached project on an iPad and a Mac simultaneously.
On both devices, tap the ship to connect to GameCenter.
Create an automatched match by tapping the rightmost icon on both devices.
When the two devices are matched, on iPad close the dialog and tap on the ship to disconnect from GameCenter.
Wait some time until the Mac detects the disconnect and automatically sends an invitation to join again.
When the notification arrives on the iPad, tap it, then tap the ship to connect to GameCenter again. The iPad receives the call player(_:didAccept:), but nothing else, so there’s no way to get a GKMatch instance again.
GameKit
RSS for tagCreate apps that allow players to interact with each other using GameKit.
Posts under GameKit tag
74 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hi,
I tried to save the game progress using the official Apple plugin for Unity but the crash happened when I active the "iCloud Documents" inside capabilities and when deactivated it this error message appeared:
Code=27 Domain=GKErrorDomain Description=The requested operation could not be completed because you are not signed in to iCloud or have not enabled iCloud Drive. (UbiquityContainerUnavailable)
Authentication with Game Center works fine using the Core plugin, but nothing works correctly when I use the GameKit plugin.
Note:
I already active iCloud for app Identifier.
Tichnecal informations:
Unity version: 2022.3.47f1 LTS
XCode 16
Swift 6
GameKit-3.0.0 (Apply unity plugin)
Core-3.1.5 (Apply unity plugin)
I'm displaying a GKGameCenterViewController after successfully authenticating and on iOS 18.0 and 18.1, I get a black screen. As a sanity check GKLocalPlayer.local.isAuthenticated is also returning true. The same code works just fine on iOS 17. Is there something that needs to be done on iOS 18 and above?
Once GKAccessPoint is active, then enter an arview page, the arview will lose camera feed.
OSVersion: iOS 18.0.1, iOS 18.1
The welcome banner is off the top left side of the screen instead of coming down the center. This behavior is encountered when running my iOS application on macOS.
The update was the only change I can see. Which I did just the other day. I did log on to iCloud.com, I also looked at Apple Developer. I didn't see any additional updates of terms that needed to be accepted. I am sure to log into iCloud on the simulator. It seems to stay logged in. Until I fetchSavedGames. Where I have it exit at 20 seconds due to timing out. Then when I go back to check my account in Settings, it's asking to "Sign in to iCloud" again. It does work properly on a device. So it doesn't stay logged into iCloud on the simulator but it seems like the fetchSavedGame from GKLocalPlayer is what resets that. Any help or suggestions would be appreciated. Thanks.
Hello,
I’m working with the GameKit API, and I am encountering an issue when submitting a player’s score to a leaderboard at the end of a game.
Goal:
After submitting the new score to a leaderboard, I want to immediately fetch and display the updated leaderboard that reflects the new score.
Problem:
After successfully submitting the player’s score, when I fetch the leaderboard, the entries are not updated right away. The fetched leaderboard still shows the outdated player score.
Is this delay in updating the leaderboard expected behavior, or am I missing something in my implementation?
Steps to Reproduce:
Submit the local player’s score to Leaderboard X.
On successful submission, fetch the leaderboard entries for Leaderboard X.
Expected Result:
The fetched leaderboard should reflect the updated player score immediately.
Actual Result:
The fetched leaderboard shows the outdated score, with no immediate update.
As a workaround, I update the leaderboard myself locally, that does the job, but is error-prone and require more efforts.
When opening the Game Center dashboard via the Access Point, the Game Center dashboard appears BEHIND any content in the window with z depth (default type not volumetric). It obscures the dashboard and this makes it unusable.
Alerts have the same placement.
The new defaultWindowPlacement would probably suffice, but I don't think there's a way to apply that to the Game Center window.
What to do?
Thanks.
Hi,
I created a leaderboard in my application, and a method to record a new score:
GKLeaderboard.loadLeaderboards(IDs: [leaderboardID]) { (leaderboards, error) in
if let error = error {
print("Error loading leaderboards: \(error.localizedDescription)")
}
guard let leaderboard = leaderboards?.first else {
print("Leaderboard not found")
return
}
leaderboard.submitScore(score, context: 0, player: self.localPlayer) { error in
if let error = error {
print("Error reporting score: \(error.localizedDescription)")
} else {
print("Score reported successfully!")
}
}
}
}
When debuging, this method is correctly called and I have a success, so I tried to test it with an internal TestFlight release.
The leaderboard is never updated.
Is there a way to perform a test of a leaderboard before publishing the app?
I have the same question for achievements:
let achievement = GKAchievement(identifier: identifier)
achievement.percentComplete = percentComplete
GKAchievement.report([achievement]) { error in
if let error = error {
print("Error reporting achievement: \(error.localizedDescription)")
}
}
}
Thanks!
Hello,
I would like to know if anyone has or still using the GKVoiceChat capabilities in their apps. I wanted to use it for my online game but I am coming across issues using it and wondering if their are alternatives?. The documentation mentions to use Share-play but that wont be possible with random online players. Any help will be appreciated!.
Hello, I try to invite a friend to play my app , however when the friend try to press invite link component via iMessage, it shows “Retrieving” and then disappear, nothing happens,
it doesn't redirect to my app, what I'm missing? or doing wrong I can leave some part of my code
import Foundation
import GameKit
extension RealTimeGame: GKLocalPlayerListener {
/// Handles when the local player sends requests to start a match with other players.
func player(_ player: GKPlayer, didRequestMatchWithRecipients recipientPlayers: [GKPlayer]) {
print("\n\nSending invites to other players.")
}
/// Presents the matchmaker interface when the local player accepts an invitation from another player.
func player(_ player: GKPlayer, didAccept invite: GKInvite) {
// Present the matchmaker view controller in the invitation state.
if let viewController = GKMatchmakerViewController(invite: invite) {
viewController.matchmakerDelegate = self
rootViewController?.present(viewController, animated: true) { }
}
}
}
also I don't have "<key>CFBundleURLTypes</key>" in my info.plist, I don't know I need that or not...
Has anyone come across the issue that setting GKLocalPlayer.local.authenticateHandler breaks a RealityView's world tracking on iOS / iPadOS 18 beta 5?
I'm in the process of upgrading my app to make use of the much appreciated RealityView unification, using RealityView not only on visionOS but now also on iOS and iPadOS. In my RealityView, I enable world tracking on iOS like this:
content.camera = .worldTracking
However, device position and orientation were ignored (the camera remained static) and there was no camera pass-through. Then I discovered that the issue disappeared when I remove the line
GKLocalPlayer.local.authenticateHandler = { viewController, error in
// ... some more code ...
}
So I filed FB14731139 and hope that it will be resolved before the release of iOS / iPadOS 18.
I have an AR game using ARKit with SceneKit that works just fine in iOS 17.
In the iOS 18 betas, the AR background image shows black instead of showing the real world. As a result there's no tracking and obviously the whole game is useless.
I narrowed down the issue to showing the Game Center Access Point.
My app has ViewController 1 (VC1) showing the main menu and that's where I want to show the GC Access Point. From there you open VC2 which shows a list of levels. Selecting any level will open VC3 which has the ARScene.
Following is the code I use to start Game Center in VC1:
GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in
let isGameCenterReady = (gcAuthVC == nil) && (error == nil)
if let viewController = gcAuthVC {
self.present (viewController, animated: true, completion: nil)
}
if error != nil {
print(error?.localizedDescription ?? "")
}
if isGameCenterReady {
GKAccessPoint.shared.location = .topLeading
GKAccessPoint.shared.showHighlights = true
GKAccessPoint.shared.isActive = true
}
}
When switching to VC2 I run GKAccessPoint.shared.isActive = false so that the Access Point will no longer show in any of the following VCs. I tried running it in VC1, VC2, and again in VC3 - it doesn't change anything. Once I reach VC3, the background is black.
If in VC1 I don't run GKAccessPoint.shared.isActive = true, so I don't activate the access point, the behavior is as follows:
If I wait until after the Game Center login animation completes and closes on its own and then I proceed to VC2 and VC3, the camera image will show correctly
If I quickly move to VC2 before the Game Center login animation has completed, so my code will close it by setting active = false, and then I continue to VC3, I will see the black background problem.
So it does look like activating the access point and then de-activating it causes the issue. BTW, if I activate the access point and leave it on in all VCs, the same black background issue persists.
Other than that, when I'm in VC3 with the black background and I switch to another app (so my game moves to the background), when it returns to the foreground, the camera suddenly shows the real world correctly!
I tried to manually reset the AR session by pausing and restarting it, but that didn't change anything. Also, when I check with the debugger, it looks like when the app comes back to the foreground it also doesn't run the session start code.
But something does seem to reset itself so I wonder what that is. Maybe I could trigger the same manually in my cdoe???
I repeat that everything works just fine in iOS 17 and below. This problem only started with the iOS 18 beta (currently on beta 5, but it started in some of the previous betas as well).
So could this be a bug in iOS 18?
As a workaround I could check the iOS version and if it's iOS18 not activate the access point, hoping that the user will not jump to VC2 too quickly, and show my own button which will open Game Center. But I'd rather give the users the full experience with their own avatar and the highlights showing up. Plus, certainly some users will move quickly to VC2 and that will be an awful experience.
Any help would be greatly appreciated. Thanks!
Hello,
has anyone been able to implement in their game a way to display the number of players currently online in their game?. I thought up of this feature and thought it will be useful for players to find out if there is anyone currently online so that they don't waste their time trying to find a random online match. Any help will be greatly appreciated.
Kind regards,
Jabir Abdi
This may be a bit dumb but I've really been having trouble with understanding the documentation for Apple's Unity Plugins. I wanted to implement Game Center functionality on my game. So far the only line of code I've managed to get working is the authentication, in which I did
async void Start()
{
await Login();
}
public async Task Login()
{
if (!GKLocalPlayer.Local.IsAuthenticated)
{
var player = await GKLocalPlayer.Authenticate();
var localPlayer = GKLocalPlayer.Local;
]
}
However, I'm at a complete loss as to how to open leaderboards. I followed the documentation given:
void OpenLeaderboard()
{
var allLeaderboards = await GKLeaderboard.LoadLeaderboards();
var filteredLeaderboards = await GKLeaderboard.LoadLeaderboards("leaderboardIwant1");
}
But it did not work. What did I do wrong? Am I missing a function to get it to work? Why can't Apple write proper documentation to properly implement this in a simple way?
My apologies for my frustration. Up until now I've used another plugin from the Unity Asset Store which is shockingly easy to use, but I decided to attempt to use Apple's system because the plugin I had used deprecated functions and I was afraid the App Store would not approve it. But Apple's own plugins are stunningly opaque and hard to test.
As additional questions (but not the main ones), I'm also completely at a loss how to submit scores or load specific leaderboards and Apple's documentation does nothing to help there either.
Any help or thoughts are appreciated. Thanks.
I can't update any apps unless I redeem a code for TestFlight. I have no idea where this code is. It hasn't been emailed to me. Can anyone help?
In the last several days I've gotten reports from customers saying that Game Center suddenly cannot connect to players. I was able to verify this myself.
It will find players to match, but then during the Connecting process it just sits there indefinitely with a spinning thing. Up until maybe 4 days ago this had worked fine for the last 12+ years, so something on the Game Center server broke.
Is anyone else experiencing the same problem?
Hello,
Asking the following as, I was unable to find answers via search on the forum and in the documentation:
Invitations sent via iMessage seem to work correctly with my custom image ( GKMessageImage.png ) however, notifications sent to Game Center Friends via invites generated in Game Center do not include the custom image ( GKMessageImage.png ).
Questions:
Is this expected behavior? Is there a different way to customize the image in the notification? Note the Game Center notification includes the App name correctly.
I also noted in the WWDC session in 2016 ( saw video recently ) that there was some mention of no longer adding friends via Game Center. Is that currently true?
Thanks in advance.
Trying to send and receive data in the GameCenter environment using the following methods:
func sendData(dictionaryWithData dictionary: Dictionary<String, Any>,toPeer targetPeers: [GKPlayer]) {
guard let match = self.match else { return }
do {
let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false)
try match.send(dataToSend, to: targetPeers, dataMode: .reliable)
}
catch {
#if DEBUG
print("CONNECTION MANAGER SEND DATA ERROR")
#endif
}
}
public func match(_ theMatch: GKMatch,didReceive data: Data,forRecipient recipient: GKPlayer,fromRemotePlayer player: GKPlayer) {
if match != theMatch { return }
DispatchQueue.main.async {
do {
guard let message = NSDictionary.unsecureUnarchived(from: data) as? Dictionary<String, Any> else {return}
...
<CODE>
...
}
///Source: https://stackoverflow.com/questions/51487622/unarchive-array-with-nskeyedunarchiver-unarchivedobjectofclassfrom
static func unsecureUnarchived(from data: Data) -> Self? {
do {
let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
unarchiver.requiresSecureCoding = false
let obj = unarchiver.decodeObject(of: self, forKey: NSKeyedArchiveRootObjectKey)
if let error = unarchiver.error {
print("Error:\(error)")
}
return obj
} catch {
print("Error:\(error)")
}
return nil
}
Everything works great until the data exceeds 87K (which, I understand, is the limit for exchanging data in GameCenter).
The data is not sent and gives the following error:
Async message[1FCA0D11-05DE-47D0-9714-983C8023F5C1] send error: FailedToSendData: , InternalError: reliable, maxPayloadSizeExceeded
Interesting enough, I do not have this problem when using MCSession, as follows, even if data exceeds 87K:
func sendData(dictionaryWithData dictionary: Dictionary<String, Any>, toPeer targetPeers: [MCPeerID]) {
do {
let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false)
try session.send(dataToSend, toPeers: targetPeers, with: MCSessionSendDataMode.reliable)
}
catch {
#if DEBUG
print("CONNECTION MANAGER SEND DATA ERROR")
#endif
}
}
I have been doing research and found that I need to fragment data and send and receive it in packages. But I could not find a good explanation how to do it.
Any help would be appreciated!
I'm using the Apple Unity Plugins to use Game Center to authenticate Playfab accounts for my game and when I test this on testflight, everything works fine for me and the people I've tested with, however, when I send the build to review, they are getting GameKitException 37 which states "This game is not listed in a marketplace that supports Game Center" and upon further research I found this page https://developer.apple.com/documentation/gamekit/gkerror/code/appunlisted which I'm assuming is the same thing.
This seems to suggest that I need my app to be listed on the App Store which is strange because this has created a what comes first, the chicken or the egg problem. I need to pass review to get the game listed in the App Store and they can't test the game because accounts cannot be authenticated with Game Center which apparently needs to be listed on the App Store.
So far, I can't find the reason why this doesn't happen on testflight and only happens when I send it to review. I opened a ticket to Apple Developer Support and haven't recieved a response. I asked app review about it and they replied
"Hello,
Thank you for your response. Since all apps must pass App Review before they can be approved, it should not be necessary to have a "store page".
We look forward to reviewing your app once all issues have been addressed and the new build has been received and queued for review.
Best regards,
App Review"
Which doesn't really help me. I am quite pressed for time and I really need assistance in resolving this issue which I cannot replicate. Has anyone encountered this issue or know how to solve it?