I'm completely lost, all the tutorials I've found have been for iOS 6 apps with Storyboards. My question is if you can have a twitter or facebook sharing feature in a sprite-kit game? If so what is the best way to go about adding it? Alot of the tutorials I've read over use viewcontrollers but sprite-kit uses scenes so I'm a bit confused.
Thanks.
Here is an answer for twitter. Your Welcome!
1) import the Social framework under the Build Phases tab then Link Binary with Libraries. Put this code at the top of your SKScene that you want to share it in.
#import <Social/Social.h>
2) add your tweet button in the -(id)initWithSize:(CGSize)size method with this code:
SKSpriteNode *tweetButton = [SKSpriteNode spriteNodeWithImageNamed:#"share"];
tweetButton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)-150);
tweetButton.name = #"tweet";
[self addChild:tweetButton];
3) in your touchesBegan: method put the following code to handle clicking the tweet button and composing a tweet
if ([node.name isEqualToString:#"tweet"]) {
// Create an instance of the Tweet Sheet
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:
SLServiceTypeTwitter];
// Sets the completion handler. Note that we don't know which thread the
// block will be called on, so we need to ensure that any required UI
// updates occur on the main queue
tweetSheet.completionHandler = ^(SLComposeViewControllerResult result) {
switch(result) {
// This means the user cancelled without sending the Tweet
case SLComposeViewControllerResultCancelled:
break;
// This means the user hit 'Send'
case SLComposeViewControllerResultDone:
break;
}
};
// Set the initial body of the Tweet
[tweetSheet setInitialText:#"This is my tweet text!"];
// Adds an image to the Tweet. Image named image.png
if (![tweetSheet addImage:[UIImage imageNamed:#"image.png"]]) {
NSLog(#"Error: Unable to add image");
}
// Add an URL to the Tweet. You can add multiple URLs.
if (![tweetSheet addURL:[NSURL URLWithString:#"http://twitter.com/"]]){
NSLog(#"Error: Unable to URL");
}
UIViewController *controller = self.view.window.rootViewController;
[controller presentViewController:tweetSheet animated: YES completion:nil];
}
This may help. ShareKit
It is an easy way to integrate Facebook, Twitter, and other social networking services into your app.
I'm using Social Framework on iOS 6 for Twitter integration, using the following code :
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
controller.completionHandler = ^(SLComposeViewControllerResult result) {
if (result == SLComposeViewControllerResultCancelled) {
// cancelled
} else if (result == SLComposeViewControllerResultDone) {
// done
} else {
// unknown
}
[controller dismissViewControllerAnimated:YES completion:nil];
};
[self presentViewController:controller animated:YES completion:Nil];
If the user set the same tweet message as one of its old message, I get a popup "The tweet "xxx" is a duplicate and cannot be sent." but the completion handler result value is still SLComposeViewControllerResultDone. Is there a way to know if a tweet has really be sent ?
It seems that the same behaviour is happening for TWTweetComposeViewController.
In iOS 5 twitter integration,
TWTweetComposeViewControllerResult just has 2 options
When user selects done -- TWTweetComposeViewControllerResultDone
When user selects cancel -- TWTweetComposeViewControllerResultCancel
This result doesn't depend on the tweets updated by apple in background. If the tweets fail while updating it shows an alert.
SO i suggest do not implement any custom pop-up for success or failure. As apple itself implemented indications for success/failure tweet updates. On success it plays a sound & on failure a pop-up with reason.
I'm using iOS6 and my phone is a 4S.
I'm using code from the GKLeaderboards example to get Game Center working and the local player authenticated. This code I've imported into my own Sparrow framework scaffold project.
This seems to work totally fine on the simulator, I get the "welcome back xxxx, ** sandbox mode *" msg.
But when I test it on the actual iPhone, my game (which right now just consists of lots of tiles on the screen) slows down to a crawl, and no Game Center msg appears.
Looking at code, because I'm logged in with a different Game Center account on the phone (i'e not the sandbox one) then I think it's trying to present the log in with new account view, but it's not appearing.
The code I'm using is...
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){
// If there is an error, do not assume local player is not authenticated.
if (viewController != nil)
{
[mainViewController presentViewController:viewController animated:NO completion:nil];
//store this view controller pointer
NSLog(#"viewController != nil");
}
else if (localPlayer.isAuthenticated)
{
NSLog(#"Authentication changed: player authenticated.");
}
else
{
NSLog(#"can't log in");
}
}
I think the problem is being caused by this line...
[mainViewController presentViewController:viewController animated:NO completion:nil];
The game doesn't seem to crash but there seems to be something going wrong causing it all to slow right now, any ideas as to what could cause this?
Ok I seem to have gotten this working. Basically I didn't have mainViewController set properly.
I'm currently developing a turn based game using Game Center to handle the online functionalities (for matchmaking and turns handling).
I'm using two sandbox accounts - one on my 3gs and one on the ios Simulator.
I've been testing my app using the GKTurnBasedMatchMakerViewController to do the match making for a while without any problems, but I'm now stuck with an issue:
Every time I want to invite another player for a new (with either one or the other player), the GKTurnBasedMatchMakerViewController displays a UIAlertView stating :
Could not create game - Please remove an existing game and try again.
The thing is, I've deleted all the matches for each player (none of them has any game in his list (not even a closed game). So none of the user is in any match at the moment.
In my GKTurnBaseMatchMakerViewControllerDelegate the turnBasedMatchmakerViewController:didFailWithError: is not called.
The only called function called in the delegate- when I click the OK button on the UIAlertView - is turnBasedMatchmakerViewControllerWasCancelled:
The only thing I can think of is that my games are actually not removed from GameCenter, but as I'm removing them using the GKMatchMakerViewController UI, I barely think so.
When quitting from a turn-based match I've implemented the turnBasedMatchmakerViewController:playerQuitForMatch: like this:
- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController playerQuitForMatch:(GKTurnBasedMatch *)match
{
if ( [self isLocalPlayerCurrentPlayerForMatch:match] ) {
NSData* endData = match.matchData;
for (GKTurnBasedParticipant* participant in match.participants) {
participant.matchOutcome = GKTurnBasedMatchOutcomeWon;
}
match.currentParticipant.matchOutcome = GKTurnBasedMatchOutcomeLost;
[match endMatchInTurnWithMatchData:endData
completionHandler:^(NSError *error) {
if (error) {
NSLog(#"%#",error.description);
}
}];
}
}
(NB: I only have two players in the game)
where isLocalPlayerCurrentPlayerForMatch is:
- (BOOL) isLocalPlayerCurrentPlayerForMatch:(GKTurnBasedMatch*)match
{
return [[[GKLocalPlayer localPlayer] playerID] isEqualToString:match.currentParticipant.playerID];
}
Has anyone encountered and found a solution to this issue?
Am I doing something wrong here, or is it so obvious I just can't see it?
Thank you very much for any comments that would help me find the root of that issue.
Update
Thanks to #kaan-dedeoglu I managed to know that both users had an empty list of matches (consistent with the displayed state).
I also created a third Sandbox account.
Naming the two first accounts A and B, C the third one.
State 1:
A and B are not linked to any match.
A and B are both getting the "Could not create game" error while creating any game (A invites B, A||B invites other player, A||B creates new automatch).
State 2:
C (working account) can invite B and normally plays a party with B.
C (working) can invite B for another simultaneous party
C (working) invites A to play.
A can't play (can't access the list of current matches, the GKTurnBasedMatchMakerViewController directly goes to the creation of a new game).
C is not working anymore.
A, B and C are now stuck in "Could not create game" error.
As a complement here is how I initialize my GKTurnBasedMatchMakerViewController, but I don't see that being wrong.
- (void) displayMatchMakerVC
{
if (! [[GKLocalPlayer localPlayer] isAuthenticated] ) return;
GKMatchRequest* request = [[[GKMatchRequest alloc] init] autorelease];
int nbPlayers = 2;
request.minPlayers = nbPlayers;
request.maxPlayers = nbPlayers;
GKTurnBasedMatchmakerViewController* matchMakerVC = [[[GKTurnBasedMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
matchMakerVC.turnBasedMatchmakerDelegate = self;
matchMakerVC.showExistingMatches = YES;
[[CCDirector sharedDirector] presentModalViewController:matchMakerVC animated:YES];
}
NB: I'm not using ARC, could that be related to a memory issue? I'm not really a memory management guru, but it seems correct to my understanding.
Any idea of how this could be related to my code and not to game center?
Thank you very much for any answer that could help me go further.
Update 2: turnbasedMatchmakerViewController:didFindMatchMethod:
Here's my turnbasedMatchmakerViewController:didFindMatchMethod: method.
- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFindMatch:(GKTurnBasedMatch *)match
{
BLTheme* theme = [[[BLGameConfig sharedConfig] localPlayer] userTheme];
GameSceneRemoteGCLoader* loader = [[GameSceneRemoteGCLoader alloc] initWithGKMatch:match andTheme:theme];
[viewController dismissViewControllerAnimated:NO completion:^{}];
[[CCDirector sharedDirector] replaceScene:loader];
}
When I'm launching an automatch it's launching the exact same error "Could not create game - Please remove an existing game and try again.".
This may or may not be the solution to your problem, but I had a similar issue and solved it in the following way.
It seems that either by default, or somehow, Game Center treats apps with differing CFBundleVersion (build number, not version number, or CFBundleShortVersionString) values as incompatible with one another, and thus does not show matches between apps with incremented build numbers. (Often, developers increment this number as new ad hoc builds or stable releases are distributed during development, so this is quite unfortunate).
To find and remove the "missing" games, I decremented my CFBundleVersion value (which revealed the games), and then deleted the offending matches.
Alternatively, tweaking some settings in iTunes Connect seems to have removed this CFBundleVersion incompatibility. It takes a while to propagate, but I think what did it was tapping on my app, tapping on View Details, making sure the Game Center switch is set to "Enabled", and making sure there is an item in the "Multiplayer Compatibility" table. You could also play with the possibilities within the "Manage Game Center" button from the original app screen, but I think the "Multiplayer Compatibility" setting is what finally allowed me to see all the "old" matches that were previously hidden.
Good luck!
Just to make sure: In both these devices, add these lines in your authentication completion handler and run it once. (then you can comment it out).
[GKTurnBasedMatch loadMatchesWithCompletionHandler:(^)(NSArray *matches, NSError *error) {
for (GKTurnbasedMatch *match in matches) {
[match removeWithCompletionHandler:NULL];
}
}];
This will ensure that all games are removed from your playerID.
It's ridiculous . You don't have to remove an existing match to create a new match. I'm developing a game like this and it actually works.
The following worked for me. First I ran the app on the device for each player, calling quitAllMatches. Then I ran the app again on each device, calling removeAllMatches.
In the long run, it has to be better to clean them up as you go along. But this solved the immediate problem.
-(void) quitAllMatches {
[GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray* matches, NSError* error) {
for (GKTurnBasedMatch* match in matches) {
GKTurnBasedParticipant* participant = match.currentParticipant;
NSString* playerID = participant.playerID;
NSString* localPlayerID = [GKLocalPlayer localPlayer].playerID;
if ([playerID isEqualToString: localPlayerID]) {
NSArray* participants = match.participants;
for (GKTurnBasedParticipant* participant in participants) {
participant.matchOutcome = GKTurnBasedMatchOutcomeTied;
}
NSData* data = [NSData data];
[match endMatchInTurnWithMatchData: data completionHandler:^(NSError* error) {
if (error) {
WJLog(#"did not end -- error %#", [error localizedDescription]);
}
else {
WJLog(#"match ended!");
}
}];
}
}
}];
}
-(void) removeAllMatches {
[GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray* matches, NSError* error) {
for (GKTurnBasedMatch* match in matches) {
[match removeWithCompletionHandler:^(NSError* error) {
if (error) {
WJLog(#"error: %#", [error localizedDescription]);
}
else {
WJLog(#"removed match");
}
}];
}
}];
}
I am adding Game Center functionality to my app. On the simulator, the app registers and loads the high scores perfectly from the Game Center app and the Leaderboard View in my app. When I try the same thing from an actual device,the console says the score was submitted but the score does not show up in the Game Center App or in the Leaderboard View in my app. No idea why this would be. Any Help would be great. Here is my code on how I am implementing this.
My View Did Load
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error){
if (error ==nil) {
NSLog(#"Success");
} else {
NSLog(#"Fail");
}
}];
How I am submitting my score
-(IBAction)submitMyScore{
//This is the same category id you set in your itunes connect GameCenter LeaderBoard
GKScore *myScoreValue = [[[GKScore alloc] initWithCategory:#"01"] autorelease];
myScoreValue.value = score;
[myScoreValue reportScoreWithCompletionHandler:^(NSError *error){
if(error != nil){
NSLog(#"Score Submission Failed");
} else {
NSLog(#"Score Submitted");
}
}];
}
Anyone have any idea why this is?
I fixed the Issue. I logged out of my game center account and then started the game. It prompted me to create a new game center account and I did. It then put me into sandbox mode and allowed me to view and post scores.