# User account

For OnsideKit to function fully, the user must be authenticated. An authenticated account securely stores payment methods, purchase history, and ensures that product availability and pricing are accurate for the user's region.

## How Authentication Affects Product Availability

The user's region is crucial for determining which products are available and at what price. The login status directly impacts how this region is determined:

* **When Logged In:** The region associated with the user's Onside account is used. This is the most accurate source of truth.
* **When Logged Out:** The SDK uses a fallback mechanism to estimate the user's region:
  1. It first calls the [`onsideDefaultCountryCodeAssumption()`](https://docs.onside.io/sdk/customizing-sdk-behavior#providing-a-pre-login-country-code-hint) delegate method. If you provide a country code here, it will be used.
  2. If the delegate method returns nil, the SDK will use the device's system region as the default.

## Initiating the Login Flow

Authentication in OnsideKit can be initiated in two ways: explicitly by your code, or implicitly by the SDK when a user attempts an action that requires a valid session.

#### **1. Explicit Initiation**

You can trigger the login flow at any time by calling the static `Onside.requestLogin()` method. This is the recommended approach for UI elements like a dedicated "Log In" button.

**2. Implicit Initiation (Automatic)**

OnsideKit is designed to be smart. You don't always need to check if the user is logged in before calling certain functions. If a user is not authenticated when they try to perform a protected action, the SDK will automatically present the login flow first. Once the user successfully logs in, the SDK will proceed with the original action.

The login flow will be triggered implicitly when you call methods to:

* Initiate a product purchase.
* Display the payment methods manager screen.
* Start the flow for adding a new payment card.

> **This simplifies your code!** You can simply call the purchase method, and OnsideKit handles the "is user logged in?" check for you.

## Understanding the Authentication Flows

Regardless of whether the login is initiated explicitly or implicitly, OnsideKit will use one of the following two authentication flows:

* **App-to-App Authentication (Preferred):** If the Onside store app is installed and OnsideKit correctly configured, the user is redirected to Onside store for a seamless login and then returned to your app. See [Installation Guide](https://docs.onside.io/sdk/installation-guide).
* **In-SDK Authentication (Fallback):** If the Onside app isn't available or the app-to-app flow is disabled via the [`onsideShouldForceLocalLoginMethods()`](https://docs.onside.io/sdk/customizing-sdk-behavior#forcing-in-app-login) delegate method, the SDK presents its own UI for phone number verification.

## Checking the Current Authentication Status

While OnsideKit can handle login implicitly, you will often want to check the user's authentication status to customize your UI.

The user's session is represented by the `storefront` object on the payment queue. A non-nil `storefront` indicates an active, authenticated session.

There are two ways to work with the `storefront`: by manually checking its current state, or by observing changes in real-time.

**1. Manually Checking the Current Status**

```swift
func updateUserUIBasedOnLoginStatus() {
    let isUserLoggedIn = Onside.defaultPaymentQueue().storefront != nil
    
    if isUserLoggedIn {
        // User is logged in. Show account-specific UI.
        loginButton.isHidden = true
        
        // You can also access the user's region from the storefront
        if let userRegion = Onside.defaultPaymentQueue().storefront?.countryCode {
            print("User is authenticated. Storefront region: \(userRegion)")
        }
    } else {
        // User is not logged in. Show a login button.
        loginButton.isHidden = false
        print("User is not authenticated.")
    }
}
```

**2. Observing Changes in Real-Time**

For a more robust and reactive approach, you can observe changes to the `storefront` directly. This is the best way to ensure your UI is always in sync with the user's authentication state.

To do this, you must add an observer that conforms to the `OnsidePaymentTransactionObserver` protocol to the payment queue. The SDK will then notify your observer whenever the `storefront` changes.

```swift
import UIKit
import OnsideKit

class MyViewController: UIViewController, OnsidePaymentTransactionObserver {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Add self as an observer to the payment queue
        Onside.defaultPaymentQueue().add(observer: self)
    }

    func onsidePaymentQueueDidChangeStorefront(_ queue: OnsidePaymentQueue) {
        print("Storefront changed! New storefront: \(String(describing: queue.storefront))")
        // Now, update your UI based on the new state.
        updateUserUIBasedOnLoginStatus()
    }
    
    ...
}
```

## Logging Out

To manually end the current user's session, call the `Onside.logout()` method. This is useful for implementing a "Sign Out" button in your app's user profile or settings screen.

Calling this method will clear all local authentication data for the current user. After a successful logout, `Onside.defaultPaymentQueue().storefront` will become nil, and any action requiring authentication (like making a purchase) will automatically trigger the login flow again.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.onside.io/sdk/user-account.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
