Getting Email Address from LinkedIn API - ios

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);
}];
}

Related

not getting email id with linkedin swift [duplicate]

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);
}];
}

Sharing a image URL and text in LinkedIn integration using sdk

In LinkedIn sharing,LinkedIn provide a SDK but using this SDK,I can't share image link and text it always shows
LISDKErrorAPIDomain Code=403 The operation couldn’t be completed. (LISDKErrorAPIDomain error 403.)
Code:
NSString *url = #"https://api.linkedin.com/v1/people/~/shares";
NSString *payload = #"{\"comment\":\"Check out developer.linkedin.com! http://linkd.in/1FC2PyG\",\"visibility\":{ \"code\":\"anyone\" }}";
if ([LISDKSessionManager hasValidSession])
{
[[LISDKAPIHelper sharedInstance] postRequest:url stringBody:payload
success:^(LISDKAPIResponse *response) {
// do something with response
NSLog(#"response : %#",response.data);
}
error:^(LISDKAPIError *apiError) {
// do something with error
NSLog(#"error: %#",apiError);
}];
}
Sharing on LinkedIn Error : LISDKErrorAPIDomain Code=403 The operation couldn’t be completed.
if you are repeating same static text to post on LinkedIn, it might be a change to getting same error.
you must get share permission before add post
NSArray *permissions = [NSArray arrayWithObjects:LISDK_BASIC_PROFILE_PERMISSION,LISDK_W_SHARE_PERMISSION, nil];
full login code
NSArray *permissions = [NSArray arrayWithObjects:LISDK_BASIC_PROFILE_PERMISSION,LISDK_W_SHARE_PERMISSION, nil];
[LISDKSessionManager createSessionWithAuth:permissions state:nil showGoToAppStoreDialog:YES successBlock:^(NSString *returnState){
NSLog(#"%s","success called!");
LISDKSession *session = [[LISDKSessionManager sharedInstance] session];
NSLog(#"Session : %#", session.description);
[[LISDKAPIHelper sharedInstance] getRequest:#"https://api.linkedin.com/v1/people/~"
success:^(LISDKAPIResponse *response) {
NSData* data = [response.data dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dictResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSString *authUsername = [NSString stringWithFormat: #"%# %#", [dictResponse valueForKey: #"firstName"], [dictResponse valueForKey: #"lastName"]];
NSLog(#"Authenticated user name : %#", authUsername);
} error:^(LISDKAPIError *apiError) {
NSLog(#"Error : %#", apiError);
}];
} errorBlock:^(NSError *error) {
NSLog(#"Error called : %#", error);
}];

Setting the username to Facebook name with Parse API.

Currently here is my code in my LogInViewController that contains the handler for Facebook signup process and code that I was hoping would setup the username and email address to their Facebook Name and Email address.
- (IBAction)fbButtonPressed:(id)sender
{
NSArray *permissions =#[#"public_profile", #"email", #"user_friends"];
[PFFacebookUtils logInWithPermissions:permissions block:^(PFUser *user, NSError *error) {
if (!user) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Log In Error" message:#"Uh oh. The user cancelled the Facebook login." delegate:nil cancelButtonTitle:nil otherButtonTitles:#"Dismiss", nil];
[alert show];
} else if (user.isNew) {
NSLog(#"User signed up and logged in through Facebook!");
FBRequest *request = [FBRequest requestForMe];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error){
NSDictionary *userData = (NSDictionary *)result;
NSString *facebookID= userData[#"ID"];
NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=large&return_ssl_resources=1", facebookID]];
NSMutableDictionary *userProfile = [NSMutableDictionary dictionaryWithCapacity:7];
if (facebookID){
userProfile[#"facebookID"] = facebookID;
}
if (userData[#"name"]) {
user.username = userProfile[#"name"];
}
if (userData[#"email"]){
user.email = userData[#"emai"];
}
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error){
NSLog(#"ERROR: %# %#", error, [error userInfo]);
}else{
[self.navigationController popToRootViewControllerAnimated:YES];
}
}];
}
}];
} else {
NSLog(#"User logged in through Facebook!");
[self.navigationController popToRootViewControllerAnimated:YES];
}
}];
}
You have a typo in
user.email = userData[#"emai"];
Also, for the name, you try getting the name from userProfile:
if (userData[#"name"]) {
user.username = userProfile[#"name"];
}
which should be
if (userData[#"name"]) {
user.username = userData[#"name"];
}
Try this.
PFUser *user = [PFUser currentUser];
FBRequest *request = [FBRequest requestForMe];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
NSLog(#"test");
if(!error) {
NSDictionary *userData = (NSDictionary *)result;
NSString *name = userData[#"name"];
user.username = name;
NSLog(#"user:%#", name);
[user saveEventually];
} else {
NSLog(#"An error occurred: %#", error.localizedDescription);
}
}];

shouldPerformSegueWithIdentifier issue

I tried too much to solve my bellow issue but i am failed.Please help me to solve this issue. I have login view and after validating id and password i am pushing it to next view controller.Please check bellow image.
Issue - When Id and Password is correct it's pushing to next view controller but after 2 clicks on login button.
Code -
ServiceManager.m
-(void)initGetAppServiceRequestWithUrl:(NSString *)baseUrl onCompletion:
(ServiceCompletionHandler)handler
{
NSString *fullUrl = [NSString stringWithFormat:#"%#",[baseUrl
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL
URLWithString:fullUrl]];
[NSURLConnection sendAsynchronousRequest:(NSURLRequest *)request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,NSData *data,NSError *error)
{
if (error) {
handler(nil,error);
// NSLog(#"error = %#",error);
}
else
{ handler(data, nil);
// NSLog(#"data = %#",data);
}
}];
}
JSONResponseHandler.m
+(void)handleResponseData:(NSData *)responseData onCompletion:(JSONHandler)handler
{
if (responseData) {
NSError *jsonParseError;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions error:&jsonParseError];
if (!json) {
handler(nil , jsonParseError);
}
else
{
handler (json , nil);
}
}
}
ASKevrServiceManager.m
-(void)login:(Login *)login completionHandler:(ServiceCompletionHandler)handler
{
NSString *loginUrl = [NSString
stringWithFormat:#"http://249development.us/johnsan/askever/login.php?
login=%#&password=%#",login.emailAddr , login.password];
[self initGetAppServiceRequestWithUrl:loginUrl onCompletion:^(id object, NSError
*error)
{
handler(object , error);
}
];
}
ASKevrOperationManager.m
+(void)login:(Login *)login handler:(OperationHandler)handler
{
ASKevrServiceManager *serviceManager = [[ASKevrServiceManager alloc]init];
[serviceManager login:login completionHandler:^(id object, NSError *error)
{
[JSONResponseHandler handleResponseData:object onCompletion:^(NSDictionary
*json , NSError *jsonError)
{
if(json)
{
handler(json , nil , YES);
}
else
{
handler(nil , jsonError , NO);
}
}];
}];
}
LoginViewController.m
-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if ([identifier isEqualToString:#"pushTab"])
{
if ([emailTxt.text isEqualToString:#""] || [passwordTxt.text
isEqualToString:#""])
{
[self showAlertWithMessage:#"Please write your id or password"];
return NO;
}
else
{
Login *loginModel = [[Login alloc]init];
loginModel.emailAddr =emailTxt.text;
loginModel.password = passwordTxt.text;
[ASKevrOperationManager login:loginModel handler:^(id object , NSError *error ,
BOOL success)
{
if (success)
{
NSLog(#"object =%#",object);
NSDictionary *arr = [object objectForKey:#"response"];
str = [arr objectForKey:#"flag"];
//check for error
NSDictionary *toDict = [object objectForKey:#"response"];
currentUserId = [toDict objectForKey:#"c_id"];
NSLog(#"currentUserId = %#",currentUserId);
}
else
{
[self showAlertWithMessage:#"Wrong Id or Password."];
}
}];
NSLog(#"str = %#",str);
if ([str isEqualToString:#"1"])
{
// [self showAlertWithMessage:#"Wrong Id or Password."];
return YES;
}
}
}
return NO;
}
When pressing login button do run the code
if (![emailTxt.text isEqualToString:#""] &&
![passwordTxt.text isEqualToString:#""]){
Login *loginModel = [[Login alloc]init];
loginModel.emailAddr =emailTxt.text;
loginModel.password = passwordTxt.text;
[ASKevrOperationManager login:loginModel handler:^(id object , NSError *error ,
BOOL success)
{
if (success){
NSLog(#"object =%#",object);
NSDictionary *arr = [object objectForKey:#"response"];
str = [arr objectForKey:#"flag"];
//check for error
NSDictionary *toDict = [object objectForKey:#"response"];
currentUserId = [toDict objectForKey:#"c_id"];
NSLog(#"currentUserId = %#",currentUserId);
//perform the segue only when succesful
[self performSegueWithIdentifier:#"yourSegue" sender:sender];
}else{
[self showAlertWithMessage:#"Wrong Id or Password."];
}
}];
}else {
[self showAlertWithMessage:#"Please write your id or password"];
}
Keep your shouldPerformSegueWithIdentifier simple
-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if ([identifier isEqualToString:#"pushTab"])
{
//don't put logic here
//put code here only if you need to pass data
//to the next screen
return YES:
}
return NO;
}

AFNetworking retry timeout requests using enqueueBatchOfHTTPRequestOperations

There are few similar questions to mine with answers,but could not find a way to use that solutions on my code. I would be glad, if anyone can help me on code. How to retry timeout request?
while block for pagination purpose:
while(mult < (int)totalCount) {
AFHTTPRequestOperation *opr = [self getRequestForAllRecordsOfClass:className updatedAfterDate:mostRecentUpdatedDate withinPage:page+1];
[pagedOperations addObject:opr];
mult = mult + PAGINATION_SIZE;
page = page + 1;
}
[[SDAFParseAPIClient sharedClient] enqueueBatchOfHTTPRequestOperations:operations progressBlock:^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) {
NSLog(#"totalNumberOfOperations: %u numberOfCompletedOperations: %u",totalNumberOfOperations,numberOfCompletedOperations);
} completionBlock:^(NSArray *operations) {
...
}];
and building request operation
-(AFHTTPRequestOperation *)getRequestForAllRecordsOfClass:(NSString *)className updatedAfterDate:(NSDate *)mostRecentDate withinPage:(int)page {
NSMutableURLRequest *request = [ZurmoHelper GETRequestForAllRecordsOfClass:className updatedAfterDate:mostRecentDate inPage:page];
AFHTTPRequestOperation *operation = [[SDAFParseAPIClient sharedClient] HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"RESPONSE pagination!!! %#:", className);
NSError *error = nil; //error in parsing json
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
if (!error) {
NSLog(#"json dict paged in : %d",page );
id dataObject = [jsonDict objectForKey:#"data"];
NSArray *itemsObject = [dataObject objectForKey:#"items"];
[self addItems:itemsObject className:className];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Request for class %# failed with error: %#", className, error);
if (error.code == -1001) {
NSLog(#"for class %# page: %d,",className,page);
//need to retry this operation???
}
}];
return operation;
}

Resources