GKTurnBasedEventListener could not be set to delegate of my ViewController?

早过忘川 提交于 2020-01-05 07:07:18

问题


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!


回答1:


FYI, if you want a working example of how to use GKLocalPlayerListener during a turn-based GameKit match, you are welcome to take a look at this example project for a turn based game. I hope it helps to see all the pieces in context.




回答2:


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.



来源:https://stackoverflow.com/questions/44889019/gkturnbasedeventlistener-could-not-be-set-to-delegate-of-my-viewcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!