From c86fd0c2d1fc7a3cb43c61d640dbf4f5c4b6c40c Mon Sep 17 00:00:00 2001
From: Nick Sarno <44950578+SwiftfulThinking@users.noreply.github.com>
Date: Mon, 22 Apr 2024 20:38:08 -0400
Subject: [PATCH 1/2] Update README.md
---
README.md | 148 ++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 127 insertions(+), 21 deletions(-)
diff --git a/README.md b/README.md
index 61594a9..ff1c19d 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@ Convenience methods to manage Firebase Authentication in Swift projects.
- ✅ Sign In With Apple
- ✅ Sign In With Google
+- ✅ Sign In With Phone
```swift
Task {
@@ -22,41 +23,61 @@ Task {
}
```
-## Usage
+Sample project: https://github.com/SwiftfulThinking/SwiftfulFirebasePackagesExample
-Import the package to your project.
+## Setup
+
+
+ Details (Click to expand)
+
+
+### 1. Import the package to your project.
* File -> Swift Packages -> Add Package Dependency
* Add URL for this repository: https://github.com/SwiftfulThinking/SwiftfulFirebaseAuth.git
-#### Import the package to your file.
+### 2. Import the package to your file.
```swift
import SwiftfulFirebaseAuth
```
-#### Create one instance of AuthManager for your application.
+### 3. Create one instance of AuthManager for your application.
```swift
let authManager = AuthManager(configuration: .firebase)
+
+// Use Mock configuration to avoid running Firebase while developing (ex. for SwiftUI Previews).
+let authManager = AuthManager(configuration: .mock)
```
+### 4. Configure your Firebase project.
+Add the Firebase SDK to your application and configure() the SDK on launch.
-#### Use Mock configuration to avoid running Firebase while developing (ex. for SwiftUI Previews).
```swift
-let authManager = AuthManager(configuration: .mock)
+@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
+```
+```swift
+func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ FirebaseApp.configure()
+ return true
+}
```
-#### Configure your Firebase project.
-Add the Firebase SDK to your application and configure() the SDK on launch.
+
-##### Sign In With Apple
-1. Enable Apple as a Sign-In Method in Firebase Authentication console.
-2. Add Sign in with Apple Signing Capability to your Xcode project.
+## Sign In With Apple
-https://firebase.google.com/docs/auth/ios/apple
+
+ Details (Click to expand)
+
+Firebase docs: https://firebase.google.com/docs/auth/ios/apple
-```swift
-try await authManager.signInApple()
-```
+### 1. Enable Apple as a Sign-In Method in Firebase Authentication console.
+* Firebase Console -> Authentication -> Sign-in method -> Add new provider
+
+### 2. 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)
+
+### 3. Add Apple Button (optional)
```swift
SignInWithAppleButtonView(
type: .signUp,
@@ -66,19 +87,85 @@ SignInWithAppleButtonView(
.frame(height: 50)
```
-##### Sign In With Google
-1. Enable Apple as a Sign-In Method in Firebase Authentication console & update the info.plist file.
-2. Add custom URL scheme (URL Types -> REVERSED_CLIENT_ID)
+### 4. Sign in
-https://firebase.google.com/docs/auth/ios/google-signin
+```swift
+try await authManager.signInApple()
+```
+
+
+
+## Sign In With Google
+
+
+ Details (Click to expand)
+
+
+Firebase docs: https://firebase.google.com/docs/auth/ios/google-signin
+### 1. Enable Google as a Sign-In Method in Firebase Authentication console.
+* Firebase Console -> Authentication -> Sign-in method -> Add new provider
+### 2. Update you app's the info.plist file.
+* Firebase Console -> Project Settings -> Your apps -> GoogleService-Info.plist
+
+### 3. 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
+
+### 4. Add Google Button (optional)
+```swift
+SignInWithGoogleButtonView(
+ type: .signUp,
+ style: .black,
+ cornerRadius: 10
+)
+.frame(height: 50)
+```
+
+### 5. Sign in
```swift
let clientId = FirebaseApp.app()?.options.clientId
try await authManager.signInGoogle(GIDClientID: clientId)
```
+
+
+
+## Sign In With Phone
+
+
+ Details (Click to expand)
+
+
+Firebase docs: https://firebase.google.com/docs/auth/ios/phone-auth
+
+### 1. Enable Phone Number as a Sign-In Method in Firebase Authentication console.
+* Firebase Console -> Authentication -> Sign-in method -> Add new provider
+
+### 2. Enable APNs notifications (silent push notifications).
+* Create an APNs Authentication Key in [Apple Developer Member Center](https://developer.apple.com/membercenter/index.action) (requires Apple Developer Account)
+* Certificates, Identifiers & Profiles -> New Key for Apple Push Notifications service (APNs) -> download .p8 file
+
+### 3. Upload APNs key to Firebase.
+* Firebase Console -> Project Settings -> Cloud Messaging -> APNs Authentication Key
+
+### 4. Enable reCAPTCHA verification (optional?).
+* Firebase Console -> Project Settings -> Encoded App ID
+* Xcode Project Navigator -> Target -> Info -> URL Types -> add Encoded App ID as URL Schemes value
+
+### 5. Get the user's phone number
+* This SDK does NOT format phone numbers or provide UI for this. You must provide a string in the correct format.
+* Phone numbers have to be correctly formatted, such as "+1 650-555-3434" for US numbers.
+* See [Firebase Docs](https://firebase.google.com/docs/auth/ios/phone-auth) for details about phone number implementation
+* Possible resources for phone number formatting:
+ - https://stackoverflow.com/questions/32364055/formatting-phone-number-in-swift
+ - https://github.com/iziz/libPhoneNumber-iOS
+ - https://github.com/MojtabaHs/iPhoneNumberField
+
+### 6. Add Google Button (optional)
+
```swift
-SignInWithGoogleButtonView(
+SignInWithPhoneButtonView(
type: .signUp,
style: .black,
cornerRadius: 10
@@ -86,6 +173,24 @@ SignInWithGoogleButtonView(
.frame(height: 50)
```
+### 7. Send verification code to user's phone.
+
+```swift
+try await authManager.signInPhone_Start(phoneNumber: phoneNumber)
+```
+
+### 8. Verify code and sign in
+```swift
+try await authManager.signInPhone_Verify(code: code)
+```
+
+
+
+## Already Signed In
+
+
+ Details (Click to expand)
+
#### Synchronously get user's authentication info.
```swift
@@ -106,7 +211,6 @@ Task {
}
```
-
#### Sign out or delete user's authentication.
```swift
try authManager.signOut()
@@ -115,5 +219,7 @@ try authManager.signOut()
try await authManager.deleteAuthentication()
```
+
+
## Want to contribute?
Open a PR! New Sign-In Methods must use Swift Concurrency (async/await).
From 9b6cace87d5a65531fac009ce3bb5dbc911dc4b3 Mon Sep 17 00:00:00 2001
From: Nick
Date: Mon, 22 Apr 2024 21:03:56 -0400
Subject: [PATCH 2/2] [Feature] Add SignInWithPhoneButtonView
---
Package.swift | 2 +-
README.md | 16 ++---
.../ASAuthorizationAppleIDButton+EXT.swift | 60 ++++++++++++++++
.../Core/SignInWithAppleButtonView.swift | 6 --
.../Core/SignInWithGoogleButtonView.swift | 62 +++-------------
.../Core/SignInWithPhoneButtonView.swift | 70 +++++++++++++++++++
.../GoogleRed.colorset/Contents.json | 20 ++++++
7 files changed, 163 insertions(+), 73 deletions(-)
create mode 100644 Sources/SwiftfulFirebaseAuth/Core/ASAuthorizationAppleIDButton+EXT.swift
create mode 100644 Sources/SwiftfulFirebaseAuth/Core/SignInWithPhoneButtonView.swift
create mode 100644 Sources/SwiftfulFirebaseAuth/Support/Assets.xcassets/GoogleRed.colorset/Contents.json
diff --git a/Package.swift b/Package.swift
index 3b5bc6c..7e88719 100644
--- a/Package.swift
+++ b/Package.swift
@@ -30,7 +30,7 @@ let package = Package(
.product(name: "GoogleSignInSwift", package: "GoogleSignIn-iOS")
],
resources: [
- .process("Assets")
+ .process("Support/Assets")
]
),
.testTarget(
diff --git a/README.md b/README.md
index ff1c19d..f20e913 100644
--- a/README.md
+++ b/README.md
@@ -79,12 +79,8 @@ Firebase docs: https://firebase.google.com/docs/auth/ios/apple
### 3. Add Apple Button (optional)
```swift
-SignInWithAppleButtonView(
- type: .signUp,
- style: .black,
- cornerRadius: 10
-)
-.frame(height: 50)
+SignInWithAppleButtonView()
+ .frame(height: 50)
```
### 4. Sign in
@@ -115,12 +111,8 @@ Firebase docs: https://firebase.google.com/docs/auth/ios/google-signin
### 4. Add Google Button (optional)
```swift
-SignInWithGoogleButtonView(
- type: .signUp,
- style: .black,
- cornerRadius: 10
-)
-.frame(height: 50)
+SignInWithGoogleButtonView()
+ .frame(height: 50)
```
### 5. Sign in
diff --git a/Sources/SwiftfulFirebaseAuth/Core/ASAuthorizationAppleIDButton+EXT.swift b/Sources/SwiftfulFirebaseAuth/Core/ASAuthorizationAppleIDButton+EXT.swift
new file mode 100644
index 0000000..e635853
--- /dev/null
+++ b/Sources/SwiftfulFirebaseAuth/Core/ASAuthorizationAppleIDButton+EXT.swift
@@ -0,0 +1,60 @@
+//
+// ASAuthorizationAppleIDButton.swift
+//
+//
+// Created by Nick Sarno on 4/22/24.
+//
+
+import Foundation
+import SwiftUI
+import AuthenticationServices
+
+extension ASAuthorizationAppleIDButton.Style {
+ var backgroundColor: Color {
+ switch self {
+ case .white:
+ return .white
+ case .whiteOutline:
+ return .white
+ default:
+ return .black
+ }
+ }
+
+ var foregroundColor: Color {
+ switch self {
+ case .white:
+ return .black
+ case .whiteOutline:
+ return .black
+ default:
+ return .white
+ }
+ }
+
+ var borderColor: Color {
+ switch self {
+ case .white:
+ return .white
+ case .whiteOutline:
+ return .black
+ default:
+ return .black
+ }
+ }
+}
+
+extension ASAuthorizationAppleIDButton.ButtonType {
+ var buttonText: String {
+ switch self {
+ case .signIn:
+ return "Sign in with"
+ case .continue:
+ return "Continue with"
+ case .signUp:
+ return "Sign up with"
+ default:
+ return "Sign in with"
+ }
+ }
+}
diff --git a/Sources/SwiftfulFirebaseAuth/Core/SignInWithAppleButtonView.swift b/Sources/SwiftfulFirebaseAuth/Core/SignInWithAppleButtonView.swift
index a18ad8d..13046ef 100644
--- a/Sources/SwiftfulFirebaseAuth/Core/SignInWithAppleButtonView.swift
+++ b/Sources/SwiftfulFirebaseAuth/Core/SignInWithAppleButtonView.swift
@@ -63,12 +63,6 @@ private struct SignInWithAppleButtonViewRepresentable: UIViewRepresentable {
style: .white, cornerRadius: 30)
.frame(height: 50)
.background(Color.red)
-
- SignInWithGoogleButtonView(
- type: .signIn,
- style: .white, cornerRadius: 30)
- .frame(height: 50)
- .background(Color.red)
}
.padding(40)
}
diff --git a/Sources/SwiftfulFirebaseAuth/Core/SignInWithGoogleButtonView.swift b/Sources/SwiftfulFirebaseAuth/Core/SignInWithGoogleButtonView.swift
index c54a394..03afae8 100644
--- a/Sources/SwiftfulFirebaseAuth/Core/SignInWithGoogleButtonView.swift
+++ b/Sources/SwiftfulFirebaseAuth/Core/SignInWithGoogleButtonView.swift
@@ -9,54 +9,8 @@ import Foundation
import SwiftUI
import AuthenticationServices
-fileprivate extension ASAuthorizationAppleIDButton.Style {
- var backgroundColor: Color {
- switch self {
- case .white:
- return .white
- case .whiteOutline:
- return .white
- default:
- return .black
- }
- }
-
- var foregroundColor: Color {
- switch self {
- case .white:
- return .black
- case .whiteOutline:
- return .black
- default:
- return .white
- }
- }
-
- var borderColor: Color {
- switch self {
- case .white:
- return .white
- case .whiteOutline:
- return .black
- default:
- return .black
- }
- }
-}
-
-fileprivate extension ASAuthorizationAppleIDButton.ButtonType {
- var buttonText: String {
- switch self {
- case .signIn:
- return "Sign in with"
- case .continue:
- return "Continue with"
- case .signUp:
- return "Sign up with"
- default:
- return "Sign in with"
- }
- }
+public extension Color {
+ static let googleRed = Color("GoogleRed", bundle: Bundle.module)
}
public struct SignInWithGoogleButtonView: View {
@@ -66,7 +20,7 @@ public struct SignInWithGoogleButtonView: View {
private var borderColor: Color
private var buttonText: String
private var cornerRadius: CGFloat
-
+
public init(
type: ASAuthorizationAppleIDButton.ButtonType = .signIn,
style: ASAuthorizationAppleIDButton.Style = .black,
@@ -81,8 +35,8 @@ public struct SignInWithGoogleButtonView: View {
public init(
type: ASAuthorizationAppleIDButton.ButtonType = .signIn,
- backgroundColor: Color = .black,
- borderColor: Color = .black,
+ backgroundColor: Color = .googleRed,
+ borderColor: Color = .googleRed,
foregroundColor: Color = .white,
cornerRadius: CGFloat = 10
) {
@@ -102,14 +56,14 @@ public struct SignInWithGoogleButtonView: View {
.fill(backgroundColor)
.padding(0.8)
- HStack(spacing: 6) {
+ HStack(spacing: 8) {
Image("GoogleIcon", bundle: .module)
.resizable()
.scaledToFit()
.frame(width: 16, height: 16)
Text("\(buttonText) Google")
- .font(.system(size: 20))
+ .font(.system(size: 21))
.fontWeight(.medium)
}
.foregroundColor(foregroundColor)
@@ -120,7 +74,7 @@ public struct SignInWithGoogleButtonView: View {
}
#Preview("SignInWithGoogleButtonView") {
- SignInWithGoogleButtonView()
+ SignInWithGoogleButtonView(backgroundColor: .googleRed)
.frame(height: 60)
.padding()
}
diff --git a/Sources/SwiftfulFirebaseAuth/Core/SignInWithPhoneButtonView.swift b/Sources/SwiftfulFirebaseAuth/Core/SignInWithPhoneButtonView.swift
new file mode 100644
index 0000000..37e2a3a
--- /dev/null
+++ b/Sources/SwiftfulFirebaseAuth/Core/SignInWithPhoneButtonView.swift
@@ -0,0 +1,70 @@
+//
+// SignInWithPhoneButtonView.swift
+//
+//
+// Created by Nick Sarno on 4/22/24.
+//
+
+import SwiftUI
+import SwiftUI
+import AuthenticationServices
+
+public struct SignInWithPhoneButtonView: View {
+
+ private var backgroundColor: Color
+ private var foregroundColor: Color
+ private var borderColor: Color
+ private var buttonText: String
+ private var cornerRadius: CGFloat
+
+ public init(
+ type: ASAuthorizationAppleIDButton.ButtonType = .signIn,
+ style: ASAuthorizationAppleIDButton.Style = .black,
+ cornerRadius: CGFloat = 10
+ ) {
+ self.cornerRadius = cornerRadius
+ self.backgroundColor = style.backgroundColor
+ self.foregroundColor = style.foregroundColor
+ self.borderColor = style.borderColor
+ self.buttonText = type.buttonText
+ }
+
+ public var body: some View {
+ ZStack {
+ RoundedRectangle(cornerRadius: cornerRadius)
+ .fill(borderColor)
+
+ RoundedRectangle(cornerRadius: cornerRadius)
+ .fill(backgroundColor)
+ .padding(0.8)
+
+ HStack(spacing: 8) {
+ Image(systemName: "phone.fill")
+ .resizable()
+ .scaledToFit()
+ .frame(width: 16, height: 16)
+
+ Text("\(buttonText) Phone")
+ .font(.system(size: 21))
+ .fontWeight(.medium)
+ }
+ .foregroundColor(foregroundColor)
+ }
+ .padding(.vertical, 1)
+ .disabled(true)
+ }
+}
+
+#Preview("SignInWithGoogleButtonView") {
+ VStack {
+ SignInWithAppleButtonView()
+ .frame(height: 60)
+ .padding()
+ SignInWithGoogleButtonView()
+ .frame(height: 60)
+ .padding()
+ SignInWithPhoneButtonView()
+ .frame(height: 60)
+ .padding()
+ }
+}
diff --git a/Sources/SwiftfulFirebaseAuth/Support/Assets.xcassets/GoogleRed.colorset/Contents.json b/Sources/SwiftfulFirebaseAuth/Support/Assets.xcassets/GoogleRed.colorset/Contents.json
new file mode 100644
index 0000000..142de37
--- /dev/null
+++ b/Sources/SwiftfulFirebaseAuth/Support/Assets.xcassets/GoogleRed.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x35",
+ "green" : "0x43",
+ "red" : "0xEA"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}