Same for me, it's been a couple of days now... and Facebook is requesting codes to do their regular validation checks, the clock is ticking!
Apple is looking into it. Made them aware of that thread.
Post
Replies
Boosts
Views
Activity
Many thanks Quinn!
I symbolicated the crash report and indeed it takes me to that same function, so this must be it. Here is the extra detail:
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 HatStacker 0x104bbe9d8 closure #1 in closure #1 in GameScene.sync_hiscore() (in HatStacker) (GameScene.swift:1882) + 76248
1 HatStacker 0x104bbea60 thunk for @escaping @callee_guaranteed (@guaranteed GKLeaderboardEntry?, @guaranteed [GKLeaderboardEntry]?, @guaranteed Error?) -> () (in HatStacker) (<compiler-generated>:0) + 76384
I found a safer sample of code doing the same thing, could you confirm it should do the trick in a safer manner?
(it functions just as well, my hiscore updates if out of sync like if I reinstalled the game/deleted all save files)
func sync_hiscore2()
{
if (GKLocalPlayer.local.isAuthenticated)
{
if #available(iOS 14.0, *)
{
GKLeaderboard.loadLeaderboards(IDs: ["HatStacker_LD01"])
{ leaderBoards, error in
guard let leaderBoard = leaderBoards?.first else { return }
leaderBoard.loadEntries(for: [GKLocalPlayer.local], timeScope: .allTime)
{ [weak self] leaderboard, entries, error in
guard let self else { return }
let hiscore = leaderboard?.score ?? 0
if ( hiscore > player_hiscore)
{
player_hiscore = hiscore
}
}
}
}
}
One thing that is puzzling me...
That "high score sync" function is only called when the user press "Start game" in the main menu, so isn't in theory reached at "app launch" time.
The apple review team claims they can't even launch the game successfully so I assume weren't reaching the menu and pressing on anything.
Does the Swift trapping scans the whole code and triggers anyway? Unless they simply can't be bothered to give me those details on repro steps and it crashes on "game start" and not "on launch" as they suggest in their generic statement.
Any reason why it only happens at app review time, and never when I try on my devices at home? (even using the very same release binary through TestFlight) / Maybe they have a special setup with a Game Center account that is failing in a special way and triggering the swift trap? But I tried to launch on my devices without being logged in, and it never crashed, even using the very same release build with TestFlight.
My worry is I "blind" fix that one, and resubmit, then my code trigger another trap in another function further down in my code with every submission I make, as I get no warning from Xcode that my code is unsafe, and it doesn't crash my devices at home!?
I fear I could alienate the apple review team if I keep using them to crash things one swift trap at a time!
Many thanks again for taking the time to help me with my "swift rookie" questions.
Cheers,
JBB
Very odd.
As far as I can see the only piece of code in the whole of my GameScene.swift - or even the whole project - calling loadEntries (to fetch hiscores) is my sync_hiscore() function.
How is it getting called right after the GameKit inits?
In theory my sync_hiscore() function is only called when we're well into my game main loop, navigating the main menu, so it will be a few seconds before the user presses the start button. The "app start" frame 16 would be long gone, no?
I added a "fatal error()" in my sync_hiscore2() function to see if it was somehow called at launch time and crash on boot. But no, nothing.
But then if I try the press "start game" it does crash right away as it reaches that "fatal error" line, but the crash report looks nothing like the one apple sent, as it is clearly showing it went into my function after I press start etc.
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libswiftCore.dylib 0x18166d534 _assertionFailure(_:_:file:line:flags:) + 576
1 HatStacker 0x1028e46cc GameScene.sync_hiscore2() + 224
2 HatStacker 0x1028d66e4 GameScene.start_game() + 1420
3 HatStacker 0x1028b5aa0 GameScene.menu() + 5640
4 HatStacker 0x1028b1d84 GameScene.update(_:) + 308
This confirms the fact the apple review team isn't crashing that way, pressing the button, which syncs the score, calls my LoadEntries with the dodgy completion handler.
They are crashing earlier, in a different manner.
So, correct me if I'm wrong here: they seem to be indeed crashing on very early on launch (app start is still within 16 frames) and somehow as the various systems kick in, Swift traps some bad code in my leaderboard completion handler, situated inside a function that is never called, but related to a similar LoadEntries function called by something else?
Sorry for being thick here! I am very confused.
Do I fix my function with a safer completion handler anyway? It cannot hurt I guess, as that way if it gets called for any reason, it will survive?!
I've attached the original symbolicated crash report, in case it can shed some extra light on why the loadEntriesForPlayers gets called, then the completion handler in my function gets called right after?
Sorry for all these questions... Many thanks for you help Quinn, much appreciated!
Cheers,
JBB
HatStacker_build4_symbolicated.crash
BTW, I did blind fix my unsafe completion handlers in the leaderboard code, and resubmitted - and it passed this time!
So it was that.
Still puzzled as to why that piece of code normally only called when you pressed "start game" was being called at app launch? Maybe completion handlers are setup and called/scanned/trapped early on in some cases?
But at least I am unstuck. Many thanks Quinn for your help earlier!
Cheers,
JBB