Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yahoo authenticate & fetch profile details iOS

I've listed here Yahoo Integration steps which I've followed.

  • Step 1. I went to http://developer.yahoo.com/social/sdk/objectivec/
  • Step 2. Downloaded entire framework from here - http://github.com/yahoo/yos-social-objc
  • Step 3. I did Drag & drop that framework into my project.
  • Step 4. Enabled flag fno-objc-arc for yahoo framework files.
  • Step 5. I did #import "YOSSocial.h" in my viewController's header file.
  • Step 6. In view did load, I placed Code block 1 to create a session object.
  • Step 7. On a button click, I invoke, Code block 2.
  • Step 8. In AppDelegate.m, I've implemented method as Code block 3.
  • Step 9. I receive oauth_token & oauth_verifier in redirection.

Code block 1

 - (void)viewDidLoad {
    [super viewDidLoad];
    self.session = [YOSSession sessionWithConsumerKey:@"ConsumerKeyHere"
                                           andConsumerSecret:@"ConsumerSecretKeyHere"
                                            andApplicationId:@"AppKey"];
    BOOL hasSession = [self.session resumeSession];
    if(hasSession == FALSE) {
        // custom call back URL which will redirect to our-app.
        // 10.0.0.76/iOS/callback.php redirects 
        // to com.mymobileapps.currentApp.yahoo
        [self.session 
           sendUserToAuthorizationWithCallbackUrl:
           @"http://10.0.0.76/iOS/callback.php"];
    } else {
        [self sendRequests];
    }
}

Code block 2

- (void)sendRequests {
    // initialize a user request for the logged-in user
    YOSUserRequest *request = [YOSUserRequest requestWithSession:self.session];

    // fetch the user's profile data
    [request fetchProfileWithDelegate:self];
}

