> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getpara.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Swift Session Management

> Guide to managing authentication sessions in Para for Swift applications

export const Link = ({href, label, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  return <a href={href} target={newTab ? '_blank' : '_self'} rel={newTab ? 'noopener noreferrer' : undefined} className="not-prose inline-block relative text-black font-semibold cursor-pointer border-b-0 no-underline" onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      {label}
      <span className={`absolute left-0 bottom-0 w-full rounded-sm bg-gradient-to-r from-orange-600 to-purple-600 transition-all duration-300 ${isHovered ? 'h-0.5' : 'h-px'}`} />
    </a>;
};

Para Swift SDK provides robust session management, automatically tracking authentication states and ensuring secure, seamless interactions. Effective session management is critical for security, usability, and reliability of your application.

## Session States

Para manages sessions using the `ParaSessionState` enum:

* `unknown`: Initial state before the status is determined.
* `inactive`: SDK initialized but no active session.
* `active`: Session is active but user not fully logged in.
* `activeLoggedIn`: User is fully logged in with an active session.

### Observing Session States

Utilize SwiftUI's Combine or other state management tools to observe changes:

```swift theme={null}
@StateObject private var paraManager: ParaManager

.onChange(of: paraManager.sessionState) { newState in
  switch newState {
    case .activeLoggedIn:
      print("User authenticated")
    case .inactive:
      print("Session inactive")
    default:
      print("Session state: \(newState)")
  }
}
```

## Session Duration

Para session length is configured per API key and can be set up to 30 days through the Configuration section of the <Link label="Developer Portal" href="https://developer.getpara.com" /> or CLI. The Para API enforces the configured duration. Signing a message or transaction, or calling the session keep-alive method, can extend an active session according to that configuration.

## Key Session Methods

* `isSessionActive() async throws -> Bool`: Checks if the session is currently valid before performing authenticated operations.
* `isFullyLoggedIn() async throws -> Bool`: Checks if the user is fully logged in with an active session.
* `exportSession() async throws -> String`: Exports session state as a string that can be used for advanced integration scenarios.
* `logout() async throws`: Clears the current session, removes all website data from the WebView, and resets the session state to inactive.

## Maintaining Active Sessions

For long-running applications, check session status before performing sensitive operations:

```swift theme={null}
func performSensitiveOperation() {
  Task {
    do {
      if try await paraManager.isSessionActive() {
        // Proceed with sensitive operation
        try await signTransaction(...)
      } else {
        // Handle session expiration - redirect to login
        navigateToLogin()
      }
    } catch {
      await MainActor.run {
        isLoggedIn = false
      }
    }
  }
}
```

## Refreshing Expired Sessions

When a session has expired, Para recommends initiating a full authentication flow rather than trying to refresh the session.

<Warning>
  For Swift applications, always call `logout()` before reinitiating authentication when a session has expired to ensure all stored data is properly cleared.
</Warning>

```swift theme={null}
import ParaSwift

func handleSessionExpiration() async {
  do {
    // When session expires, first clear storage
    try await paraManager.logout()

    // Then redirect to authentication screen
    await MainActor.run {
      // Navigate to authentication screen
    }
  } catch {
    // Handle error
  }
}
```

## Background Security

Clear sensitive data when app goes to background by logging out:

```swift theme={null}
class AppDelegate: NSObject, UIApplicationDelegate {
  func applicationDidEnterBackground(_ application: UIApplication) {
    Task {
      try? await paraManager.logout()
    }
  }
}
```

## Exporting Sessions to Your Server

In some advanced scenarios, you may need to export the session state:

```swift theme={null}
func sendSessionToServer() async throws {
  do {
    // Export session without signing capabilities
    let sessionString = try await paraManager.exportSession()

    // Create URL request
    var request = URLRequest(url: URL(string: "https://your-api.com/sessions")!)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")

    // Create request body
    let body: [String: Any] = ["session": sessionString]
    request.httpBody = try JSONSerialization.data(withJSONObject: body)

    // Send request
    let (_, response) = try await URLSession.shared.data(for: request)

    guard let httpResponse = response as? HTTPURLResponse,
          httpResponse.statusCode == 200 else {
      throw URLError(.badServerResponse)
    }

    // Handle success
  } catch {
    // Handle error
    throw error
  }
}
```

## Best Practices

### Check Sessions on App Launch

Verify session status when your app starts to determine if users need to reauthenticate:

```swift theme={null}
import SwiftUI
import ParaSwift

class AppStartupManager: ObservableObject {
  @Published var isLoggedIn = false
  let paraManager: ParaManager

  init(paraManager: ParaManager) {
    self.paraManager = paraManager
    checkSessionOnLaunch()
  }

  func checkSessionOnLaunch() {
    Task {
      do {
        let isActive = try await paraManager.isSessionActive()
        await MainActor.run {
          if isActive {
            // User is logged in
            isLoggedIn = true
          } else {
            // Session not active, clear any lingering data
            Task {
              try? await paraManager.logout()
            }
            isLoggedIn = false
          }
        }
      } catch {
        await MainActor.run {
          isLoggedIn = false
        }
      }
    }
  }
}
```

### Handle App Lifecycle Changes

Swift apps can be backgrounded and foregrounded, which may affect session status:

```swift theme={null}
import SwiftUI
import ParaSwift

class LifecycleManager: ObservableObject {
  let paraManager: ParaManager

  init(paraManager: ParaManager) {
    self.paraManager = paraManager

    // Register for foreground notifications
    NotificationCenter.default.addObserver(
      self,
      selector: #selector(appMovedToForeground),
      name: UIApplication.willEnterForegroundNotification,
      object: nil
    )
  }

  @objc func appMovedToForeground() {
    // App came to foreground, check session
    checkSession()
  }

  func checkSession() {
    Task {
      let isActive = try? await paraManager.isSessionActive()
      if isActive != true {
        try? await paraManager.logout()
        await MainActor.run {
          // Navigate to login screen
        }
      }
    }
  }

  deinit {
    NotificationCenter.default.removeObserver(self)
  }
}
```

## Next Steps

Explore more advanced features and integrations with Para in Swift:

<CardGroup cols={2}>
  <Card horizontal title="Social Login" imgUrl="/images/v3/custom-ui-social.png" href="/v3/swift/guides/social-login" description="Learn how to implement social login in Swift" />

  <Card horizontal title="External Wallets" imgUrl="/images/v3/general-wallets.png" href="/v3/swift/guides/external-wallets" description="Connect to external wallets like MetaMask in your Swift app" />
</CardGroup>
