Skip to content

Commit

Permalink
Merge pull request #1 from SwiftfulThinking/auth_manager
Browse files Browse the repository at this point in the history
Auth manager
  • Loading branch information
SwiftfulThinking authored Nov 2, 2023
2 parents 9c29544 + d73066a commit 2c9bb5d
Show file tree
Hide file tree
Showing 11 changed files with 957 additions and 4 deletions.
140 changes: 140 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
{
"pins" : [
{
"identity" : "abseil-cpp-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/abseil-cpp-binary.git",
"state" : {
"revision" : "bfc0b6f81adc06ce5121eb23f628473638d67c5c",
"version" : "1.2022062300.0"
}
},
{
"identity" : "appauth-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/openid/AppAuth-iOS.git",
"state" : {
"revision" : "71cde449f13d453227e687458144bde372d30fc7",
"version" : "1.6.2"
}
},
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk.git",
"state" : {
"revision" : "837d4af6ead57cec1fc38007892500d3139c7556",
"version" : "10.16.0"
}
},
{
"identity" : "googleappmeasurement",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleAppMeasurement.git",
"state" : {
"revision" : "56f681586ff006a7982b53dc94082eea31971acf",
"version" : "10.16.0"
}
},
{
"identity" : "googledatatransport",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleDataTransport.git",
"state" : {
"revision" : "aae45a320fd0d11811820335b1eabc8753902a40",
"version" : "9.2.5"
}
},
{
"identity" : "googlesignin-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleSignIn-iOS.git",
"state" : {
"revision" : "7932d33686c1dc4d7df7a919aae47361d1cdfda4",
"version" : "7.0.0"
}
},
{
"identity" : "googleutilities",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleUtilities.git",
"state" : {
"revision" : "c38ce365d77b04a9a300c31061c5227589e5597b",
"version" : "7.11.5"
}
},
{
"identity" : "grpc-binary",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/grpc-binary.git",
"state" : {
"revision" : "a673bc2937fbe886dd1f99c401b01b6d977a9c98",
"version" : "1.49.1"
}
},
{
"identity" : "gtm-session-fetcher",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "d415594121c9e8a4f9d79cecee0965cf35e74dbd",
"version" : "3.1.1"
}
},
{
"identity" : "gtmappauth",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GTMAppAuth.git",
"state" : {
"revision" : "cee3c709307912d040bd1e06ca919875a92339c6",
"version" : "2.0.0"
}
},
{
"identity" : "interop-ios-for-google-sdks",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/interop-ios-for-google-sdks.git",
"state" : {
"revision" : "2d12673670417654f08f5f90fdd62926dc3a2648",
"version" : "100.0.0"
}
},
{
"identity" : "leveldb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/leveldb.git",
"state" : {
"revision" : "0706abcc6b0bd9cedfbb015ba840e4a780b5159b",
"version" : "1.22.2"
}
},
{
"identity" : "nanopb",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/nanopb.git",
"state" : {
"revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692",
"version" : "2.30909.0"
}
},
{
"identity" : "promises",
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/promises.git",
"state" : {
"revision" : "e70e889c0196c76d22759eb50d6a0270ca9f1d9e",
"version" : "2.3.1"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "3c54ab05249f59f2c6641dd2920b8358ea9ed127",
"version" : "1.24.0"
}
}
],
"version" : 2
}
15 changes: 14 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,30 @@ import PackageDescription

let package = Package(
name: "SwiftfulFirebaseAuth",
platforms: [
.iOS(.v13)
],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
name: "SwiftfulFirebaseAuth",
targets: ["SwiftfulFirebaseAuth"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/firebase/firebase-ios-sdk.git", from: "10.0.0"),
.package(url: "https://github.com/google/GoogleSignIn-iOS.git", from: "7.0.0")
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "SwiftfulFirebaseAuth"),
name: "SwiftfulFirebaseAuth",
dependencies: [
.product(name: "FirebaseAuth", package: "firebase-ios-sdk"),
.product(name: "GoogleSignIn", package: "GoogleSignIn-iOS"),
.product(name: "GoogleSignInSwift", package: "GoogleSignIn-iOS")
]),
.testTarget(
name: "SwiftfulFirebaseAuthTests",
dependencies: ["SwiftfulFirebaseAuth"]),
Expand Down
70 changes: 70 additions & 0 deletions Sources/SwiftfulFirebaseAuth/Core/AuthManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// AuthManager.swift
//
//
// Created by Nick Sarno on 10/25/23.
//

