Skip to content

flida-dev/ios-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flida iOS SDK

The official iOS SDK for integrating Flida authentication into your iOS applications.

Installation

Swift Package Manager

  1. In Xcode, go to File > Add Package Dependencies...
  2. Enter the repository URL: https://github.com/flida-dev/ios-sdk
  3. Select the version you want to use.

Configuration

1. Info.plist Setup (Recommended)

Add the FlidaAuthHost key to your Info.plist file:

<key>FlidaAuthHost</key>
<string>YOUR_CLIENT_ID.api.flida.dev</string>

Format: {clientId}.api.{domain}

Examples:

  • 019b650a-156e-77f3-ad1d-df2e2d8c2a5c.api.flida.dev
  • 019b650a-156e-77f3-ad1d-df2e2d8c2a5c.api.flida.ru

The SDK automatically derives from FlidaAuthHost:

  • Client ID — extracted from the first part
  • API Endpointhttps://api.{domain}
  • Auth Endpointhttps://{domain}
  • Redirect URIflida{clientId}://auth

2. URL Scheme Setup

Add a URL scheme to handle the OAuth callback. In your Info.plist:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>flida{YOUR_CLIENT_ID}</string>
        </array>
    </dict>
</array>

3. Initialization

The SDK initializes automatically from Info.plist when you first access FlidaIDSDK.shared. No explicit initialization needed.

Usage

Sign In

To start the login flow, call signIn. You need to provide a ASWebAuthenticationPresentationContextProviding (usually your view controller).

import AuthenticationServices
import FlidaIDSDK

class ViewController: UIViewController, ASWebAuthenticationPresentationContextProviding {

    func signIn() {
        FlidaIDSDK.shared.signIn(
            presenting: self,
            scopes: ["openid", "name", "e-mail-address", "phone-number"]
        ) { result in
            switch result {
            case .success(let tokenResponse):
                print("Access Token: \(tokenResponse.token.accessToken)")
            case .failure(let error):
                print("Error: \(error.localizedDescription)")
            }
        }
    }

    // ASWebAuthenticationPresentationContextProviding
    func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
        return self.view.window!
    }
}

Get User Info

Once authorized, you can fetch user details:

FlidaIDSDK.shared.getUserInfo(accessToken: accessToken) { result in
    switch result {
    case .success(let user):
        print("User Name: \(user.name)")
        print("User ID: \(user.id)")
    case .failure(let error):
        print("Error: \(error.localizedDescription)")
    }
}

Refresh Token

To refresh the access token:

FlidaIDSDK.shared.refreshTokens(refreshToken: refreshToken) { result in
    switch result {
    case .success(let tokenResponse):
        print("New Access Token: \(tokenResponse.token.accessToken)")
    case .failure(let error):
        print("Error: \(error.localizedDescription)")
    }
}

Logout

FlidaIDSDK.shared.logout()

Event Stream

The SDK provides a Combine-based event stream for reactive programming. Subscribe to events to get notified about authentication state changes.

Available Events

Event Description
signedIn(user:accessToken:) User successfully signed in
signInFailed(error:) Sign in failed
tokensRefreshed(accessToken:) Tokens refreshed successfully
tokenRefreshFailed(error:) Token refresh failed
loggedOut(reason:) User was logged out
userInfoFetched(user:) User info fetched successfully
userInfoFetchFailed(error:) User info fetch failed

Logout Reasons

Reason Description
.userInitiated User called logout() explicitly
.sessionExpired Refresh token expired (404)
.unauthorized Server returned 401 on token refresh

Subscribe to Events

import Combine
import FlidaIDSDK

class AuthManager {
    private var cancellables = Set<AnyCancellable>()
    
    init() {
        FlidaIDSDK.shared.events.events
            .sink { [weak self] event in
                self?.handleEvent(event)
            }
            .store(in: &cancellables)
    }
    
    private func handleEvent(_ event: FlidaEvent) {
        switch event {
        case .signedIn(let user, let accessToken):
            print("User signed in: \(user?.name ?? "Unknown")")
            
        case .signInFailed(let error):
            print("Sign in failed: \(error.localizedDescription)")
            
        case .tokensRefreshed(let accessToken):
            print("Tokens refreshed")
            
        case .tokenRefreshFailed(let error):
            print("Token refresh failed: \(error.localizedDescription)")
            
        case .loggedOut(let reason):
            switch reason {
            case .userInitiated:
                print("User logged out")
            case .sessionExpired:
                print("Session expired")
            case .unauthorized:
                // 401 on refresh - redirect to login
                print("Session invalid, please sign in again")
            }
            
        case .userInfoFetched(let user):
            print("User info: \(user.name)")
            
        case .userInfoFetchFailed(let error):
            print("Failed to get user info: \(error.localizedDescription)")
        }
    }
}

Error Handling

All SDK methods return typed FlidaError for precise error handling:

FlidaIDSDK.shared.signIn(presenting: self, scopes: ["openid"]) { result in
    switch result {
    case .success(let response):
        // Handle success
        
    case .failure(let error):
        switch error {
        case .userCancelled:
            // User cancelled - no need to show error
            break
        case .notInitialized:
            print("Configure FlidaAuthHost in Info.plist")
        case .unauthorized:
            print("Token expired, please sign in again")
        case .networkError(let underlyingError):
            print("Network error: \(underlyingError)")
        default:
            print("Error: \(error.localizedDescription)")
        }
    }
}

Error Types

Error Description
notInitialized SDK not configured (missing FlidaAuthHost)
userCancelled User cancelled authentication
invalidCallbackURL Invalid callback URL received
stateMismatch OAuth state mismatch (possible CSRF)
noAuthorizationCode No authorization code in callback
pkceGenerationFailed Failed to generate PKCE challenge
oauthError(String) OAuth error from server
unauthorized 401 - Access token expired
forbidden(String?) 403 - Access denied
refreshTokenExpired Refresh token expired
tokenExchangeFailed(String?) Token exchange failed
networkError(Error) Network request failed
serverError(statusCode:message:) Server returned an error
decodingError(Error) Failed to decode response
noData No data received from server

Logging

The SDK includes a built-in logging system with configurable log levels.

Log Levels

Level Description
.none Logging disabled (default)
.error Only errors
.warning Errors and warnings
.info Errors, warnings, and info messages
.debug All above + HTTP request/response info
.verbose All messages including HTTP bodies

Enable Logging

// Enable debug logging
FlidaIDSDK.shared.setLogLevel(.debug)

// Or for maximum detail
FlidaIDSDK.shared.setLogLevel(.verbose)

⚠️ Security Note: At .verbose level, sensitive data is automatically masked, but it's recommended to only use verbose logging during development.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published