# Facebook Login for iOS - Advanced



#### - [Login Review](#review)
#### - [Custom Login Button](#custom-login-button)
#### - [Using the Interface Builder](#interface-builder)
#### - [Access Tokens](#access-tokens)
#### - [Profiles](#profiles)
#### - [Track Profile Pictures](#profile_picture_view)
#### - [Setting the Authorization Type](#auth_type)

## Login Review {#review}

If your app asks for more than `public_profile` and `email`, Facebook must review it before you release it. Learn more about the review process and what's required to pass review.

[Login Review Guide](https://developers.facebook.com/docs/facebook-login/review)

## Custom Login Button {#custom-login-button}

Instead of using the Facebook-branded login button (explained in [Facebook Login for iOS - Quickstart](https://developers.facebook.com/documentation/facebook-login/ios#6--add-facebook-login-to-your-code)) you may want to design a custom layout and behavior. In the following code example we invoke the login dialog using the login manager class (`LoginManager`) and a custom button (`UIButton`). You can use any other custom user interface or event handling to invoke the login dialog.

```
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // Add a custom login button to your app
        let loginButton = UIButton(type: .custom)
        loginButton.backgroundColor = .darkGray
        loginButton.frame = CGRect(x: 0, y: 0, width: 180, height: 40)
        loginButton.center = view.center
        loginButton.setTitle("My Login Button", for: .normal)

        // Handle clicks on the button
        loginButton.addTarget(self, action: #selector(loginButtonClicked), for: .touchUpInside)

        view.addSubview(loginButton)
    }

    // Once the button is clicked, show the login dialog
    func loginButtonClicked() {
        let loginManager = LoginManager()
        loginManager.logIn(permissions: ["public_profile"], from: self) { result, error in
            if let error = error {
                print("Encountered Erorr: \(error)")
            } else if let result = result, result.isCancelled {
                print("Cancelled")
            } else {
                print("Logged In")
            }
        }
    }
}
```

## Using the Interface Builder {#interface-builder}

These steps are required for version 12.0.0 and later of the Facebook iOS SDK. Apps using the `Interface Builder` may crash if you have not completed this step.

To add the login button graphically in `Interface Builder`:

1. Add a `UIButton` object to your layout. Set constraints to position it.
2. In `Identity inspector` change the `Class` property to `FBSDKLoginButton`.

Now your layout looks like this:

**Note**: Do not set a module for the `FBSDKLoginButton` class. It should show **None**:

**Note**: You may see the following error in Xcode logs due to a known issue with XCFrameworks:

```
[Storyboard] Unknown class FBSDKLoginButton in Interface Builder file.
```

You can fix this by "pre-loading" the FBSDKLoginButton class before the storyboard loads by adding the following to your `application:didFinishLaunchingWithOptions:` method:

```
// For Swift
_ = FBLoginButton.self

// For Objective-C
[FBSDKLoginButton class];
```

## Access Tokens {#access-tokens}

### Notifications {#access-tokens-notifications}

You can track `AccessToken.current` changes with the `.AccessTokenDidChange` notification in `NotificationCenter`. This allows you to respond to changes in the user's login state:

```
NotificationCenter.default.addObserver(
    forName: .AccessTokenDidChange,
    object: nil,
    queue: .main
) { notification in
    if notification.userInfo?[AccessTokenDidChangeUserIDKey] != nil {
        // Handle user change
    }
}
```

The iOS SDK can update `AccessToken.current` over time, such as when the SDK refreshes a token with a longer expiration date. Therefore, you should check the `userInfo` dictionary in the notification for `AccessTokenDidChangeUserIDKey` to determine if the user has changed.

## Profiles {#profiles}

`Profile` contains public profile information, allowing you to personalize your app with the user's name and profile picture. You can load the logged in user's profile using `loadCurrentProfile(completion:)`.

```
Profile.loadCurrentProfile { profile, error in
    if let firstName = profile?.firstName {
        print("Hello, \(firstName)")
    }
}
```

You can set the `enableUpdatesOnAccessTokenChange` property to `true` to have the profile automatically loaded to `Profile.current`. This also lets you to observe the `.ProfileDidChange` notification to respond to profile changes:

```
Profile.enableUpdatesOnAccessTokenChange(true)
NotificationCenter.default.addObserver(
    forName: .ProfileDidChange,
    object: nil,
    queue: .main
) { notification in
    if let currentProfile = Profile.current {
        // Update for new user profile
    }
}
```

## Showing Profile Pictures {#profile_picture_view}

The `FBProfilePictureView` class provides an easy way to display someone's Facebook profile picture. Simply set the `profileID` property on the instance. You can set it to a value of `AccessToken.current.userID` to show the profile picture of the person currently logged in.

```
let profilePictureView = FBProfilePictureView()
profilePictureView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
profilePictureView.profileID = AccessToken.current!.userID
view.addSubview(profilePictureView)
```

## Setting the Authorization Type {#auth_type}

The default `auth_type` for Facebook Login buttons in the Facebook SDK for iOS is [rerequest](https://developers.facebook.com/documentation/facebook-login/guides/permissions/request-revoke#handling). If you want to avoid requesting permissions that were previously denied, set `auth_type` to `nil`. You can also set it to [reauthorize](https://developers.facebook.com/documentation/facebook-login/auth-vs-data#data-access-expiration) to show the data reauthorization dialog if the user's data access has expired.

The following example shows how to set the `auth_type` in Swift.

```
let loginButton = FBLoginButton()

// Set to nil for no auth_type
button.authType = nil

// Or set to reauthorize
button.authType = .reauthorize
```

The following example shows how to set the `auth_type` using a login configuration with a login manager.

```
let config = LoginConfiguration(
    permissions: [],
    tracking: .enabled,
    messengerPageId: nil,
    authType: nil
)

let loginManager = LoginManager()
loginManager.logIn(viewController: self, configuration: config!) { loginResult in
    // Do something with loginResult
}
```