import Foundation

public struct AuthInfo {
public let profile: UserAuthInfo?

public var userId: String? {
profile?.uid
}

public var isSignedIn: Bool {
profile != nil
}
}

public enum Configuration {
case mock, firebase

var provider: AuthProvider {
switch self {
case .firebase:
return FirebaseAuthProvider()
case .mock:
return MockAuthProvider()
}
}
}

public final class AuthManager {

private let provider: AuthProvider

@Published public private(set) var currentUser: AuthInfo?

public init(configuration: Configuration) {
self.provider = configuration.provider
self.currentUser = AuthInfo(profile: provider.getAuthenticatedUser())
self.streamSignInChanges()
}

private func streamSignInChanges() {
Task {
for await user in await provider.authenticationDidChangeStream() {
currentUser = AuthInfo(profile: user)
}
}
}

public func signInGoogle() async throws -> (user: UserAuthInfo, isNewUser: Bool) {
try await provider.authenticateUser_Google()
}

public func signInApple() async throws -> (user: UserAuthInfo, isNewUser: Bool) {
try await provider.authenticateUser_Apple()
}

public func signOut() throws {
try provider.signOut()
}

public func deleteAuthentication() async throws {
try await provider.deleteAccount()
}
}
60 changes: 60 additions & 0 deletions Sources/SwiftfulFirebaseAuth/Core/SignInWithAppleButtonView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// SignInWithAppleButtonView.swift
//
//
// Created by Nick Sarno on 10/25/23.
//

import SwiftUI
import AuthenticationServices

public struct SignInWithAppleButtonView: View {
public let type: ASAuthorizationAppleIDButton.ButtonType
public let style: ASAuthorizationAppleIDButton.Style
public let cornerRadius: CGFloat

public init(
type: ASAuthorizationAppleIDButton.ButtonType = .signIn,
style: ASAuthorizationAppleIDButton.Style = .black,
cornerRadius: CGFloat = 10
) {
self.type = type
self.style = style
self.cornerRadius = cornerRadius
}

public var body: some View {
ZStack {
Color.black.opacity(0.001)

SignInWithAppleButtonViewRepresentable(type: type, style: style, cornerRadius: cornerRadius)
.disabled(true)
}
}
}

private struct SignInWithAppleButtonViewRepresentable: UIViewRepresentable {
let type: ASAuthorizationAppleIDButton.ButtonType
let style: ASAuthorizationAppleIDButton.Style
let cornerRadius: CGFloat

func makeUIView(context: Context) -> some UIView {
let button = ASAuthorizationAppleIDButton(type: type, style: style)
button.cornerRadius = cornerRadius
return button
}

func updateUIView(_ uiView: UIViewType, context: Context) {

}

func makeCoordinator() -> () {

}
}

#Preview("SignInWithAppleButtonView") {
SignInWithAppleButtonView(cornerRadius: 30)
.frame(height: 60)
.padding()
}
51 changes: 51 additions & 0 deletions Sources/SwiftfulFirebaseAuth/Extensions/UIApplication+EXT.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// File.swift
//
//
// Created by Nick Sarno on 10/25/23.
//

import Foundation
import UIKit

extension UIApplication {

static private func rootViewController() -> UIViewController? {
var rootVC: UIViewController?
if #available(iOS 15.0, *) {
rootVC = UIApplication
.shared
.connectedScenes
.compactMap { ($0 as? UIWindowScene)?.keyWindow }
.last?
.rootViewController
} else {
rootVC = UIApplication
.shared
.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.last { $0.isKeyWindow }?
.rootViewController
}

return rootVC ?? UIApplication.shared.keyWindow?.rootViewController
}

@MainActor static func topViewController(controller: UIViewController? = nil) -> UIViewController? {
let controller = controller ?? rootViewController()

if let navigationController = controller as? UINavigationController {
return topViewController(controller: navigationController.visibleViewController)
}
if let tabController = controller as? UITabBarController {
if let selected = tabController.selectedViewController {
return topViewController(controller: selected)
}
}
if let presented = controller?.presentedViewController {
return topViewController(controller: presented)
}
return controller
}

}
Loading

0 comments on commit 2c9bb5d

Please sign in to comment.