Skip to content

Instantly share code, notes, and snippets.

@lamprosg
Last active January 3, 2016 14:03
Show Gist options
  • Save lamprosg/5021076 to your computer and use it in GitHub Desktop.
Save lamprosg/5021076 to your computer and use it in GitHub Desktop.
(iOS) iOS6 Social framework
Official Twitter API (Has all the service URLs)
https://dev.twitter.com/docs/api/1.1
#import <Foundation/Foundation.h>
#import <Social/Social.h>
#import <Accounts/Accounts.h>
//Twitter GET USER INFO Service URL
//https://dev.twitter.com/docs/api/1.1/get/users/show
#define TWITTERGETUSERINFOURL @"https://api.twitter.com/1.1/users/show.json"
//User info json keys
#define SCREEN_NAME_KEY @"screen_name"
#define NAME_KEY @"name"
#define FOLLOWERS_COUNT_KEY @"followers_count"
#define FRIENDS_COUNT_KEY @"friends_count"
#define TWEET_COUNT_KEY @"statuses_count"
#define PROFILE_IMAGE_KEY @"profile_image_url_https"
#define PROFILE_BANNER_KEY @"profile_banner_url"
#define TWEET_KEY @"status"
//Twitter FAVORITE A TWEET Service URL
//https://dev.twitter.com/docs/api/1.1/post/favorites/create
#define TWITTERFAVORITETWEET @"https://api.twitter.com/1.1/favorites/create.json"
//Tweet to be favorited json key
#define FAVORITEIDKEY @"id"
//Twitter RETWEET Service URL
//https://dev.twitter.com/docs/api/1.1/post/statuses/retweet/%3Aid
#define TWITTERRETWEET @"https://api.twitter.com/1.1/statuses/retweet/tweetid.json"
//Twitter UPDATE Service URL
//https://dev.twitter.com/docs/api/1/post/statuses/update
#define TWITTERUPDATE @"https://api.twitter.com/1.1/statuses/update.json"
//Text to be tweeted json key
#define TWEETTEXT @"id_str"
//In reply to tweet json key
#define REPLYTOSTATUSKEY @"in_reply_to_status_id"
//Twitter FOLLOW Service URL
//https://dev.twitter.com/docs/api/1.1/post/friendships/create
#define FOLLOWUSER @"https://api.twitter.com/1.1/friendships/create.json"
//User id to follow json key
#define USERTOFOLLOWKEY @"user_id"
//Enable notificationsbBoolean json key
#define FOLLOWKEY @"follow"
//Twitter UNFOLLOW Service URL
//https://dev.twitter.com/docs/api/1.1/post/friendships/destroy
#define UNFOLLOWUSER @"https://api.twitter.com/1.1/friendships/destroy.json"
//User id to follow json key
#define USERTOUNFOLLOWKEY @"user_id"
@protocol SocialDelegate <NSObject>
@optional
-(void) connectedToTwitter;
@end
@interface Social : NSObject <UIActionSheetDelegate>
@property (nonatomic, weak) id <SocialDelegate> delegate;
-(void)connectToTwitter;
-(void)signOut;
-(void)postTweet:(NSString*)text withURL:(NSString*)url andImage:(NSString*)imageFile fromViewController:(UIViewController*)vc;
-(void)favoriteTweetWithID:(NSString*)tweetID;
-(void)retweetWithID:(NSString*)tweetID;
-(void)replyToTweetWithID:(NSString*)tweetID withResponseTweet:(NSString*)responseTweet;
-(void)followUserWithID:(NSString*)userId;
-(void)unfollowUserWithID:(NSString*)userId;
@end
#import "Social.h"
#import "SVProgressHUD.h"
#import "Engine.h"
#import "UtilImage.h"
#import "Config.h"
#import "MenuViewController.h"
@implementation Social
#pragma mark - Connect to Twitter
-(void)connectToTwitter
{
[SVProgressHUD showWithStatus:L(RETRIEVINGINFO) maskType:SVProgressHUDMaskTypeBlack];
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
//Obtain access to the user's Twitter accounts
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; //ACAccountTypeIdentifierFacebook for Facebook
[accountStore requestAccessToAccountsWithType:accountType options:nil
completion:^(BOOL granted, NSError *error) {
if(granted)
{
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
if ([accountsArray count] == 1) //If there os only one account log in with that
{
Eng.twitterUser.connected = YES;
Eng.twitterUser.twitterAccount = [accountsArray objectAtIndex:0];
[self connectToTwitterWithAccount:Eng.twitterUser.twitterAccount];
}
else if ([accountsArray count] > 0)
{
Eng.twitterUser.connected = YES;
//Display all accounts for selection
dispatch_async(dispatch_get_main_queue(), ^{
UIActionSheet *accountsSheet = [[UIActionSheet alloc] init];
[accountsSheet setDelegate:self];
[accountsSheet setTitle:L(TWITTERACCOUNTS)];
[accountsSheet addButtonWithTitle:L(CANCEL)];
[accountsSheet setDestructiveButtonIndex:0];
//Adding twitter names
for (ACAccount *twitterAccount in accountsArray) {
[accountsSheet addButtonWithTitle:twitterAccount.username];
}
accountsSheet.actionSheetStyle = UIActionSheetStyleDefault;
UIStoryboard *storybrd = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MenuViewController *menuvc = [storybrd instantiateViewControllerWithIdentifier:@"MenuID"];
[accountsSheet showInView:menuvc.view];
});
}
else //No accounts availabke
{
Eng.twitterUser.connected = NO;
[SVProgressHUD dismiss];
}
}
else //Access is not granted
{
Eng.twitterUser.connected = NO;
[SVProgressHUD dismiss];
}
if (!Eng.twitterUser.connected)
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Twitter"
message:L(TWITTERNOTAVAILABLE)
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];
}
}];
}
-(void)connectToTwitterWithAccount:(ACAccount*)account
{
//Get the user account
Eng.twitterUser.twitterAccount = account;
SLRequest *twitterInfoRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:TWITTERGETUSERINFOURL] parameters:[NSDictionary dictionaryWithObject:Eng.twitterUser.twitterAccount.username forKey:SCREEN_NAME_KEY]];
[twitterInfoRequest setAccount:Eng.twitterUser.twitterAccount];
[twitterInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
// Check if we reached the reate limit
if ([urlResponse statusCode] == 429) {
NSLog(@"Rate limit reached");
Eng.twitterUser.connected = NO;
return;
}
// Check if there was an error
if (error) {
NSLog(@"Error: %@", error.localizedDescription);
Eng.twitterUser.connected = NO;
return;
}
// Check if there is some response data
if (responseData)
{
NSError *error = nil;
id TWData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
if ([TWData isKindOfClass:[NSDictionary class]])
{
// Get the user info
Eng.twitterUser.screen_name = [TWData objectForKey:SCREEN_NAME_KEY];
Eng.twitterUser.name = [TWData objectForKey:NAME_KEY];
Eng.twitterUser.followers = [[TWData objectForKey:FOLLOWERS_COUNT_KEY] integerValue];
Eng.twitterUser.following = [[TWData objectForKey:FRIENDS_COUNT_KEY] integerValue];
Eng.twitterUser.tweets = [[TWData objectForKey:TWEET_COUNT_KEY] integerValue];
Eng.twitterUser.profileImageStringURL = [TWData objectForKey:PROFILE_IMAGE_KEY];
Eng.twitterUser.bannerImageStringURL =[TWData objectForKey:PROFILE_BANNER_KEY];
Eng.twitterUser.lastTweet = [[TWData objectForKey:TWEET_KEY] objectForKey:@"text"];
// Get the profile image in the original resolution
Eng.twitterUser.originalProfileImageStringURL = [Eng.twitterUser.profileImageStringURL stringByReplacingOccurrencesOfString:@"_normal" withString:@""];
//Retina banner
Eng.twitterUser.retinaBannerImageStringURL = [NSString stringWithFormat:@"%@/mobile_retina", Eng.twitterUser.bannerImageStringURL];
//User will be connected from now on
Eng.twitterUser.connected = YES;
[SVProgressHUD dismiss];
if (self.delegate && [self.delegate respondsToSelector:@selector(connectedToTwitter)]) {
[self.delegate connectedToTwitter];
}
}
}
}); //End of twitter info request
}]; //End of completion handler
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == actionSheet.destructiveButtonIndex)
{
[SVProgressHUD dismiss];
}
if (buttonIndex>0)
{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
//Obtain access to the user's Twitter accounts
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; //ACAccountTypeIdentifierFacebook for Facebook
[accountStore requestAccessToAccountsWithType:accountType options:nil
completion:^(BOOL granted, NSError *error) {
if(granted)
{
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
ACAccount* twitterAccount = [accountsArray objectAtIndex:buttonIndex-1];
NSLog(@"Selected user: %@", twitterAccount.username);
[self connectToTwitterWithAccount:twitterAccount];
}
}];
}
}
#pragma mark - Post a tweet
-(void)postTweet:(NSString*)text withURL:(NSString*)url andImage:(NSString*)imageFile fromViewController:(UIViewController*)vc
{
if (!Eng.twitterUser.connected)
{
NSLog(@"User is not signed in");
return;
}
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
SLComposeViewController *tweetVC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter]; //SLServiceTypeFacebook for Facebook
[tweetVC addURL:[NSURL URLWithString:url]];
[tweetVC addImage:[UIImage imageNamed:imageFile]];
[tweetVC setInitialText:text];
[vc presentViewController:tweetVC animated:YES completion:nil];
// 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;
// }
//
// // dismiss the Tweet Sheet
// dispatch_async(dispatch_get_main_queue(), ^{
// [vc dismissViewControllerAnimated:NO completion:^{
// NSLog(@"Tweet Sheet has been dismissed.");
// }];
// });
// };
}
else
{
[SVProgressHUD showErrorWithStatus:L(TWITTERNOTAVAILABLE)];
}
}
#pragma mark - Favorite a tweet
-(void)favoriteTweetWithID:(NSString*)tweetID {
if (!Eng.twitterUser.connected)
{
NSLog(@"User is not signed in");
return;
}
SLRequest *twitterFavoriteRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:TWITTERFAVORITETWEET] parameters:[NSDictionary dictionaryWithObject:tweetID forKey:FAVORITEIDKEY]];
[twitterFavoriteRequest setAccount:Eng.twitterUser.twitterAccount];
[twitterFavoriteRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
//Chcek if the favorite action is succesfull (200 OK response)
if ([urlResponse statusCode] == 200)
{
NSLog(@"Tweet with id:%@ favorited",tweetID);
[SVProgressHUD showSuccessWithStatus:L(TWEETFAVORITED)];
}
else
{
if (error)
{
NSLog(@"Error: %@", error.localizedDescription);
}
[SVProgressHUD showErrorWithStatus:L(FAILED)];
}
});
}];
}
#pragma mark - Retweet
-(void)retweetWithID:(NSString*)tweetID {
if (!Eng.twitterUser.connected)
{
NSLog(@"User is not signed in");
return;
}
NSString* twitterretweetservice = [TWITTERRETWEET stringByReplacingOccurrencesOfString:@"tweetid" withString:tweetID];
SLRequest *twitterRetweetRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:twitterretweetservice] parameters:nil];
[twitterRetweetRequest setAccount:Eng.twitterUser.twitterAccount];
[twitterRetweetRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the reate limit
if ([urlResponse statusCode] == 403) {
NSLog(@"Rate limit reached");
[SVProgressHUD showErrorWithStatus:L(FAILED)];
return;
}
NSLog(@"Tweet with id:%@ retweeted",tweetID);
[SVProgressHUD showSuccessWithStatus:L(RETWEETED)];
});
}];
}
#pragma mark - Reply to Tweet
-(void)replyToTweetWithID:(NSString*)tweetID withResponseTweet:(NSString*)responseTweet {
if (!Eng.twitterUser.connected)
{
NSLog(@"User is not signed in");
return;
}
NSMutableDictionary* postData = [[NSMutableDictionary alloc] init];
[postData setObject:responseTweet forKey:TWEETTEXT];
[postData setObject:tweetID forKey:REPLYTOSTATUSKEY];
SLRequest *twitterReplyRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:TWITTERUPDATE] parameters:postData];
[twitterReplyRequest setAccount:Eng.twitterUser.twitterAccount];
[twitterReplyRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (responseData)
{
NSError *parseError = nil;
id json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&parseError];
if (!json)
{
NSLog(@"Parse Error: %@", parseError);
[SVProgressHUD showErrorWithStatus:L(FAILED)];
}
else
{
NSLog(@"Tweet with id:%@ replied",tweetID);
[SVProgressHUD showSuccessWithStatus:L(REPLIED)];
}
}
else
{
NSLog(@"Request Error: %@", [error localizedDescription]);
[SVProgressHUD showErrorWithStatus:L(FAILED)];
}
});
}];
}
#pragma mark - Follow a user
-(void)followUserWithID:(NSString*)userId {
if (!Eng.twitterUser.connected)
{
NSLog(@"User is not signed in");
return;
}
NSMutableDictionary* postData = [[NSMutableDictionary alloc] init];
[postData setObject:userId forKey:USERTOFOLLOWKEY];
[postData setObject:@"true" forKey:FOLLOWKEY];
SLRequest *twitterFollowRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:FOLLOWUSER] parameters:postData];
[twitterFollowRequest setAccount:Eng.twitterUser.twitterAccount];
[twitterFollowRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
//User is already followed
if ([urlResponse statusCode] == 403)
{
NSLog(@"User is already being followed");
return;
}
//Chcek if the follow action is succesfull (200 OK response)
if ([urlResponse statusCode] == 200)
{
NSLog(@"Followed user with id:%@",userId);
}
else
{
if (error)
{
NSLog(@"Error: %@", error.localizedDescription);
}
[SVProgressHUD showErrorWithStatus:L(FAILED)];
}
});
}];
}
#pragma mark - Unfollow a user
-(void)unfollowUserWithID:(NSString*)userId {
if (!Eng.twitterUser.connected)
{
NSLog(@"User is not signed in");
return;
}
SLRequest *twitterUnfollowRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:UNFOLLOWUSER] parameters:[NSDictionary dictionaryWithObject:userId forKey:USERTOUNFOLLOWKEY]];
[twitterUnfollowRequest setAccount:Eng.twitterUser.twitterAccount];
[twitterUnfollowRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
//Chcek if the funollow action is succesfull (200 OK response)
if ([urlResponse statusCode] == 200)
{
NSLog(@"Unfollowed user with id:%@",userId);
}
else
{
if (error)
{
NSLog(@"Error: %@", error.localizedDescription);
}
[SVProgressHUD showErrorWithStatus:L(FAILED)];
}
});
}];
}
#pragma mark - Sign Out
-(void)signOut {
Eng.twitterUser.screen_name = nil;
Eng.twitterUser.name = nil;
Eng.twitterUser.followers = 0;
Eng.twitterUser.following = 0;
Eng.twitterUser.tweets = 0;
Eng.twitterUser.profileImageStringURL = nil;
Eng.twitterUser.bannerImageStringURL = nil;
Eng.twitterUser.lastTweet = nil;
Eng.twitterUser.originalProfileImageStringURL = nil;
Eng.twitterUser.retinaBannerImageStringURL = nil;
//User will be logged off
Eng.twitterUser.connected = NO;
[SVProgressHUD showSuccessWithStatus:L(SIGNEDOUT)];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment