I've implemented Game Center features like achievements and leaderboards, and now I'm working on the challenges. I was under the impression that I didn't have to add any additional code - if I had achievements or leaderboards, players would be able to send challenges to their friends. But now, in iOS10, you no longer have the ability to add players as friends - the challenges are handled through iMessages. The problem is - I don't see that feature anywhere in the GKViewController screen. If you select an achievement/leaaderboard score, you can tap on 'Challenge Friends', but it only suggests the players you already have in your friends list rather than in your contact list. Apple has also deprecated GKChallengesViewController, so I'm not sure where to look on how to do this.
Does anyone know how to add the iMessage Challenges feature to Game Center in iOS 10?
Update: I have seen that this feature lives within the GKMatchmakerViewController, but that seems to be for multiplayer type things. I'm still not sure how to use this to just send challenges.
From the Apple Docs:
Issuing a challenge does not display a user interface to the player issuing the challenge; this is code you need to implement yourself.
There are also a few examples on how to issue challenges and how to find players you can invite, such as:
- (void) challengePlayersToCompleteAchievement: (GKAchievement*) achievement
{
[achievement selectChallengeablePlayers:[GKLocalPlayer localPlayer].friends withCompletionHandler:^(NSArray *challengeablePlayerI, NSError *error) {
if (challengeablePlayers)
{
[self presentChallengeWithPreselectedPlayers: challengeablePlayers];
}
}];
}
...or:
- (void) challengeLesserMortalsForScore: (int64_t) playerScore inLeaderboard: (NSString*) leaderboard
{
GKLeaderboard *query = [[GKLeaderboard alloc] init];
query.leaderboardIdentifier = leaderboard;
query.playerScope = GKLeaderboardPlayerScopeFriendsOnly;
query.range = NSMakeRange(1,100);
[query loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
NSPredicate *filter = [NSPredicate predicateWithFormat:#"value < %qi",playerScore];
NSArray *lesserScores = [scores filteredArrayUsingPredicate:filter];
[self presentChallengeWithPreselectedScores: lesserScores];
}];
}
By the looks of it you still can only invite players that are already part of game center, i.e. no arbitrary "contacts" from the contact list (which makes sense), but this is only an assumption.
Related
Scenario = I have an app that allows users to message other users. I also have a button that will display that amount of new (unread) messages that the user has. The amount will be displayed on a badge icon on the tab bar at the bottom.
What I've Been Doing = This queries every 5 seconds if a new message has been posted for the current user.
- (void)queryForMessagesBadgeNumber:(NSTimer *)timer
{
NSString *currentUserID = [PFUser currentUser][#"userID"];
PFQuery *badgeQuery = [PFQuery queryWithClassName:#"Message"];
[badgeQuery whereKey:#"receiverID" equalTo:currentUserID];
[badgeQuery whereKey:#"wasRead" equalTo:[NSNumber numberWithBool:NO]];
[badgeQuery countObjectsInBackgroundWithBlock:^(int number, NSError *error)
{
if (number == 0)
{
NSLog(#"No unread messages");
}
else
{
[[self.tabBar.items objectAtIndex:2] setBadgeValue:[NSString stringWithFormat:#"%d",number]];
}
}];
}
Issues = This is very taxing on the "Requests Per Second" count. Parse allows for 30req/sec on freemium and just with my one phone I am using half of that with this query.
Question = Does anyone know of a more efficient way I can achieve what I am doing here?
Use Push notifications.
When a user sends a message to another user, you could get the app to send the recepient a push notification. You can choose whether to display a banner or not, or simply update the badge.
Guide is located here - Parse Push guide
Parse push is also free to a certain amount of notifications, but a much better way than polling the DB every x amount of seconds
I am developing a board game. Using Game Center for multiplayer, but currently stuck at how to send or receive invitations of GKTurnBasedMatch. I am creating match programmatically using:
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.defaultNumberOfPlayers = 2;
[GKTurnBasedMatch findMatchForRequest:request
withCompletionHandler:
^(GKTurnBasedMatch *match, NSError *error) {
if(error) {
NSLog(#"%#", error.localizedDescription);
return;
}
[self.delegate startGameForMatch:match];
}];
The GKTurnBasedMatch instance in parameter of above block, has only local player with other player as nil and I need to display details of opponent in the game.
NSMutableArray *participantIds = [[NSMutableArray alloc] init];
NSLog(#"%#", match.participants);
for (GKTurnBasedParticipant *participant in match.participants) {
if(participant.playerID) [participantIds addObject:participant.playerID];
}
[GKPlayer loadPlayersForIdentifiers:participantIds
withCompletionHandler:^(NSArray *players, NSError *error) {
NSMutableString *string = [[NSMutableString alloc] init];
for (GKPlayer *player in players) {
[string appendFormat:#"---- Alias: %# DisplayName: %#", player.alias, player.displayName];
}
NSLog(#"%#", string);
}];
Am I missing something or Game Center works like this?
I read that participants of the match wont get invitations until that GKTurnBasedParticipant is GKTurnBasedMatch.currentParticipant but I need to display the details of opponent when game started.
Thanks for the help. Point me in correct direction.
This happens when you create a match against a random opponent. Try creating a second test user in iTunesConnect and signing into that user on a second device.
Then, send that second test player an invite to be your friend. This will allow you to more easily test your game with multiplayer features without having to wait for a random match to be found.
After the friend request is accepted, try creating a new game once more. Now, invite your 'Friend' to your game and start your turn. You will now notice that the (null) variables will - for the most part - be filled in. Something like this should now appear in your log-
GKTurnBasedParticipant 0xb9432e0 - playerID:G:123456789 status:Invited matchOutcome:None lastTurnDate:(null) timeoutDate:(null)
I make the turn-based game on Game Center.
When I search another user through auto-match function, does GameCenter search another user that this game was installed or user that have free time?
Because when I implement auto match feature on turn based game, it returns null value,
I want to know more detail about the auto match feature.
If GameCenter searches the user that game was installed and the game is not famous, then I think that auto-match can't run.
How can I implement auto-match feature programmatically?
Following codes doesn't return any user of game center.
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
[GKTurnBasedMatch findMatchForRequest: request withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
{
if (match){
//[self performSegueWithIdentifier:#"GamePlayScene" sender:match];
NSLog(#"match id: %#", match.matchID);
}
}];
Because it has very little info on sites for auto-match feature, so please help me for auto-match.
Thanks for your help.
I'm trying to create a custom view controller to display active games to the user (similar to what Letterpress does).
I am currently trying to subclass GKTurnBasedMatchmakerViewController except I don't know how to hide the default elements (for inviting/showing existing games) and to add my own. I have currently been playing around with logging things to ensure I can access the active matches, current player IDs, etc (which I have recently figured out) but I am stuck on how to start with the interface.
Not sure what code, if any would be relevant at this point. Please let me know.
Looking to: Hide current elements. I'm assuming I can build the interface as I would for any other application after that.
Thanks,
Steven
I don't think its a good idea to subclass. Start with a clean UIViewController and build the UI from there. Then implement all the necessary methods.
Set yourself as delegate:
[GKTurnBasedEventHandler sharedTurnBasedEventHandler].delegate = self;
so you get delegate event, such as:
handleInviteFromGameCenter
handleTurnEventForMatch
handleMatchEnded
etc.
Add a UITableView, and load all matches from Game center:
[GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error) {
// Add matches to table view
}];
Don't forget to authenticate the player first:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *loginVC, NSError *error)
{
};
Star a match programatically:
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
[GKTurnBasedMatch findMatchForRequest:request withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
{
}];
etc. Look at the doc for the full API.
After posting my score to Game Center only local score is visible from my app as well as from the game centre application.
Weird thing is sandbox worked fine and shown score for all test accounts.
This is the part of my code where i report score:
- (void) reportScore: (int64_t) score forLeaderboardID: (NSString*) identifier
{
if (!_gameCenterFeaturesEnabled) {
NSLog(#"Player not authenticated");
return;
}
GKScore *scoreReporter = [[GKScore alloc] initWithLeaderboardIdentifier: identifier];
scoreReporter.value = score;
scoreReporter.context = 0;
NSArray *scores = #[scoreReporter];
[GKScore reportScores:scores withCompletionHandler:^(NSError *error) {
if (error) {
NSLog(#"Error:%#",error);
}
}];
}
Score challenges work fine and i get notified when challenge is completed.
App was released a day ago, is this usual?
I am seeing the same problem on my game that was released on 27th November. The sandbox leaderboards all worked fine. All the scores are viewable via iTunes connect.
If you look on the apple developer forums there are a few people with similar problems with apps released in the last 10 days.
I've posted a bug report via the Apple 'report a bug' system, but who knows if they even check that. I'm hoping this can get resolved quickly as it is somewhat spoiling my Christmas themed score chasing game :-(
UPDATE: My issue has been resolved as it seems has several others on the Dev Forums. I hope yours is resolved too.