# iOSアプリにLINEログインを組み込む

SDKをインストールしてプロジェクトを設定したら、LINEログインを使ったユーザーエクスペリエンスの向上に取りかかることができます。

# LineSDKフレームワークとチャネルIDを設定する

ログインアクションで生成される結果を処理するため、LINE SDK for iOS SwiftをAppDelegate.swiftファイルに設定します。

# 1. LineSDKフレームワークをインポートする

AppDelegate.swiftファイルの冒頭で、LineSDKフレームワークを以下のようにインポートします。

// AppDelegate.swift
import LineSDK

アプリ内の他のファイルでSDKを使用する場合は、各ファイルにLineSDKフレームワークをインポートしてください。

# 2. LoginManager.setupメソッドを呼び出す

アプリの起動直後に、以下のようにLoginManager.setupメソッドを呼び出します。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Add this to your "didFinishLaunching" delegate method.
    LoginManager.shared.setup(channelID: "YOUR_CHANNEL_ID", universalLinkURL: nil)
    
    return true
}
注意

LINE SDK for iOS Swiftの他のプロパティにアクセスしたり、他のメソッドを呼び出したりする前にsetupメソッドを呼び出してください。

# ユニバーサルリンクを使用する

LINE Developersコンソールでユニバーサルリンクを設定した場合は、universalLinkURLパラメータを指定してsetupメソッドを呼び出します。LINEによりユニバーサルリンクを使ってアプリが起動されるため、ログイン処理のセキュリティが高まります。

ユニバーサルリンクを使ったログイン処理の制御について詳しくは、「ユニバーサルリンクを利用する」を参照してください。

# 3. アプリの起動を制御する

LINEプラットフォームから返されたログイン結果を制御するには、取得したURLをLoginManagerapplication(_:open:options:)メソッドに渡します。プロジェクトがマルチウィンドウ(iOS13で導入された機能)をサポートするかどうかで、アプリデリゲートクラスまたはシーンデリゲートクラスを変更する必要があります。

# アプリデリゲートを変更する

iOS 12以前では、UIApplicationDelegateオブジェクトを呼び出して、URLを開きます。したがって、アプリデリゲートクラスのapplication(_:open:options:)デリゲートメソッドに、次の行を追加します。

// AppDelegate.swift
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    return LoginManager.shared.application(app, open: url)
}

# シーンデリゲートを変更する

iOS 13以降では、UISceneDelegateオブジェクトを呼び出して、URLを開きます。

Xcode 11以降でプロジェクトを作成した場合は、デフォルトでは、プロジェクトにはSceneDelegate.swiftファイルが含まれ、Info.plistファイルにはUIApplicationSceneManifestエントリーが含まれます。

プロジェクトがマルチウィンドウをサポートする場合は、使用するシーンデリゲートクラスに、次の行を追加します。

// SceneDelegate.swift
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    _ = LoginManager.shared.application(.shared, open: URLContexts.first?.url)
}
注意

プロジェクトがマルチウィンドウをサポートしていない場合は、UIApplicationDelegateオブジェクトを呼び出して、URLを開きます。アプリデリゲートクラスを変更してください。

# ログイン処理を実行する

ユーザーがiOSアプリにログインできるようにするために、LINEロゴがついたログインボタンを作成できます。ユーザーはこのボタンを使ってログインできます。

ログインを実行するには2つの方法があります。

# LINE SDKに組み込まれているログインボタンを使う

LINE SDK for iOS Swiftには定義済みのログインボタンが備わっています。SDKに含まれるLoginButtonクラスはUIButtonクラスのサブクラスで、「[LINEログインボタン デザインガイドライン][login-button]」で推奨されるスタイルに準拠しています。ユーザーが簡単にアプリにログインできるように、以下の手順に従って、アプリのユーザーインターフェイスにログインボタンを追加できます。

// In your view controller
override func viewDidLoad() {
    super.viewDidLoad()

    // Create Login Button.
    let loginButton = LoginButton()
    loginButton.delegate = self
    
    // Configuration for permissions and presenting.
    loginButton.permissions = [.profile]
    loginButton.presentingViewController = self
    
    // Add button to view and layout it.
    view.addSubview(loginButton)
    loginButton.translatesAutoresizingMaskIntoConstraints = false
    loginButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    loginButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}

ユーザーがログインボタンをタップすると、適切なログインフローで認証されます。ユーザーがデバイスにLINEをインストール済みの場合、LINEからアプリにユーザーのLINE認証情報が渡されます。ユーザーはこの認証情報を使って認証を受けます。そうでない場合、ブラウザでLINEログイン画面が開きます。ユーザーは、この画面にLINE認証情報を入力します。

ログイン状態を受信するには、LoginButtonDelegateプロトコルの関連するデリゲートメソッドを以下のように実装します。

extension LoginViewController: LoginButtonDelegate {
    func loginButton(_ button: LoginButton, didSucceedLogin loginResult: LoginResult) {
        hideIndicator()
        print("Login Succeeded.")
    }
    
