I am building a Twitter app (with oAuth) and I cannot find any info on how I can get the current user's info.
By current user, I mean the user which granted my app permissions and for whom the app is making the requests to the API.
Any suggestions?
It was actually "account/verify_credentials" as seen here:
https://developer.twitter.com/en/docs/accounts-and-users/manage-account-settings/api-reference/get-account-verify_credentials.html
Link to the documentation for API v. 1.1: https://dev.twitter.com/docs/api/1.1/get/account/verify_credentials
Using oAuth you are able to make calls to get user info from your TwitterOAuth object.
e.g if
$oauth = new TwitterOAuth([keys here]);
$credentials = $oauth->get('account/verify_credentials');
echo "Connected as #" . $credentials->screen_name ."\n";
Solution respecting iOS:
1) If you have a Twitter account (i.e. ACAccount from ACAccountStore) on your device, the only thing you need is to attach it to SLRequest and get all the user info from the returned dictionary:
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/account/verify_credentials.json"];
NSMutableDictionary *params = [NSMutableDictionary new];
[params setObject:[Twitter sharedInstance].session.userID forKey:#"user_id"];
[params setObject:#"0" forKey:#"include_entities"];
[params setObject:#"1" forKey:#"skip_status"];
[params setObject:#"1" forKey:#"include_email"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:params];
[request setAccount:twitterAccount]; //one of the Twitter Acc
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (responseData) {
NSDictionary *twitterData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:NULL];
});
}else {
NSLog(#"Error while downloading Twitter user data: %#", error);
}
}];
2) Otherwise - you need to send OAuth (X-Auth) user credentials. The easiest way is to use TWTROAuthSigning class to retrieve OAuth-params:
TWTROAuthSigning *oauthSigning =
[[TWTROAuthSigning alloc]
initWithAuthConfig:
[Twitter sharedInstance].authConfig
authSession:session];
NSDictionary *authHeaders =
[oauthSigning OAuthEchoHeadersToVerifyCredentials];
and than send the ordinary request attaching credentials as header fields:
NSString *oauthParameters = authHeaders[#"X-Verify-Credentials-Authorization"];
NSString *urlString = authHeaders[#"X-Auth-Service-Provider"];
NSMutableURLRequest *request =
[NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
request.allHTTPHeaderFields = #{#"Authorization":oauthParameters};
[request setHTTPMethod:#"GET"];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response,NSData *data,NSError *error){
NSDictionary *twitterData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:NULL];
}];
If you support an old version of Twitter SDK or searching for more options I'd recommend to look at STTwitter lib
Related
I have tried to get friend list from facebook using Graph API but it's not returning friend list. I have tried following code to get list after a successful login in facebook...
FBRequest *req = [FBRequest requestForMe];
[req startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *result, NSError *error) {
if (!error)
{
[[VSFacebook sharedFacebook] setFbUser:result];
FriendsViewController *f = [[FriendsViewController alloc] initWithNibName:#"FriendsViewControlleriPad" bundle:nil];
[self presentViewController:f animated:YES completion:nil];
}
}];
and after connecting on FriendsViewContrller.m file I have call graph API to get friend list as following
self.facebookBlock = completionBlock;
NSString *fields = #"id,name,picture,birthday";
NSString *format = #"json";
NSString *urlString = [NSString stringWithFormat:#"https://graph.facebook.com/%#/friends?fields=%#&format=%#&access_token=%#", #"me", fields, format, self.fbAccessTokenData.accessToken];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
id result = nil;
if (data)
{
result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
}
self.facebookBlock([result valueForKey:#"data"], error);
I got on result only three value pair like "summary", "data", "paging"
You cann't get all friends list from facebook using Graph API. It's
not possible to get all Friend's List , according to new API version
I am trying to post new profile picture according to Twitter's documentation at https://dev.twitter.com/rest/reference/post/account/update_profile_image and here is my code:
NSData *jpeg = UIImageJPEGRepresentation(img, 0.9);
NSString *base64 = [jpeg base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/account/update_profile_image.json"];
NSDictionary *params = #{#"image" : base64
};
SLRequest *request =
[SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:url
parameters:params];
[request setAccount:self.twitterAccount];
[request performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse,
NSError *error) {
...
}
But URL response is:
errors = (
{
code = 215;
message = "Bad Authentication data.";
}
);
What am I doing wrong? My ACAccount is valid (I've just tried signing out from and into Twitter in Settings.app).
You code seems fine, but you must be missing something.
Make sure that:
That your Twitter account is connected and is listed in the Settings app Twitter settings. I know you already checked, but it is essential that you verify it. Maybe even restart your phone and make sure your Twitter handle is there afterwards.
That your app has requested and granted permission to
access the account (using the requestAccessToAccountsWithType method). Once permission is granted, you should see your app listed in the Twitter settings (in the Settings app) under "ALLOW THESE APPS TO USE YOUR ACCOUNT".
The Twitter account that you're setting to the SLRequest is valid and is not nil.
Given the conditions above I was abled to modify my profile image successfully just now. Here's a sample code based on the code you've provided:
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];
ACAccount *twitterAccount = [accounts lastObject];
NSData *jpeg = UIImageJPEGRepresentation([UIImage imageNamed:#"photo.jpg"], 0.9);
NSString *base64 = [jpeg base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/account/update_profile_image.json"]
parameters:#{#"image" : base64}];
[request setAccount:twitterAccount];
[request performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse,
NSError *error)
{
NSLog(#"%#", [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil]);
}];
}
}];
I want my app to tag friend within a video-post.
(Posting a video without the tags is working fine)
The account I'm using, has been added to the list of testers for my app.
So I should be able to do this call without any permissions.
But the response is still:
"error: (#3) Application does not have the capability to make this API call."
To get the "Taggable Friends" permission, I need upload a build of my app to fb.
But I can't implement this feature without testing it by myself first.
How can I solve this chicken-and-egg problem?
My code looks like this (iOS - Objc):
NSDictionary *params = #{
#"title": #"some title",
#"description": #"some desctiption",
#"tags": _friendId
};
SLRequest *uploadRequest = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:videourl
parameters:params];
I have found the solution.
You can't set the tag whithin the upload request (I still don't know why).
But you can tag a user in the video after you uploaded the video.
When the upload succeeded, you get a videoId:
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONReadingMutableContainers
error:&error];
_currentVideoId = json[#"id"];
With this id you can make a second request:
ACAccountCredential *fbCredential = [_facebookAccount credential];
NSString *accessToken = [fbCredential oauthToken];
NSString *urlStr = [NSString stringWithFormat: #"https://graph-video.facebook.com/%#/tags?access_token=%#&tag_uid=%#", _currentVideoId, accessToken, userId];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:[NSURL URLWithString: urlStr]
parameters: #{}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
//Do something
}];
});
To make the second request, you need the permission for #"user_videos".
If you want to tag more users, you need to make this request a few times. Maybe it's also possible with one request, but I didn't figuered out how to do it yet.
I have an app that uploaded photos on the fly and i'm trying to add the ability to upload to the users facebook fan page (that they administer).
The problem that i'm having is that i can sucessfully upload a photo to the fan page but it's not showing up on the fan page timeline, it's only showing up under the "Recent Posts by Others" section of the fan page.
I'm obviously not uploading these images properly. Here's my code:
ACAccountType * accountType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
[_accountStore requestAccessToAccountsWithType:accountType options:#{ACFacebookAppIdKey: #"XXXXXXXXXXXX", ACFacebookPermissionsKey : #[#"photo_upload",#"publish_stream", #"publish_actions", #"manage_pages"], ACFacebookAudienceKey : ACFacebookAudienceEveryone} completion:^(BOOL granted, NSError *error) {
if (granted) {
NSArray * accounts = [_accountStore accountsWithAccountType:accountType];
NSDictionary *fanPages = [[NSUserDefaults standardUserDefaults] objectForKey:FACEBOOK_PREF_FAN_PAGES_IDS];
//if using fan pages
if (fanPages.count)
{
for (id key in fanPages) {
//id is the key and the access token is the value
NSLog(#"access token:%#, fanpage id: %#", fanPages[key], key);
NSMutableString *requestURL = [NSMutableString stringWithFormat:#"https://graph.facebook.com/%#/photos/", key];
NSURL * url = [NSURL URLWithString:requestURL];
NSDictionary *parameters = #{#"access_token": [fanPages[key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], #"no_story":#"0", #"message": hashtags};
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodPOST URL:url parameters:parameters];
[request addMultipartData:UIImageJPEGRepresentation(image, 0.9) withName:#"source" type:#"application/octet-stream" filename:#"media.png"];
//NSLog(#"%#",[accounts lastObject]);
[request setAccount:[accounts lastObject]];
//make request
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"uploaded for %#",fanPages[key]);
NSString *respData = [[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding];
NSLog(#"responseData %#",respData);
NSLog(#"urlResponse for %#",urlResponse);
[self performSelectorOnMainThread:#selector(removeProgressView) withObject:nil waitUntilDone:NO];
}];
}
}
else
{
//upload to personal timeline
NSURL * url = [NSURL URLWithString:#"https://graph.facebook.com/me/photos"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodPOST URL:url parameters:nil];
[request addMultipartData:[hashtags dataUsingEncoding:NSUTF8StringEncoding] withName:#"message" type:#"multipart/form-data" filename:nil];
[request addMultipartData:UIImageJPEGRepresentation(image, 0.9) withName:#"source" type:#"application/octet-stream" filename:#"media.png"];
[request setAccount:[accounts lastObject]];
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
[self performSelectorOnMainThread:#selector(removeProgressView) withObject:nil waitUntilDone:NO];
}];
}
} else {
//theres an error or they are not granted
}
Any Ideas on what i'm doing wrong? I've scoured the internet for days on this one and everything seems correct.
So it turns out that i was doing everything correctly, the problem was that if i left in:
[request setAccount:[accounts lastObject]];
This causes it to post on my behalf and wouldn't show up in the timeline. removing this code remedied the issue and all my posts are now showing up on the fan pages timeline from the fan page itself and not from my facebook user account.
Thanks Tobi, i kinda knew it was the access token and i thought i was passing it correctly, apparently i wasn't.
So just to re-iterate, don't use setAccount when posting to a fan page as it will overwrite the access_token with your user token and not the fan page token.
I am able to send a tweet easily using TWRequest like this as per the apple example,
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountaccountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to access their Twitter account
[account requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error)
{
// Did user allow us access?
if (granted == YES)
{
// Populate array with all available Twitter accounts
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
// Sanity check
if ([arrayOfAccounts count] > 0)
{
// Keep it simple, use the first account available
ACAccount *acct = [arrayOfAccounts objectAtIndex:0];
// Build a twitter request
TWRequest *postRequest = [[TWRequest alloc] initWithURL:
[NSURL URLWithString:#"http://api.twitter.com/1/statuses/update.json"]
parameters:[NSDictionary dictionaryWithObject:#"tweet goes here"
forKey:#"status"] requestMethod:TWRequestMethodPOST];
// Post the request
[postRequest setAccount:acct];
// Block handler to manage the response
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
NSLog(#"Twitter response, HTTP response: %i", [urlResponse statusCode]);
}];
but i was wondering if it is possible to use http://api.twitter.com/1/statuses/update_with_media.json in some way to send an image with the tweet instead of going via twitpic or another service. Or is there another way to send an image along with the tweet?
Thanks
It is possible.
You'll need to use addMultiPartData:withName:type: method for adding attributes for your tweet.
Status text won't be displayed until you add it as multipart data.
TWRequest *postRequest = [[TWRequest alloc] initWithURL:[NSURL URLWithString:#"https://upload.twitter.com/1/statuses/update_with_media.json"] parameters:nil requestMethod:TWRequestMethodPOST];
NSData *myData = UIImagePNGRepresentation(img);
[postRequest addMultiPartData:myData withName:#"media" type:#"image/png"];
myData = [[NSString stringWithFormat:#"Any status text"] dataUsingEncoding:NSUTF8StringEncoding];
[postRequest addMultiPartData:myData withName:#"status" type:#"text/plain"];