- (void)requestDidFinishLoading:(YOSResponseData *)data {
    // parse the response text string into a dictionary
    NSDictionary *rspData = [NSJSONSerialization JSONObjectWithData:[data.responseText dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
    NSDictionary *profileData = [rspData objectForKey:@"profile"];

    // format a string using the nickname object from the profile.
    NSString *welcomeText = [NSString stringWithFormat:@"Hey %@ %@!",
                             [profileData objectForKey:@"givenName"],
                             [profileData objectForKey:@"familyName"]];
    NSLog(@"welcometext is %@",welcomeText);
    self.lblProfile.text = welcomeText;
}

Code block 3

- (BOOL)application: (UIApplication *)application
            openURL: (NSURL *)url
  sourceApplication: (NSString *)sourceApplication
         annotation: (id)annotation {
    NSString *str = [[url description] stringByReplacingOccurrencesOfString:@"com.mymobileapps.currentApp.yahoo://oauth-response?oauth_token=" withString:@""];
    NSArray *ar = [str componentsSeparatedByString:@"&oauth_verifier="];
    NSLog(@"oauth_token is %@",[ar objectAtIndex:0]);
    NSLog(@"oauth_verifier is %@",[ar objectAtIndex:1]);
    // How my session will get updated now with valid authentication done?
    return YES;
}

I followed each & every step as described here - http://developer.yahoo.com/social/sdk/objectivec/ & I also implemented redirection as described here - How to redirect from Yahoo to my IOS app after authentication?

QUESTION is as follows. I am still not able to fetch user-profile details like gender, date of birth etc. That is - From Code block 2, I receive data as nil.

What is missing in my code to retrieve data of user-profile?

Other reference.

- (BOOL)application: (UIApplication *)application
            openURL: (NSURL *)url
  sourceApplication: (NSString *)sourceApplication
         annotation: (id)annotation {
    return [GPPURLHandler handleURL:url
                  sourceApplication:sourceApplication
                         annotation:annotation];
}

Above code illustrates How Google+ framework handles redirection & manages with local session. In case of Yahoo, I don't find any details which is helpful to update local-session of mobile app.

Edit:
If it is not possible through Yahoo OAuth, How is it possible to fetch basic profile details (like - gender, date of birth, email ID, name etc.) from Yahoo?

like image 782
Sagar Kothari Avatar asked Jan 03 '14 10:01

Sagar Kothari


2 Answers

Here is the solution.

NOTE: You would be needing an intermediate server for that.

  • Step 01. Download PHP yahoo framework http://github.com/yahoo/yos-social-php
  • Step 02. Start WAMP/XAMPP server.
  • Step 03. Obtain URL
    • example - http://10.0.0.76/iOS/yos-social-php-master/sample/sampleapp.php
  • Step 04. Get back to XCode project.
  • Step 05. Open XIB, Put a button for Yahoo & connect IBAction method.
  • Step 06. In IBAction method, navigate to obtained URL from iOS App to URL. See Code Block 1
  • Step 07. Add method in AppDelegate.m for handling redirection from Server to your mobile App. See Code Block 2
  • Step 08. Make sure your app is capable handling Redirection. Open your project-info.plist as source-code & make sure you have valid URL types, URL identifier & URL Schemes. as indicated in Code Block 3
  • Step 09. Now your mobile app is ready for redirection from server.
  • Step 10. Open yourLocalServer/iOS/yos-social-php-master/sample/sampleapp.php file. (https://github.com/yahoo/yos-social-php/blob/master/sample/sampleapp.php)
  • Step 11. Comment code from 97 to 106.
  • Step 12. Put code as indicated in Code Block 4
  • Step 13. Run your project, Click on button from iOS App.
  • Step 14. App will navigate to your site-page. Site page will do the authentication & get the profile details.
  • Step 15. As soon as authentication is done, site-page will redirect back to your-mobile-app with details like - Gender, Full name, date of birth, guid, profile picture url etc.

Summary

Mobile App navigates to Server -> Server manages authentication via OAuth-php. Once authenticated Server retrieves profile details & server indicates safari to navigate back to - your-mobile-App. Your-mobile-app gets all details in Code Block

Code Block 1

- (IBAction)connectYahoo:(id)sender {
      [[UIApplication sharedApplication] 
           openURL:[NSURL URLWithString:
           @"http://yourLocalServer/iOS/yos-social-php-master/sample/sampleapp.php"
      ]];
}

Code Block 2

- (BOOL)application:(UIApplication *)application
        openURL:(NSURL *)url
   sourceApplication:(NSString *)sourceApplication
     annotation:(id)annotation {

    if([[url scheme] isEqualToString:@"com.yourcompany.app.fsq"]) {
        return [self.obj_LoginHomeVCtr.foursquare handleOpenURL:url];
    } else if([[url scheme] isEqualToString:@"com.yourcompany.app.googleplus"]){
        return [GPPURLHandler handleURL:url
                  sourceApplication:sourceApplication
                         annotation:annotation];

    }else if([[url scheme] isEqualToString:@"fb188315544652080"]){
        return [FBAppCall handleOpenURL:url
                  sourceApplication:sourceApplication
                    fallbackHandler:^(FBAppCall *call) {
                        NSLog(@"In fallback handler");
                    }];
    } else if ([[url scheme] isEqualToString:@"com.yourcompany.app.yahoo"]){
        STLog(@"URL is %@",url);
        return YES;
    }
    return YES;
}

Code block 3

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>com.yourcompany.app.yahoo</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>com.yourcompany.app.yahoo</string>
        </array>
    </dict>
</array>

Code block 4

  else if($hasSession && $profile) {
      $string = "com.yourcompany.app.yahoo://response?birthdate=" . $profile->birthdate . "&familyName=" . $profile->familyName. " " . $profile->givenName . "&gender=" . $profile->gender . "&guid=" . $profile->guid . "&image=" . $profile->image->imageUrl;
      echo '<meta http-equiv="Refresh" content="1;URL='. $string .'">';
  }
?>
like image 51
Sagar Kothari Avatar answered Oct 21 '22 16:10

Sagar Kothari


fetchProfileWithDelegate: (source here) builds a URL and sets some header info, then passes this data to [YOSRequestClient -sendAsyncRequestWithDelegate:] (source here).

The request client then creates a NSMutableURLRequest and NSURLConnection and starts a connection.

Once the data is downloaded (if any) YOSResponseData takes over and creates a new object from the downloaded data (source code here).

There is no code path I can see that would allow the serviceResponseData object passed in to be nil. You should at least be able to see [data didSucceed], which will tell you if the HTTP response was < 400. Oddly enough, if the server just opens and closes the connection with no HTTP response, I believe [data didSucceed] == YES even though it obviously didn't succeed (since 0 < 400).

It doesn't look like you're doing anything wrong. My guess is that since the last commit was 4 years ago, and the company has gone through significant restructuring since then, the project has been abandoned and nobody has bothered making a note of it.

Update: In addition to having no updates for 4 years, Yahoo's developer forum for this software has been closed. I don't think Yahoo's API for this software is working any more. –

like image 44
Aaron Brager Avatar answered Oct 21 '22 16:10

Aaron Brager