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 c
As @Edward Jiang already explained, LinkedIn turns the whole authentication process very clumsy due to the requirement of having the LinkedIn app installed. I wrote a Swift library that handles the authentication flux within an embeded WKWebView
: LinkedInAuth-Swift.
This library even eliminates the necessity of handling LinkedIn's response in a server. The WKWebView
instance which is presenting the authentication flux is in charge of capturing the authorization code returned by LinkedIn and subsequently requesting the access token.
LinkedIn is an interesting beast, since their mobile SDKs have two flaws:
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:
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.
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;
}
Update for Edward Jiang's answer; changes is token access on server + mobile side. Source: https://developer.linkedin.com/docs/ios-sdk-auth
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.
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:
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.
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)
}
}