I want to include a "Sign Up using LinkedIn" feature in my app.
I'd like to be able to get some information, such as name and email.
By default I am able to get a name, but I'm stuck on getting the email.
My results are in JSON.
Here's my code:
- (IBAction)logInWithLinkedIn:(id)sender
{
if ([_client validToken])
{
[self requestMeWithToken:[_client accessToken]];
}
else
{
[_client getAuthorizationCode:^(NSString *code)
{
[self.client getAccessToken:code success:^(NSDictionary *accessTokenData) {
NSString *accessToken = [accessTokenData objectForKey:#"access_token"];
[self requestMeWithToken:accessToken];
} failure:^(NSError *error) {
NSLog(#"Quering accessToken failed %#", error);
}];
} cancel:^{
NSLog(#"Authorization was cancelled by user");
} failure:^(NSError *error) {
NSLog(#"Authorization failed %#", error);
}];
}
}
- (void)requestMeWithToken:(NSString *)accessToken
{
[self.client GET:[NSString stringWithFormat:#"https://api.linkedin.com/v1/people/~?oauth2_access_token=%#&format=json", accessToken] parameters:nil success:^(AFHTTPRequestOperation *operation, NSDictionary *result) {
NSLog(#"current user %#", result);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failed to fetch current user %#", error);
}];
}
- (LIALinkedInHttpClient *)client
{
LIALinkedInApplication *application = [LIALinkedInApplication applicationWithRedirectURL:#"redirectURL"
clientId:#"key"
clientSecret:#"secret"
state:#"state"
grantedAccess:#[#"r_emailaddress"]];
return [LIALinkedInHttpClient clientForApplication:application presentingViewController:nil];
}
My result is:
firstName
headline
lastName
siteStandardProfileRequest
Anyone see how I can get the email?
You should use:
[self.client GET:[NSString stringWithFormat:#"https://api.linkedin.com/v1/people/~:(id,first-name,last-name,maiden-name,email-address)?oauth2_access_token=%#&format=json", accessToken] parameters:nil success:^(AFHTTPRequestOperation *operation, NSDictionary *result)
This may helps :)
You can use LinkedIn SDK
+ (void)loginToLinkedInAndFetchProfileData:(RequestResult)resultHandler
{
void (^PerformDataFetch)() = ^() {
if ([LISDKSessionManager hasValidSession]) {
NSString *urlString = [NSString stringWithFormat:#"%#/people/~:(id,first-name,last-name,maiden-name,email-address)", LINKEDIN_API_URL];
[[LISDKAPIHelper sharedInstance] getRequest:urlString success:^(LISDKAPIResponse *response) {
NSString *token = [[LISDKSessionManager sharedInstance].session.accessToken serializedString];
[[NSUserDefaults standardUserDefaults] setValue:token forKey:LinkedInAccessTokenKey];
[[NSUserDefaults standardUserDefaults] synchronize];
NSData *objectData = [response.data dataUsingEncoding:NSUTF8StringEncoding];
id value = [NSJSONSerialization JSONObjectWithData:objectData options:kNilOptions error:nil];
resultHandler(value, nil);
} error:^(LISDKAPIError *error) {
resultHandler(nil, error);
}];
}
};
NSString *token = [[NSUserDefaults standardUserDefaults] stringForKey:LinkedInAccessTokenKey];
if (token.length) {
LISDKAccessToken *accessToken = [LISDKAccessToken LISDKAccessTokenWithSerializedString:token];
if ([accessToken.expiration isLaterThan:[NSDate date]]) {
[LISDKSessionManager createSessionWithAccessToken:accessToken];
PerformDataFetch();
}
} else {
[LISDKSessionManager createSessionWithAuth:[NSArray arrayWithObjects:LISDK_BASIC_PROFILE_PERMISSION, LISDK_EMAILADDRESS_PERMISSION, nil] state:nil showGoToAppStoreDialog:YES successBlock:^(NSString *returnState) {
PerformDataFetch();
} errorBlock:^(NSError *error) {
resultHandler(nil, error);
}];
}
}
Response
> {
> emailAddress = "someEmail#email.com";
> firstName = Name;
> id = "2342d-6Y";
> lastName = LastName;
> }
Also this link can be useful
Update for Swift 3:
// Set preferred scope.
let scope = "r_basicprofile%20r_emailaddress"
// Then
if let accessToken = UserDefaults.standard.object(forKey: "LIAccessToken") {
// Specify the URL string that we'll get the profile info from.
let targetURLString = "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,maiden-name,email-address)?format=json"
-(void)syncLinkedInWithCompetionHandler:(CompletionBlock)block{
[LISDKSessionManager createSessionWithAuth:[NSArray arrayWithObjects:LISDK_BASIC_PROFILE_PERMISSION, LISDK_EMAILADDRESS_PERMISSION, nil]
state:#"some state"
showGoToAppStoreDialog:YES
successBlock:^(NSString *returnState) {
NSLog(#"%s","success called!");
LISDKSession *session = [[LISDKSessionManager sharedInstance] session];
NSLog(#"value=%# \nisvalid=%#",[session value],[session isValid] ? #"YES" : #"NO");
block(returnState, nil);
}
errorBlock:^(NSError *error) {
NSLog(#"%s %#","error called! ", [error description]);
block(nil, error);
}
];
}
-(void)getProfileDataWithCompletion:(CompletionBlock)block {
NSString *urlString = [NSString stringWithFormat:#"%#/people/~:(id,first-name,last-name,headline,location,email-address)", LINKEDIN_API_URL];
NSLog(#"urlString = %#",urlString);
[[LISDKAPIHelper sharedInstance] getRequest:urlString success:^(LISDKAPIResponse *response) {
NSError *jsonError;
NSData *objectData = [response.data dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
NSLog(#"responseDict = %#",responseDict);
block(responseDict, nil);
} error:^(LISDKAPIError *error) {
NSLog(#"error = %#",error);
block(error, nil);
}];
}
I am having a very hard time here. There is one part in my application that STTwitter is successful and there is another part (using the same code) that does not return anything.
The part that does NOT work: `
-(IBAction)followTwitter:(id)sender {
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"twitter_on_file" ] == nil) {
UIAlertView *allert = [[UIAlertView alloc] initWithTitle:#"Uh oh!" message:#"You have not linked your twitter account quite yet! Head to My Account settins to do so." delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil, nil];
[allert show];
} else {
ACAccountStore *store1 = [[ACAccountStore alloc] init];
ACAccountType *twitterAccountType = [store1 accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
if ([twitterAccountType accessGranted]) {
[store1 requestAccessToAccountsWithType:twitterAccountType options:nil completion:^(BOOL granted, NSError *error) {
arrayOfUsernames = [[NSMutableArray alloc] init];
iosAccounts = [store1 accountsWithAccountType:twitterAccountType];
for (ACAccount *accou in iosAccounts) {
[arrayOfUsernames addObject:accou.username];
}
NSString *usernameOnFile = [[NSUserDefaults standardUserDefaults] objectForKey:#"twitter_on_file" ];
int tracker = 0;
for (NSString *username in arrayOfUsernames) {
if ([username isEqualToString:usernameOnFile]) {
NSLog(#"Using twitter account: %#", username);
STTwitterAPI *twitterAPI = [STTwitterAPI twitterAPIOSWithAccount:iosAccounts[tracker]];
[twitterAPI verifyCredentialsWithSuccessBlock:^(NSString *username) {
NSLog(#"Successfully authenticated the user");
} errorBlock:^(NSError *error) {
NSLog(#"Erorr: %#", error);
}];
NSLog(#"Twitter API: %#", twitterAPI);
[twitterAPI postFriendshipsCreateForScreenName:#"kickscaterer" orUserID:nil successBlock:^(NSDictionary *befriendedUser) {
NSLog(#"Befriend %#", befriendedUser);
} errorBlock:^(NSError *error) {
NSLog(#"Error: %#", error);
}];
} else {
tracker++;
}
}
}];
}
}
}
`
The part that DOES work:
STTwitterAPI *twitter= [STTwitterAPI twitterAPIOSWithAccount:iosAccounts[indexForAlert.row]];
[twitter verifyCredentialsWithSuccessBlock:^(NSString *username) {
// ...
NSLog(#"Username: %#", username);
// [self.tableView reloadData];
[[NSUserDefaults standardUserDefaults] setObject:twitter.userName forKey:#"twitter_on_file"];
} errorBlock:^(NSError *error) {
NSLog(#"Error: %#", error);
// ...
}];
[twitter postFriendshipsCreateForScreenName:#"didi4" orUserID:nil successBlock:^(NSDictionary *befriendedUser) {
NSLog(#"Befriend %#", befriendedUser);
} errorBlock:^(NSError *error) {
NSLog(#"Error: %#", error);
}];
Thanks!
The postFriendshipsCreateForScreenName: method should be called inside the success block, at the same level than the log "Successfully authenticated the user".
i am using sttwiter sdk for twitter login in phonegap.
This method note return -
- (void)setOAuthToken:(NSString *)token oauthVerifier:(NSString *)verifier
{
[_twitter postAccessTokenRequestWithPIN:verifier successBlock:^(NSString *oauthToken, NSString *oauthTokenSecret, NSString *userID, NSString *screenName)
{
NSLog(#"-- screenName: %#", screenName);
}
errorBlock:^(NSError *error)
{
// _loginStatusLabel.text = [error localizedDescription];
NSLog(#"-- %#", [error localizedDescription]);
}];
}
I have received my API key for the twitter API.
Currently my request looks like this
NSString *twitterURL = [NSString stringWithFormat:#"https://api.twitter.com/1.1/search/tweets.json?q=xyz&count=20"];
Now how do I build my request url with my API key?
You can use the STTwitter library.
STTwitterAPI *twitter = [STTwitterAPI twitterAPIWithOAuthConsumerKey:#""
consumerSecret:#""
oauthToken:#""
oauthTokenSecret:#""];
[twitter verifyCredentialsWithSuccessBlock:^(NSString *username) {
[_twitter getSearchTweetsWithQuery:#"xyz"
successBlock:^(NSDictionary *searchMetadata, NSArray *statuses) {
NSLog(#"-- statuses: %#", statuses);
} errorBlock:^(NSError *error) {
NSLog(#"-- error: %#", error);
}];
} errorBlock:^(NSError *error) {
NSLog(#"-- error: %#", error);
}];
I'm having trouble in posting a reply to a specific status ID
Here's my authentication code
twitterWithReply = [STTwitterAPI twitterAPIOSWithFirstAccount];
[twitterWithReply verifyCredentialsWithSuccessBlock:^(NSString *username) {
NSLog(#"Login Successful");
self.replyTextField.enabled = YES;
}
errorBlock:^(NSError *error){
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Sorry"
message:#"You can't send a tweet right now, make sure your device has an internet connection and you have at least one Twitter account setup"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}];
And here's my code for posting the reply
NSLog(#"the text content%#",self.replyTextField.text);
[self.replyTextField resignFirstResponder];
if (self.replyTextField.text.length>0 && self.replyTextField.text.length <=140) {
// Post reply
[twitterWithReply postStatusUpdate:self.replyTextField.text inReplyToStatusID:self.tweeetID latitude:nil longitude:nil placeID:nil displayCoordinates:nil trimUser:nil successBlock:^(NSDictionary *status) {
[self showSuccessDialog];
} errorBlock:^(NSError *error) {
NSLog(#"%#",[error localizedDescription]);
}];
}
Currently what it does is to post to my own timeline not in reply to a specific tweet. I'm under the impression that my authentication code is wrong. So how do I authenticate then?
I just checked this scenario with the development version of STTwitter and it works as expected.
If this code doesn't work for you, then please fill an issue with as much details as possible.
self.twitter = [STTwitterAPI twitterAPIOSWithFirstAccount];
[_twitter verifyCredentialsWithSuccessBlock:^(NSString *username) {
[_twitter postStatusUpdate:#"test1" inReplyToStatusID:nil latitude:nil longitude:nil placeID:nil displayCoordinates:nil trimUser:nil successBlock:^(NSDictionary *status) {
NSLog(#"-- status1: %#", status);
[_twitter postStatusUpdate:#"test2" inReplyToStatusID:[status valueForKey:#"id_str"] latitude:nil longitude:nil placeID:nil displayCoordinates:nil trimUser:nil successBlock:^(NSDictionary *status) {
NSLog(#"-- status2: %#", status);
} errorBlock:^(NSError *error) {
NSLog(#"-- error2: %#", error);
}];
} errorBlock:^(NSError *error) {
NSLog(#"-- error1: %#", error);
}];
} errorBlock:^(NSError *error) {
NSLog(#"-- error0: %#", error);
}];