I am trying to make a function which returns a list of twitter users but I am not able to make the function return a nsmutablearray. Here it is the code I execute
-(NSMutableArray*) getTwitterUsersInPosition: (Position*) position
{
// Request access to the Twitter accounts
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error){
if (granted) {
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
// Check if the users has setup at least one Twitter account
if (accounts.count > 0)
{
ACAccount *twitterAccount = [accounts objectAtIndex:0];
// Creating a request to get the info about a user on Twitter
NSArray *keys = [NSArray arrayWithObjects:#"geocode", #"count", nil];
NSArray *objects = [NSArray arrayWithObjects:#"37.781157,-122.398720,100mi", #"2", nil];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects
forKeys:keys];
SLRequest *twitterInfoRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/search/tweets.json"] parameters:dictionary];
[twitterInfoRequest setAccount:twitterAccount];
// Making the request
[twitterInfoRequest performRequestWithHandler: ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the rate limit
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
// Check if there was an error
if (error) {
NSLog(#"Error: %#", error.localizedDescription);
return;
}
// Check if there is some response data
if (responseData) {
NSError *error = nil;
NSArray *TWData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
NSMutableArray *usersArray= [[NSMutableArray alloc] init];
NSMutableArray* statuses= [(NSDictionary *) TWData objectForKey:#"statuses"];
for (NSDictionary* dict in statuses )
{
NSString* user = [[dict objectForKey:#"user"] objectForKey:#"screen_name"];
NSLog(#"%#",user);
[usersArray addObject:user];
}
return userArray; //Here it says "Return type 'NSMutabelArray *' must match previous type 'void' when block literal has unspecified return type
}
});
}];
}
} else {
NSLog(#"No access granted");
}
}];
}
Thanks for your help.
Your method can NOT have a return type because the value you want to return is obtained asynchronously and isn't available until after the method has completed.
You need to rewrite your method so that it returns the data:
To a delegate
Via a block
Into an instance variable and triggers some update
Via a notification
Basically some mechanism that allows you to deal with the asynchronous response. Please don't make the call synchronous.
In the middle of your code you simply write return without a value (as if your method has return type of void):
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
// Check if there was an error
if (error) {
NSLog(#"Error: %#", error.localizedDescription);
return;
Change it to return nil and the code should compile.
Related
Getting the list of followers from twitter sdk using fabric but not able to get more than 20. And another limitation is need to get the all followers first and then upload to api. I am using code below to get the followers list. Please guide wha changes need to make in existing code or need to shift to some new way.
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error){
if (granted) {
//[MBProgressHUD showHUDAddedTo:self.view animated:YES];
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
// Check if the users has setup at least one Twitter account
if (accounts.count > 0)
{
ACAccount *twitterAccount = [accounts objectAtIndex:0];
// Creating a request to get the info about a user on Twitter
SLRequest *twitterInfoRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/followers/list.json"] parameters:[NSDictionary dictionaryWithObject:twitterAccount.username forKey:#"screen_name"]];
[twitterInfoRequest setAccount:twitterAccount];
// Making the request
[twitterInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the reate limit
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
if (error) {
NSLog(#"Error: %#", error.localizedDescription);
return;
}
// Check if there is some response data
if (responseData) {
NSError *error = nil;
NSArray *TWData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
// Filter the preferred data
NSArray *arrFollowList = [TWData valueForKey:#"users"];
// Filter the preferred data
NSMutableArray *arrFollowersList = [[NSMutableArray alloc]init];
for(int i =0; i<[arrFollowList count]; i++)
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
[dict setObject:[[arrFollowList objectAtIndex:i] valueForKey:#"name"] forKey:#"FriendName"];
[dict setObject:#"" forKey:#"Email"];
[dict setObject:strType forKey:#"FriendType"];
[dict setObject:[[arrFollowList objectAtIndex:i] valueForKey:#"id"] forKey:#"UserAccountId"];
//[dict setObject:#"" forKey:#"UserAccountId"];
[dict setObject:#"1" forKey:#"Team_Id"];
[dict setObject:[[arrFollowList objectAtIndex:i] valueForKey:#"profile_image_url"] forKey:#"ProfileImage"];
[arrFollowersList addObject:dict];
}
NSString *teamId = #"1";
NSDictionary *objDict = [NSDictionary dictionaryWithObjectsAndKeys:
teamId, #"Team_Id",
arrFollowersList, #"userFriendList",
nil];
NSLog(#"dict %#",objDict);
[iOSRequest postData:[NSString stringWithFormat:#"%#", kFriendListUpdateUrl] :objDict :^(NSDictionary *response_success)
{
NSLog(#"response_success:%#", response_success);
if([[response_success valueForKey:#"message"] isEqualToString:#"Success"])
{
NSMutableDictionary *dictSquads = [[NSMutableDictionary alloc]init];
[dictSquads setObject:[standardDefaults valueForKey:#"UserId"] forKey:#"User_Id"];
[dictSquads setObject:#"1" forKey:#"Team_Id"];
[dictSquads setObject:strType forKey:#"FriendType"];
}
}
:^(NSError *response_error)
{
}];
}
});
}];
}
} else {
NSLog(#"No access granted");
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
}
}];
How can I get all followers and following from a user's Twitter account.
I get followers and following counts. However I need usernames of followers and following users.
Here my code.
- (void) getAccountInfo
{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error){
if (granted) {
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
// Check if the users has setup at least one Twitter account
if (accounts.count > 0)
{
ACAccount *twitterAccount = [accounts objectAtIndex:0];
// Creating a request to get the info about a user on Twitter
SLRequest *twitterInfoRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/users/show.json"] parameters:[NSDictionary dictionaryWithObject:twitterAccount.username forKey:#"screen_name"]];
[twitterInfoRequest setAccount:twitterAccount];
// Making the request
[twitterInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the reate limit
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
// Check if there was an error
if (error) {
NSLog(#"Error: %#", error.localizedDescription);
return;
}
// Check if there is some response data
if (responseData) {
NSError *error = nil;
NSArray *TWData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
// Filter the preferred data
NSString *screen_name = [(NSDictionary *)TWData objectForKey:#"screen_name"];
NSString *name = [(NSDictionary *)TWData objectForKey:#"name"];
int followers = [[(NSDictionary *)TWData objectForKey:#"followers_count"] integerValue];
int following = [[(NSDictionary *)TWData objectForKey:#"friends_count"] integerValue];
}
});
}];
}
} else {
NSLog(#"No access granted");
}
}];
}
Getting list of followers
To get list of followers, change the URL you are requesting to:
https://api.twitter.com/1.1/followers/list.json
It returns a cursored collection of user objects for users following the specified user.
Getting list of followed users
To get list of the users you follow, change the URL you are requesting to:
https://api.twitter.com/1.1/friends/list.json
It returns a cursored collection of user objects for every user the specified user is following (otherwise known as their "friends").
I used your code to test it and it works. Based on REST API v1.1 Resources
You can use Criexe API, if you don't want use API.
https://github.com/criexe/api/wiki/Social-Networks-Page-Stats-API
Example:
GET https://api.criexe.com/social/pageStats?twitter=microsoft
{
"twitter":{
"user":"microsoft",
"followers":8293150
},
"total":8293150
}
I'm trying to get the user's Twitter timeline using the Twitter API in iOS SDK and got an error saying:
code = 92; message = "SSL is required";
I googled the error and I found this page on the Twitter API website, but I have no idea how to use it in iOS.
Here's my code:
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error)
{
if (granted == YES){
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0) {
ACAccount *twitterAccount = [arrayOfAccounts lastObject];
NSURL *requestAPI = [NSURL URLWithString:#"http://api.twitter.com/1.1/statuses/user_timeline.json"];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
[parameters setObject:#"100" forKey:#"count"];
[parameters setObject:#"1" forKey:#"include_entities"];
SLRequest *posts = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:requestAPI parameters:parameters];
posts.account = twitterAccount;
[posts performRequestWithHandler:
^(NSData *response, NSHTTPURLResponse
*urlResponse, NSError *error)
{
// The NSJSONSerialization class is then used to parse the data returned and assign it to our array.
array = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
if (array.count != 0) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"%#",array);
});
}
}];
}
} else {
// Handle failure to get account access
NSLog(#"%#", [error localizedDescription]);
}
}];
Is there a way to solve this problem?
Use "https" in your URL:
https://api.twitter.com/1.1/statuses/user_timeline.json
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
i have used Twitter API to get followers and following.
i have write this code. to get followers and following
-(void)getTwitterAccounts
{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
// Create an account type that ensures Twitter accounts are retrieved.
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// let's request access and fetch the accounts
[accountStore requestAccessToAccountsWithType:accountType
withCompletionHandler:^(BOOL granted, NSError *error)
{
// check that the user granted us access and there were no errors (such as no accounts added on the users device)
if (granted && !error)
{
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
if ([accountsArray count] > 1) {
// a user may have one or more accounts added to their device
// you need to either show a prompt or a separate view to have a user select the account(s) you need to get the followers and friends for
} else {
[self getTwitterFriendsForAccount:[accountsArray objectAtIndex:0]];
}
} else {
// handle error (show alert with information that the user has not granted your app access, etc.)
}
}];
}
-(void)getTwitterFriendsForAccount:(ACAccount*)account
{
// In this case I am creating a dictionary for the account
// Add the account screen name
NSMutableDictionary *accountDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:account.username, #"screen_name", nil];
// Add the user id (I needed it in my case, but it's not necessary for doing the requests)
[accountDictionary setObject:[[[account dictionaryWithValuesForKeys:[NSArray arrayWithObject:#"properties"]] objectForKey:#"properties"] objectForKey:#"user_id"] forKey:#"user_id"];
// Setup the URL, as you can see it's just Twitter's own API url scheme. In this case we want to receive it in JSON
NSURL *followingURL = [NSURL URLWithString:#"http://api.twitter.com/1/friends/ids.json"];
// Pass in the parameters (basically '.ids.json?screen_name=[screen_name]')
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:account.username, #"screen_name", nil];
// Setup the request
TWRequest *twitterRequest = [[TWRequest alloc] initWithURL:followingURL
parameters:parameters
requestMethod:TWRequestMethodGET];
// This is important! Set the account for the request so we can do an authenticated request. Without this you cannot get the followers for private accounts and Twitter may also return an error if you're doing too many requests
[twitterRequest setAccount:account];
// Perform the request for Twitter friends
[twitterRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (error) {
// deal with any errors - keep in mind, though you may receive a valid response that contains an error, so you may want to look at the response and ensure no 'error:' key is present in the dictionary
}
NSError *jsonError = nil;
// Convert the response into a dictionary
NSDictionary *twitterFriends = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&jsonError];
// Grab the Ids that Twitter returned and add them to the dictionary we created earlier
[accountDictionary setObject:[twitterFriends objectForKey:#"ids"] forKey:#"friends_ids"];
NSLog(#"%#", accountDictionary);
}];
}
but this code not works
give me error
NSRangeException', reason: '* -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array'**
why this is happening. please help me to sort out this.
Finally i get the solution.
Here is the Solution for get the Twitter Followers and Following Names
First you need to get the Valid Username. and that name you can get it from
this code.
NSString * username = [FHSTwitterEngine sharedEngine].authenticatedUsername;
using that username you can get whatever you want
NSMutableDictionary * dict1 = [[FHSTwitterEngine sharedEngine]listFriendsForUser:username isID:NO withCursor:#"-1"];
NSLog(#"====> %#",[dict1 objectForKey:#"users"] ); // Here You get all the data
NSMutableArray *array=[dict1 objectForKey:#"users"];
for(int i=0;i<[array count];i++)
{
NSLog(#"names:%#",[[array objectAtIndex:i]objectForKey:#"name"]);
}
Try this. Looks like you were trying to use old twitter api
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error){
if (granted) {
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
// Check if the users has setup at least one Twitter account
if (accounts.count > 0)
{
ACAccount *twitterAccount = [accounts objectAtIndex:0];
for(ACAccount *t in accounts)
{
if([t.username isEqualToString:username])
{
twitterAccount = t;
break;
}
}
SLRequest *twitterInfoRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/friends/ids.json?"] parameters:[NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:#"%#", username], #"screen_name", #"-1", #"cursor", nil]];
[twitterInfoRequest setAccount:twitterAccount];
// Making the request
[twitterInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the reate limit
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
// Check if there was an error
if (error) {
NSLog(#"Error: %#", error.localizedDescription);
return;
}
// Check if there is some response data
if (responseData) {
NSError *error = nil;
NSArray *TWData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
}
});
}];
}
} else {
NSLog(#"No access granted");
}
}];
- (IBAction)loginToTwitter:(id)sender {
self.accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[self.accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if(granted) {
NSArray *accounts = [self.accountStore accountsWithAccountType:accountType];
if ([accounts count] > 0) {
ACAccount *twitterAccount = [accounts objectAtIndex:0];
NSLog(#"User Name: %#",twitterAccount.username);
NSLog(#"Account Type: %#",twitterAccount.accountType);
NSArray *userID = [[accounts valueForKey:#"properties"] valueForKey:#"user_id"];
NSString *url_users_show = [NSString stringWithFormat:#"https://api.twitter.com/1.1/users/show.json?user_id=%#",[userID objectAtIndex:0]];
SLRequest *getRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:url_users_show] parameters:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"%#",[userID objectAtIndex:0]] forKey:#"user_id"]];
getRequest.account = twitterAccount;
[getRequest performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse, NSError *error)
{
if(responseData) {
NSLog(#"Twitter HTTP response: %i", [urlResponse statusCode]);
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
if(responseDictionary) {
NSLog(#"Response: %#", responseDictionary);
if ([responseDictionary objectForKey:#"errors"]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self showAlert: #"Twitter": [[[responseDictionary objectForKey:#"errors"] objectAtIndex:0] objectForKey:#"message"]];
});
}
}
} else {
// responseDictionary is nil
dispatch_async(dispatch_get_main_queue(), ^{
[self showAlert: #"Twitter": #"Unable to authenticate you"];
});
}
}];
}
} else {
//Failed
NSLog(#"error getting permission %#",error);
dispatch_async(dispatch_get_main_queue(), ^{
[self showAlert: #"No Twitter Account Detected": #"Please go into your device's settings menu to add your Twitter account."];
});
}
}];
}
Above is my code and below is the output on my console.
Output:
Twitter HTTP response: 401
Response: {
errors = (
{
code = 32;
message = "Could not authenticate you";
}
);
}
I want to fetch users data like First Name, Last Name, Profile Picture, Login ID from Twitter.
Thanks in advance...