Invalid Facebook access token - iphone

I am developing an application which posts videos to Facebook.
I have registered this app on Facebook, received APIkey, APIsecret, the app successfully passes authentication and receives the access token. Here is my code for authentication:
m_Facebook = [[Facebook alloc] init];
[m_Facebook logout:self];
m_FacebookUploader = [[FBVideoUpload alloc]init];
NSArray *permissions = [NSArray arrayWithObjects:#"publish_stream", #"offline_access",#"read_stream",nil];
m_Facebook.forceOldStyleAuth = YES;
[m_Facebook authorize:kApiKey permissions:permissions delegate:self];
However when trying to upload a video, the class FBVideoUpload tries to separate the access token into several parts:
- (NSString*) sessionID
{
NSArray *components = [accessToken componentsSeparatedByString:#"|"];
NSLog(#"components: %#", components);
return [components count] < 2 ? nil : [components objectAtIndex:1];
}
According to http://developers.facebook.com/docs/authentication/ the access token should contain several componenets, separated by "|", but the one I receive at authentication does not contain several components separated by a "|". The access_token I receive looks as follows:
AAA*GXJapke*BAGRlZC7aBLhiZB*MUEV*AAF6*ZBhZBw*0ER1M*vkXlRUZCwO*czfgs*wHbnA*BcTU*VrPZC*Yw3p*JmCIMZ*xSnCP*GqPRWZALgZDZ*
(I replaced some symbols with "*")
Here is my code for uploading the video:
[m_FacebookUploader setApiKey:kApiKey];
[m_FacebookUploader setAccessToken:m_Facebook.accessToken];
[m_FacebookUploader setAppSecret:kApiSecret];
[m_FacebookUploader startUploadWithURL:url params:params delegate:self];
I receive an error here:
if ([self sessionID] == nil) {
NSLog(#"Unable to retrieve session key from the access token.");
return;
}
Which not surprising since sessionID really returns nil.

Whatever library you're using to do that video upload is using some outdated logic to handle uploads. That whole method where it breaks apart the session key doesn't need to exist. Just use the access token you get back from FB with your video upload request. Also, be sure you're using our latest SDK https://github.com/facebook/facebook-ios-sdk

Related

iOS Twitter User-Timeline fetching with v1.1 API

Recently Twitter has changed API to v1.1. With this API, it is now required to first login on Twitter and only then we can fetch timeline. Is that true?
Can we fetch user timeline without user login?
Thanks
I tried FHSTwitterEngine but I found STTwitter better:
https://github.com/nst/STTwitter
look at FHSTwitterEngine you can use newly FHSTwitterEngine and if you request this method without autenticating, the users status is removed... you have to send consumer key and token along with screen_name..
In FHSTwitterEngine
//get username pass to method. In Dictionary you can get all info
NSString *username = [[FHSTwitterEngine sharedEngine]loggedInUsername];
NSDictionary *data=[[FHSTwitterEngine sharedEngine]getUserProfile:username];
// method to get all user info
-(id)getUserProfile:(NSString *)username
{
if (username.length == 0) {
return getBadRequestError();
}
NSURL *baseURL = [NSURL URLWithString:url_users_show];
OAMutableURLRequest *request = [OAMutableURLRequest requestWithURL:baseURL consumer:self.consumer token:self.accessToken];
OARequestParameter *usernameP = [OARequestParameter requestParameterWithName:#"screen_name" value:username];
NSArray *params = [NSArray arrayWithObjects:usernameP, nil];
id userShowReturn = [self sendGETRequest:request withParameters:params];
return userShowReturn;
}
You can perfectly fetch a user timeline even if the user is not logged in.
You have to use the new "App Only" mode in which only the application is authentified.
See more details in this answer.

Google+ check-in location in ios

I want to implement location check-in feature in ios. My application is using google+ ios sdk. The problem which I am facing is that after I have implemented google+ check-in feature then that post is not being displayed on my google+ account.
The technique which I have tried and implemented is written below.
-(IBAction)checkIn
{
GTMOAuth2Authentication *auth = [GPPSignIn sharedInstance].authentication;
GTLServicePlus* plusService = [[GTLServicePlus alloc] init] ;
plusService.retryEnabled = YES;
[plusService setAuthorizer:auth];
GTLPlusMoment *moment = [[GTLPlusMoment alloc] init];
moment.type = #"http://schemas.google.com/CheckInActivity";
GTLPlusItemScope *target = [[GTLPlusItemScope alloc] init] ;
target.url =#"https://developers.google.com/+/plugins/snippet/examples/place";
moment.target = target;
GTLQueryPlus *query =
[GTLQueryPlus queryForMomentsInsertWithObject:moment
userId:#"me"
collection:kGTLPlusCollectionVault];
[plusService executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
id object,
NSError *error) {
if (error) {
GTMLoggerError(#"Error: %#", error);
NSString *failure =
[NSString stringWithFormat:#"Status: Error: %#", error];
NSLog(#"%#",failure);
} else {
NSString *result = #"CheckedIn Saved in Google+";
NSLog(#"%#",result);
}
}];
}
Can any one please help me out. Is this the right way of implementing location check-in feature of google+ or is there any other method for it?
The method you're using is writing an "app activity" to Google+, which stores a "moment" in the user's app activity vault. As noted on https://developers.google.com/+/mobile/ios/app-activities these moments are not directly visible on the user's stream, although users may choose to share them to the stream if they wish.
To see the moments that have been shared, you will need to use the desktop app. Your profile has a list of apps that are using the Google+ Sign-In and you can view, share, and delete the activities for each of these apps. The mobile Google+ clients don't let you view the activities yet.

iOS 6 SDK SLRequest returning '400'

Let me make this clear. I am NOT using the Facebook SDK. I'm using iOS SDK's Social.framework, and ACAccountStore to access Facebook accounts, and post with it/them.
I use the same code to post on Twitter. It works 100%. But for some reason regardless of what I do for Facebook integration, I get a "400" error when I try to post.
My method is:
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *facebookAccountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
// Specify App ID and permissions
NSDictionary *options = #{ ACFacebookAppIdKey: #"MY_APP_ID",ACFacebookPermissionsKey: #[#"publish_stream", #"publish_actions"],ACFacebookAudienceKey: ACFacebookAudienceFriends };
[account requestAccessToAccountsWithType:facebookAccountType options:options
completion:^(BOOL granted, NSError *error)
{
if (granted == YES)
{
NSDictionary *parameters = #{#"message": string999};
NSURL *feedURL = [NSURL URLWithString:#"https://graph.facebook.com/me/feed"];
SLRequest *feedRequest = [SLRequest
requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodPOST
URL:feedURL
parameters:parameters];
acct.accountType = facebookAccountType;
// Post the request
[feedRequest setAccount:acct];
// Block handler to manage the response
[feedRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if (granted && error == nil) {
} else {
NSLog(#"Facebook response, HTTP response: %i %#", [urlResponse statusCode], [error description]);
[self closeShareMenu];
}
}];
}
}
I don't know where I'm going wrong! It's so annoying! I've set up my app correctly in Facebook Developers and all! Please help -_-'
Following up to the chat session held between #fguchelaar and yours truly yesterday; I was able to ascertain the following solution for this issue.
Add the following in your iOS completion handler:
NSString *temp = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];
NSLog(temp);
//'data' is your 'responseData' (or another object name) that you declare in your completion handler.
This will allow you to see the exact cause of the issue printed to the Debug Console. Now depending on the issue presented, you'll need to grab a Facebook account from the Array of Accounts generated when you call this handler in the iPhone SDK. Not at any prior stage whatsoever, as the Access Token will likely expire and give you this '400' error.
In my case; the error printed was: error:{'400' A valid access token is required… which vastly annoyed me as my prior method to access and check the current Twitter account was working perfectly. And my theory was that it should work just as well for Facebook. Why should the access token be instantaneously revoked if I'm grabbing the account a split second before?
The way I solved my issue (depending on the reason for your error the answer can vary) was to use a for loop to check the newly created array of accounts, with the sole purpose of finding the account there with the same identifier string as the one I saved into NSData/NSKeyedArchiver.
for(ACAccount *a in arrayOfAccounts) {
if([a.identifier isEqualToString:storedAccount.identifier]) {
//set the account to be used
accountToBeUsed = a;
//don't forget to break the For loop once you have your result.
break;
} else {
//This else{} block is not strictly necessary, but here you could set an account if no account was found with a matching identifier.
}
}
For it to work, it's recommended to declare an ACAccount object in your View Controller's .h file, add a #property and #synthesize it, so it can be assigned within the for loop and used after the break; statement.
This effectively solved my whole issue with the '400' error. It was inexplicably frustrating for about six hours of my day, so I hope that my explanation helps anybody who happens to stumble across this issue, and my question here on Stack Overflow :)
Regards,
cocotutch

GTM OAuth2 retrieving access_token via Keychain not successful

I'm following Google's examples on how to authorize an app to access one or more APIs.
The problem is that when i authorise successfully i get the access_token, but after this i can't get it from the keychain it is stored into. I read somewhere that iPhone Simulator doesn't work with Keychain, is it because of that, and if it is can you tell me some other way to store my access token?
Here is my code:
static NSString *const kKeychainItemName = #"OAuthGoogleReader";
GTMOAuth2Authentication *auth;
auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
clientID:kClientID
clientSecret:kClientSecret];
BOOL isSignedIn = [auth canAuthorize];
if (isSignedIn) {
NSLog(#"Signed");
self.window.rootViewController = self.viewController;
auth.accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:#"accessToken"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.google.com/reader/api/0/subscription/list?access_token=%#", [auth accessToken]]]];
GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher fetcherWithRequest:request];
// optional upload body data
//[myFetcher setPostData:[postString dataUsingEncoding:NSUTF8StringEncoding]];
[myFetcher setAuthorizer:auth];
[myFetcher beginFetchWithDelegate:self
didFinishSelector:#selector(myFetcher:finishedWithData:error:)];
// - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)retrievedData error:(NSError *)error;
}else{
NSString *scope = #"https://www.google.com/reader/api/";
GTMOAuth2ViewControllerTouch *viewController;
viewController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:scope
clientID:kClientID
clientSecret:kClientSecret
keychainItemName:kKeychainItemName
delegate:self
finishedSelector:#selector(viewController:finishedWithAuth:error:)];
self.window.rootViewController = viewController;
}
I get error:
2012-08-22 16:54:47.253 greader[20833:c07] Signed
2012-08-22 16:54:47.705 greader[20833:c07] Cannot authorize request with scheme http (<NSMutableURLRequest http://www.google.com/reader/api/0/subscription/list?access_token=(null)>)
as you can see access_token is just nil.
Also some simple examples on how to use this library would be great.
Thank you!
The gtm-oauth2 library handles storing and retrieving the access token and other auth values on the keychain. The app should not need to use the access token string directly, nor should the app put the authorization tokens into NSUserDefaults, as that is insufficiently secure.
gtm-auth2 also by default will refuse to attach an access token to a URL with an http: scheme. OAuth 2 is secure only when used with https: scheme URLs.

Self login in Salesforce API in iPhone?

I am using Salesforce api and i want to login automatically(hard code user name and password). i am using REST API and here is the login code which shows login form:
- (void)login {
SFOAuthCredentials *credentials = [[[SFOAuthCredentials alloc] initWithIdentifier:remoteAccessConsumerKey] autorelease];
credentials.protocol = #"https";
credentials.domain = OAuthLoginDomain;
credentials.redirectUri = OAuthRedirectURI;
self.coordinator = [[[SFOAuthCoordinator alloc] initWithCredentials:credentials] autorelease];
self.coordinator.delegate = self;
NSLog(#"%#",self.coordinator);
// remove this line if we want to cache the key, and use refresh flow
//effectively, we are saying, purge the old login and re-authenticate each time
[self.coordinator revokeAuthentication];
//now let's authenticate
[self.coordinator authenticate];
}
What i want, to automatically login (not ask username or password) so where i insert user name and password?
The Salesforce toolkit for iOS page shows an example of it using ZKSForce which returns a token that can be used by the REST API calls, see the document here
The REST API typically uses an OAuth token which saves the user from having to enter their username and password into a third party system such as yours. They enter the login once and the system refreshes the token to stay logged in (this is an oversimplified explanation). Either use OAuth which is the correct way with mobile and the REST API or use the session ID from an old style SOAP login request.
A quick Google and I found this - https://github.com/superfell/zkSforce
Haven't tried it yet though!
Include zkforce in your project
Add These files in your project
#import "ZKSforce.h"
#import "FDCServerSwitchboard.h"
#import "ZKLoginResult.h"
Add this code in .m
NSString *username =
NSString *password =
NSString *token = #"amnwcg24Uu5IenCvAJM5HgRq";
NSString *passwordToken = [NSString stringWithFormat:#"%#%#", password, token];
[[FDCServerSwitchboard switchboard] loginWithUsername:username password:passwordToken target:self selector:#selector(loginResult:error:)];
See result
- (void)loginResult:(ZKLoginResult *)result error:(NSError *)error
{
if (result && !error)
{
NSLog(#"Hey, we logged in!");
//[self fetchAccounts];
}
else if (error)
{
NSLog(#"An error occurred while trying to login.");
}
}