Skip to content

SwiftfulThinking/SwiftfulAuthenticating

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

24 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Learn how to build and use this package: https://www.swiftful-thinking.com/offers/REyNLwwH

Authentication Manager for Swift 6 πŸ“

A reusable AuthManager for Swift applications, built for Swift 6. Includes @Observable support.

Pre-built dependencies*:

* Created another? Send the url in issues! πŸ₯³

  • βœ… Sign In Apple
  • βœ… Sign In Google
  • βœ… Sign In Anonymous
Task {
     do {
          let (userAuthInfo, isNewUser) = try await authManager.signInApple()
          // User is signed in

          if isNewUser {
               // New user -> Create user profile in Firestore
          } else {
               // Existing user -> sign in
          }
     } catch {
          // User auth failed
     }
}

Setup

Details (Click to expand)

Create an instance of AuthManager:

let authManager = AuthManager(services: any AuthService, logger: LogManager?)

#if DEBUG
let authManager = AuthManager(service: MockAuthService(), logger: logManager)
#else
let authManager = AuthManager(service: FirebaseAuthService(), logger: logManager)
#endif

Optionally add to SwiftUI environment as an @Observable

Text("Hello, world!")
    .environment(authManager)

Inject dependencies

Details (Click to expand)

AuthManager is initialized with a AuthService. This is a public protocol you can use to create your own dependency.

MockPurchaseService is included for SwiftUI previews and testing.

// User is not yet authenticated
let service = MockAuthService(user: nil)

// User is already authenticated
let service = MockAuthService(user: .mock)

Other services are not directly included, so that the developer can pick-and-choose which dependencies to add to the project.

You can create your own AuthService by conforming to the protocol:

public protocol AuthService: Sendable {
    func getAuthenticatedUser() -> UserAuthInfo?
    func addAuthenticatedUserListener() -> AsyncStream<UserAuthInfo?>
    func signIn(option: SignInOption) async throws -> (user: UserAuthInfo, isNewUser: Bool)
    func signOut() throws
    func deleteAccount() async throws
}

Manage user account

Details (Click to expand)

The manager will automatically fetch and listen for an authenticated user on launch, via getAuthenticatedUser and addAuthenticatedUserListener.

Get authenticated user's info:

let userId = authManager.auth.uid
let authUser = authManager.auth

// Throwing method for convenience with async/await
let uid = try authManager.getAuthId()

Sign out or delete auth:

try authManager.signOut()
try await authManager.deleteAccount()

Sign In Apple

Details (Click to expand)

Add Sign in with Apple Signing Capability to your Xcode project.

  • Xcode Project Navigator -> Target -> Signing & Capabilities -> + Capability -> Sign in with Apple (requires Apple Developer Account)

Add Apple Button (optional), via SwiftfulAuthUI library

import SwiftfulAuthUI

SignInAppleButtonView()
    .frame(height: 50)

Sign in

try await authManager.signInApple()

Sign In Google

Details (Click to expand)

Update your app's the info.plist file.

  • Firebase Console -> Project Settings -> Your apps -> GoogleService-Info.plist

Add custom URL scheme (URL Types -> REVERSED_CLIENT_ID)

  • GoogleService-Info.plist -> REVERSED_CLIENT_ID
  • Xcode Project Navigator -> Target -> Info -> URL Types -> add REVERSED_CLIENT_ID as URL Schemes value

Add Google Button (optional), via SwiftfulAuthUI library

import SwiftfulAuthUI

SignInGoogleButtonView()
    .frame(height: 50)

Sign in

try await authManager.signInGoogle(GIDClientID: clientId)

Sign In Anonymous / Mock

Details (Click to expand)

Add Anonymous Button (optional), via SwiftfulAuthUI library

import SwiftfulAuthUI

SignInAnonymousButtonView()
    .frame(height: 50)

Sign in

try await authManager.signInAnonymous()

About

AuthManager for Swift 6 w/ Observable support

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages