iOS linkedin authentication

10,361

Solution 1

Integrating LinkedIn Login in a Swift application

First, download the LinkedIn iOS SDK. I'll be using the 1.07 stable version for this example. I'll be following the integration guide here.

  1. Create a new Developer Application.
  2. Add your iOS app's Bundle Identifier to your LinkedIn App under Mobile.
  3. Add your LinkedIn app Id and URL Scheme to your app's Info.plist file.
  4. Whitelist the specified LinkedIn URL schemes and ATS URLs.
  5. Copy the linkedin-sdk.framework library to your application. Make sure "copy files if necessary" and "create groups for folder references" are selected.

Project setup complete, now let's write some code!

Create a new Header file called BridgingHeader.h. Under Targets -> YourApp -> Build Settings -> Swift Compiler - Code Generation, add MyApp/BridgingHeader.h to "Objective-C Bridging Header."

In your BridgingHeader.h, add these two lines:

#import <Foundation/Foundation.h>
#import <linkedin-sdk/LISDK.h>

In your AppDelegate.swift, add this code to handle the OAuth URL callback:

Swift 3:

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    if LISDKCallbackHandler.shouldHandle(url) {
        return LISDKCallbackHandler.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
    }
    return true
}

Swift 2.x:

func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    if LISDKCallbackHandler.shouldHandleUrl(url) {
        return LISDKCallbackHandler.application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
    }
    return true
}

Now it's time to log in the user. In your view controller, say you have a "Login" button. Your IBAction might look like this:

@IBAction func doLogin(sender: AnyObject) {
    LISDKSessionManager.createSessionWithAuth([LISDK_BASIC_PROFILE_PERMISSION], state: nil, showGoToAppStoreDialog: true, successBlock: { (returnState) -> Void in
        print("success called!")
        let session = LISDKSessionManager.sharedInstance().session
        }) { (error) -> Void in
            print("Error: \(error)")
    }
}

When logging in, the user will be asked to authenticate with your application:

LinkedIn

If the user allows, the success block will be called, and you can get information about the authenticated user. If the login fails or the user does not allow access, then the failure block will be called, and you can alert the user on the issue that occurred.

To get information about the user we authenticated with, call a GET request on the user's profile:

let url = "https://api.linkedin.com/v1/people/~"

if LISDKSessionManager.hasValidSession() {
    LISDKAPIHelper.sharedInstance().getRequest(url, success: { (response) -> Void in
        print(response)
        }, error: { (error) -> Void in
            print(error)
    })
}

The response.data will contain information on the authenticated user:

"{\n  \"firstName\": \"Josh\",\n  \"headline\": \"Senior Mobile Engineer at A+E Networks\",\n  ... }"

Read the docs further for more things you can do with the API.

A sample project (with my App ID obfuscated) can be found here.

Solution 2

LinkedIn is an interesting beast, since their mobile SDKs have two flaws:

  • An end user NEEDS the LinkedIn app to be installed, otherwise the "login" button will redirect the user to the App Store.
  • The mobile access token cannot be used on the server. See this screenshot from LinkedIn's iOS documentation

So while JAL's answer is sufficient, you may want to look into implementing LinkedIn's authorization_code OAuth flow in your mobile app instead of the LinkedIn SDK. This would look roughly like the following flow:

  1. The app will redirect the user to your webserver.
  2. The webserver begins the LinkedIn authentication flow, and redirects the user to LinkedIn.
  3. The user logs into LinkedIn, and gets redirected back to your webserver.
  4. The webserver reads the response, and exchanges the Authorization Code with LinkedIn for an access token.
  5. The webserver redirects your user back to the app, using a custom url scheme to send it the LinkedIn access token.
  6. The app uses the LinkedIn access token to login to Stormpath.

Sound complicated? It's actually more straightforward than it seems. I actually wrote some demo code for this flow using Express.js & Swift. This example ultimately sends the access token to Stormpath to ultimately authenticate the user, but you can always replace it with your own code that calls the LinkedIn REST API to grab the profile's information.

Solution 3

In Swift 3.0, UIApplicationOpenURLOptionsKey should be add for Facebook and LinkedIn.

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {

    if  LISDKCallbackHandler.shouldHandle(url)
    {
        return LISDKCallbackHandler.application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: nil)
    }
    else
    {
        return FBSDKApplicationDelegate.sharedInstance().application(app, open: url
            , options: options)
    }
}

Solution 4

I know this has already been answered but I faced this issue as well and had done everything set in the Accepted answer, but for whatever reason the code still was not hitting success or failure. It turned out that with iOS 9 the following is deprecated.

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

The solution was to use this instead :

- (BOOL)application:(UIApplication *)app
        openURL:(NSURL *)url
        options:(NSDictionary<NSString *,
                         id> *)options

For example, you could do:

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
if ([LISDKCallbackHandler shouldHandleUrl:url]) {
    return [LISDKCallbackHandler application:app openURL:url sourceApplication:options[UIApplicationLaunchOptionsSourceApplicationKey] annotation:options[UIApplicationLaunchOptionsAnnotationKey]];
}
return YES;
}
Share:
10,361
NielsPijpers
Author by

NielsPijpers

Updated on July 28, 2022

Comments

  • NielsPijpers
    NielsPijpers over 1 year

    I started developing an app for iOS in Swift. Now I am at the part where I need to create a login system. However we need the LinkedIn information from people.

    How can I use the OAuth2 API in iOS to achieve this?

    I already created an app in the LinkedIn developers area, but now I am stuck. I got some advice from someone that I need to use the UIWebView but I have no clue how this works.

  • ibrahimyilmaz
    ibrahimyilmaz almost 8 years
    I perform this steps and when i clicked my loginWithLinkedIn button LinkedIn app slides from right to left and then (1 seconds later) my app slides from right to left back and nothing happened. Success or error not called. After this; i tried get request to hasValidSession and again success not called nor error. Any suggestion?
  • MattBlack
    MattBlack over 7 years
    Same issue here, did you find a resolution?
  • Francesco D.M.
    Francesco D.M. about 7 years
    I had the same problem. I edited the method that goes in the AppDelegate to solve it. The signature was slightly different (they probably updated it) and it was never called when returning to my app. Now it works for me
  • Exploring
    Exploring almost 7 years
    For me, when it moves to linkedin app in log it shows "appid = null". But I've added the appid in plist as per the docs. And also I never get call back.
  • Abhishek Thapliyal
    Abhishek Thapliyal almost 7 years
    getting unresolved identifier error in app delegate you haven't tell how to import SDK
  • JAL
    JAL almost 7 years
    @AbhishekThapliyal I have, see the part of my answer about the bridging header.
  • Abhishek Thapliyal
    Abhishek Thapliyal almost 7 years
    @JAL: one last help , can you tell me how to fetch my recent activities and feeds in via linkedin SDK ??
  • JAL
    JAL almost 7 years
    @AbhishekThapliyal You should ask a new question.
  • Alan
    Alan over 6 years
    @FrancescoD.M. could you elaborate on what you did to fix it? I have the same issue and can't seem to figure it out.
  • Francesco D.M.
    Francesco D.M. over 6 years
    @AlanS I basically just had to copy-paste the part of the answer above for swift 3...if I recall correctly I had a very similar method but it would never be called...I was probably using the method for an older swift version