    func loginButton(_ button: LoginButton, didFailLogin error: LineSDKError) {
        hideIndicator()
        print("Error: \(error)")
    }
    
    func loginButtonDidStartLogin(_ button: LoginButton) {
        showIndicator()
        print("Login Started.")
    }
}

ログイン処理が完了すると、デリゲートメソッドのいずれかがログイン結果と共に呼び出されます。

# 独自のコードを使う

デフォルトのログインボタンを使う代わりに、コードを使ってユーザーインターフェイスとログインプロセスをカスタマイズすることもできます。

ログイン処理を実行するには、適切なパラメータを指定してLoginManager.loginメソッドを呼び出します。通常、ログイン処理はビューコントローラーで以下のように実行します。

// LoginViewController.swift

import LineSDK

class LoginViewController: UIViewController {
    override func viewDidLoad() {
        //...
    }
    
    func login() {
        LoginManager.shared.login(permissions: [.profile], in: self) {
            result in
            switch result {
            case .success(let loginResult):
                print(loginResult.accessToken.value)
                // Do other things you need with the login result
            case .failure(let error):
                print(error)
            }
        }
    }
}

ユーザーがログイン処理を完了すると、完了ハンドラーがresult引数と共に呼び出されます。ログイン結果にスイッチして、ログインの詳細にアクセスします。

ログインに成功すると、共通のログイン情報を含むLoginResultオブジェクトがLINEプラットフォームから返されます。LoginManager.shared.isAuthorizedメソッドを使ってログイン状態にアクセスします。

ログイン処理中にエラーが発生した場合は、.failureresult引数と、関連付けられたLineSDKError列挙型メンバーがLINE SDKから返されます。SDKからエラーの詳細を取得して適切に制御する方法については、「エラーを制御する」を参照してください。

ログインインターフェイスの設計については、「LINEログインボタン デザインガイドライン」を参照してください。このページからは、LINEログインボタンの画像もダウンロードできます。

# ログイン結果を処理する

# アクセストークンの権限

LoginManager.loginメソッドを呼び出すとき、ユーザーからアプリに付与させたい任意の権限を指定できますが、対応する権限がチャネルに設定されていない可能性があります。その場合は、認可リクエストに指定した権限と、LoginResultオブジェクトのpermissionsプロパティの値が異なります。

アクセストークンに関連づけられた付与済みの権限を確認するには、permissionsプロパティを取得します。たとえば、アクセストークンに.profile権限が含まれるかどうかは、以下のコードを使って確認します。

case .success(let loginResult):
    let profileEnabled = loginResult.permissions.contains(.profile)

適切な権限がない場合、APIコールは失敗します。詳しくは、「エラーを制御する」を参照してください。

# ユーザープロフィール

認可リクエストにプロフィール取得権限を指定した場合、ログイン結果にはUserProfileオブジェクトが含まれます。以下のようにユーザープロフィール情報にアクセスすれば、独自のユーザーシステムを構築できます。

LoginManager.shared.login(permissions: [.profile], in: self) { 
    result in
    switch result {
    case .success(let loginResult):
        if let profile = loginResult.userProfile {
            print("User ID: \(profile.userID)")
            print("User Display Name: \(profile.displayName)")
            print("User Icon: \(String(describing: profile.pictureURL))")
        }
    case .failure(let error):
        print(error)
    }
}

ユーザーIDは各プロバイダーに対してのみ一意です。1人のLINEユーザーは、プロバイダーごとに異なるユーザーIDを持ちます。ユーザーIDでは、異なるプロバイダーを横断してユーザーを識別できません。

# ユーザー情報をバックエンドサーバーで利用する

ユーザーのなりすまし

バックエンドサーバーでは、UserProfileオブジェクトから取得できるユーザーIDなどの情報は、利用しないでください。悪意のあるクライアントは、任意のユーザーになりすますために、任意のユーザーIDや不正な情報をバックエンドサーバーに送信できます。

ユーザーIDなどの情報を送信する代わりにアクセストークンを送信し、バックエンドサーバーではアクセストークンからユーザーIDなどの情報を取得します。

通常、バックエンドサーバーでユーザーを識別するために、ユーザーIDや表示名のような、ユーザーのLINEアカウントに登録されている情報を使用します。そのような情報をアプリからバックエンドサーバーに送信する際は、情報を平文で送信するのではなく、アプリで取得したアクセストークンを送信してください。信頼できる情報を安全に送受信するために、アクセストークンを利用してください。バックエンドサーバーでアクセストークンの正当性を検証したり、ユーザー情報をLINEのサーバーから取得したりできます。

アクセストークンは、LoginResultオブジェクトから取得できます。以下のコードは、アクセストークンを取得する方法を示しています。

LoginManager.shared.login(permissions: [.profile], in: self) { 
    result in
    switch result {
    case .success(let loginResult):
        let token = loginResult.accessToken.value
        // Send `token` to your server.
    case .failure(let error):
        print(error)

バックエンドサーバーで利用するAPIについては、以下を参照してください。