iosswiftgame-centergamekitgkturnbasedmatch

GKTurnBasedEventListener could not be set to delegate of my ViewController?


In objC the syntax written by Rawendrich for GKTurnBasedEventListener, which was GKTurnBasedEventHandler there at that time, now changed by Apple is as below.

 if (!gameCenterAvailable) return;

void (^setGKEventHandlerDelegate)(NSError *) = ^ (NSError *error)
{
    GKTurnBasedEventHandler *ev = 
      [GKTurnBasedEventHandler sharedTurnBasedEventHandler];
    ev.delegate = self;
};

NSLog(@"Authenticating local user...");
if ([GKLocalPlayer localPlayer].authenticated == NO) {     
    [[GKLocalPlayer localPlayer] 
     authenticateWithCompletionHandler:
      setGKEventHandlerDelegate];        
} else {
    NSLog(@"Already authenticated!");
    setGKEventHandlerDelegate(nil);
}

Now after converting this to swift, and with the composition of writing down GKTurnBasedEventListener instead of GKTurnBasedEventHandler, this comes the following way.

//  Converted with Swiftify v1.0.6381 - https://objectivec2swift.com/
if !gameCenterAvailable {
return
}
var setGKEventHandlerDelegate: ((_: Error) -> Void)? = {(_ error:   Error?) -> Void in
    var ev = GKTurnBasedEventHandler.shared()
    ev.delegate = self
}
print("Authenticating local user...")
if GKLocalPlayer.localPlayer().authenticated == false {
GKLocalPlayer.localPlayer().authenticate(withCompletionHandler:    setGKEventHandlerDelegate)
}
else {
print("Already authenticated!")
setGKEventHandlerDelegate(nil)

}

Unfortunately this is not the right syntax to set delegate of GKTurnBasedEventListener for my ViewController.

Please if anyone of you could solve this for me, because without this I'm not able to read through event listener's default functions.

Cheers!


Solution

  • Finally after just about harsh 10 hours, I figured out this problem from Here. Although this syntax is in objC, but there's no problem of converting it to swift from Swiftify.

    Although a bit later than the real time, but I'm now able to understand that setting delegate of GKTunBasedEventListener is not like the one we do for UITableViewControllerDelegate.

    Here, one must have to first authenticate local player, then after you have to register local player's listener to the ViewController's delegate GKLocalPlayerListener.

    One other thing I found on Apple's Documentation: Do not implement GKChallengeListener, GKInviteEventListener, GKSavedGameListener, and GKTurnBasedEventListener directly; implement GKLocalPlayerListener instead. You can listen for and handle multiple events using GKLocalPlayerListener.

    So then on I've implemented in the following way.

    import GameKit
    
    class ViewController: UIViewController,   GKTurnBasedMatchmakerViewControllerDelegate, 
    GKLocalPlayerListener {
    
    
    ..... 
    
    
    func player(_ player: GKPlayer, receivedTurnEventFor match: GKTurnBasedMatch, didBecomeActive: Bool) {
    
        print("#1")
        print(player)
        print("#2")
        print(match)
        print("#3")
        print(didBecomeActive)
    
        if match.status == GKTurnBasedMatchStatus.open
        {
            if GKLocalPlayer.localPlayer() == match.currentParticipant
            {
    
    
            if didBecomeActive
            {
                // Active now
            }
            else
            {
                // Active already
            }
    
            }
            else
            {
                // It's someone's turn
    
                if match.matchData != myMatch?.matchData
                {
                   // Match Data being Updated by Someone
                    print(player.alias ?? "No Name:")
                }
    
            }
    
    
        }
    
        thirdTopLabel.text = match.matchID! + "\n" + didBecomeActive.description
    
    }
    
    .... 
    

    Now in ViewDidLoad() function put the following code.

    // In the ViewDidLoad function 
     if(!GKLocalPlayer.localPlayer().isAuthenticated)
        {
            authenticatePlayer { (auth) in
    
                weak var weakSelf = self
                weak var weakPlayer = GKLocalPlayer.localPlayer()
    
                if(auth){
    
    
                     weakPlayer?.register(weakSelf!)
                     self.suthentication = true;
    
                }
                else{
                    print("failed in authentication")
                    self.suthentication = false;
                }
    
            }
    
        }
        else
        {
            // Already Authenticated
            GKLocalPlayer.localPlayer().register(self)
            localPlayer = GKLocalPlayer.localPlayer()
    
    
        }
    

    And finally your Authentication function should be like this.

    // authenticate local player :: Just Authentication
    func authenticatePlayer(completionHandler: @escaping (_ resultedPlaces: Bool) -> Void) {
    
        localPlayer = GKLocalPlayer.localPlayer()
    
    
        localPlayer.authenticateHandler =
            { (viewController , error ) -> Void in
                if viewController != nil
                {
                    self.present(viewController!, animated:true, completion: nil)
                }
                else
                {
                    if self.localPlayer.isAuthenticated
                    {
    
                        completionHandler(true);
                    }
                    else
                    {
                        completionHandler(false);
    
    
                        print("not able to authenticate fail")
                        self.gameCenterEnabled = false
    
                        if (error != nil)
                        {
                            print("\(error.debugDescription)")
                        }
                        else
                        {
                            print(    "error is nil")
                        }
                    }
                }
    
        }
    }
    

    NOTE: GKLocalPlayerListener won't work on simulator.