Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/google_sign_in/google_sign_in_ios/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 6.3.5

* Migrates ViewProvider and GID SDK wrappers from Objective-C to Swift.
* Returns an error when no host view is available to present Google Sign-In.

## 6.3.4

* Migrates the plugin class from Objective-C to Swift.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import Testing
import Flutter
#endif

// Test implementation of FSIViewProvider.
class TestViewProvider: NSObject, FSIViewProvider {
// Test implementation of ViewProvider.
class TestViewProvider: ViewProvider {
#if os(OSX)
// The view containing the Flutter content.
var view: NSView?
Expand All @@ -28,17 +28,17 @@ class TestViewProvider: NSObject, FSIViewProvider {
#endif
}

// Test implementation of FSIGIDSignIn.
class TestSignIn: NSObject, FSIGIDSignIn {
// Test implementation of GIDSignInProtocol.
class TestSignIn: NSObject, GIDSignInProtocol {
var configuration: GIDConfiguration?

// To cause methods to throw an exception.
var exception: NSException?

// Results to use in completion callbacks.
var user: (any FSIGIDGoogleUser)?
var user: (any GIDGoogleUserProtocol)?
var error: Error?
var signInResult: (any FSIGIDSignInResult)?
var signInResult: (any GIDSignInResultProtocol)?

// Passed parameters.
var hint: String?
Expand All @@ -62,7 +62,7 @@ class TestSignIn: NSObject, FSIGIDSignIn {
return handleURLResult
}

func restorePreviousSignIn(completion: (((any FSIGIDGoogleUser)?, Error?) -> Void)?) {
func restorePreviousSignIn(completion: (((any GIDGoogleUserProtocol)?, Error?) -> Void)?) {
if let exception = exception {
exception.raise()
}
Expand Down Expand Up @@ -90,7 +90,7 @@ class TestSignIn: NSObject, FSIGIDSignIn {
hint: String?,
additionalScopes: [String]?,
nonce: String?,
completion: ((FSIGIDSignInResult?, Error?) -> Void)?
completion: ((GIDSignInResultProtocol?, Error?) -> Void)?
) {
if let exception = exception {
exception.raise()
Expand All @@ -111,7 +111,7 @@ class TestSignIn: NSObject, FSIGIDSignIn {
hint: String?,
additionalScopes: [String]?,
nonce: String?,
completion: (((any FSIGIDSignInResult)?, Error?) -> Void)?
completion: (((any GIDSignInResultProtocol)?, Error?) -> Void)?
) {
if let exception = exception {
exception.raise()
Expand All @@ -129,8 +129,8 @@ class TestSignIn: NSObject, FSIGIDSignIn {
#endif
}

// Test implementation of FSIGIDProfileData.
class TestProfileData: NSObject, FSIGIDProfileData {
// Test implementation of GIDProfileDataProtocol.
class TestProfileData: NSObject, GIDProfileDataProtocol {
var email: String
var name: String
// A URL to return from imageURLWithDimension:.
Expand All @@ -151,8 +151,8 @@ class TestProfileData: NSObject, FSIGIDProfileData {
}
}

// Test implementation of FSIGIDToken.
final class TestToken: NSObject, FSIGIDToken {
// Test implementation of GIDTokenProtocol.
final class TestToken: NSObject, GIDTokenProtocol {
let tokenString: String
let expirationDate: Date?

Expand All @@ -162,31 +162,31 @@ final class TestToken: NSObject, FSIGIDToken {
}
}

// Test implementation of FSIGIDSignInResult.
class TestSignInResult: NSObject, FSIGIDSignInResult {
var user: any FSIGIDGoogleUser
// Test implementation of GIDSignInResultProtocol.
class TestSignInResult: NSObject, GIDSignInResultProtocol {
var user: any GIDGoogleUserProtocol
var serverAuthCode: String?

init(user: any FSIGIDGoogleUser, serverAuthCode: String? = nil) {
init(user: any GIDGoogleUserProtocol, serverAuthCode: String? = nil) {
self.user = user
self.serverAuthCode = serverAuthCode
}
}

// Test implementation of FSIGIDGoogleUser.
class TestGoogleUser: NSObject, FSIGIDGoogleUser {
// Test implementation of GIDGoogleUserProtocol.
class TestGoogleUser: NSObject, GIDGoogleUserProtocol {
var userID: String?
var profile: (any FSIGIDProfileData)?
var profile: (any GIDProfileDataProtocol)?
var grantedScopes: [String]?
var accessToken: any FSIGIDToken = TestToken("Access")
var refreshToken: any FSIGIDToken = TestToken("Refresh")
var idToken: (any FSIGIDToken)?
var accessToken: any GIDTokenProtocol = TestToken("Access")
var refreshToken: any GIDTokenProtocol = TestToken("Refresh")
var idToken: (any GIDTokenProtocol)?

// An exception to throw from methods.
var exception: NSException?

// The result to return from addScopes:presentingViewController:completion:.
var result: (any FSIGIDSignInResult)?
var result: (any GIDSignInResultProtocol)?

// The error to return from methods.
var error: Error?
Expand All @@ -203,7 +203,7 @@ class TestGoogleUser: NSObject, FSIGIDGoogleUser {
userID = userIdentifier
}

func refreshTokensIfNeeded(completion: @escaping ((any FSIGIDGoogleUser)?, Error?) -> Void) {
func refreshTokensIfNeeded(completion: @escaping ((any GIDGoogleUserProtocol)?, Error?) -> Void) {
if let exception = exception {
exception.raise()
}
Expand All @@ -214,7 +214,7 @@ class TestGoogleUser: NSObject, FSIGIDGoogleUser {
func addScopes(
_ scopes: [String],
presenting presentingViewController: UIViewController?,
completion: (((any FSIGIDSignInResult)?, Error?) -> Void)?
completion: (((any GIDSignInResultProtocol)?, Error?) -> Void)?
) {
self.requestedScopes = scopes
self.presentingViewController = presentingViewController
Expand All @@ -227,7 +227,7 @@ class TestGoogleUser: NSObject, FSIGIDGoogleUser {
func addScopes(
_ scopes: [String],
presenting presentingWindow: NSWindow?,
completion: (((any FSIGIDSignInResult)?, Error?) -> Void)?
completion: (((any GIDSignInResultProtocol)?, Error?) -> Void)?
) {
self.requestedScopes = scopes
self.presentingWindow = presentingWindow
Expand Down Expand Up @@ -836,6 +836,38 @@ struct GoogleSignInPluginTests {
}
}

@Suite("wrappers") struct WrapperTests {
@Test func signInCompletesWithErrorWhenPresenterIsNil() async {
let wrapper = GIDSignInWrapper()
await confirmation("completion called") { confirmed in
wrapper.signIn(
withPresenting: nil, hint: nil, additionalScopes: nil, nonce: nil
) { result, error in
#expect(result == nil)
let nsError = error as NSError?
#expect(nsError?.domain == "google_sign_in")
#expect(
nsError?.localizedDescription
== "No host view available to present Google Sign-In.")
confirmed()
}
}
}

@Test func pluginSignInWithoutPresenterReturnsFlutterError() async {
let plugin = GoogleSignInPlugin(
signIn: GIDSignInWrapper(), viewProvider: TestViewProvider())
await confirmation("completion called") { confirmed in
plugin.signIn(withScopeHint: [], nonce: nil) { result, error in
#expect(result == nil)
#expect(error?.code == "google_sign_in: 0")
#expect(error?.message == "No host view available to present Google Sign-In.")
confirmed()
}
}
}
}

#if os(iOS) || targetEnvironment(macCatalyst)
@Suite("topViewController")
@MainActor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ let package = Package(
),
.target(
name: "google_sign_in_ios_objc",
dependencies: [
.product(name: "GoogleSignIn", package: "GoogleSignIn-iOS")
],
publicHeadersPath: "include",
cSettings: [
.headerSearchPath("include/google_sign_in_ios"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,20 @@ private func pigeonErrorCode(for gidSignInErrorCode: Int) -> FSIGoogleSignInErro
public final class GoogleSignInPlugin: NSObject, FlutterPlugin, FSIGoogleSignInApi {
/// Instance used to manage Google Sign In authentication including
/// sign in, sign out, and requesting additional scopes.
let signIn: any FSIGIDSignIn
let signIn: any GIDSignInProtocol

/// A mapping of user IDs to GIDGoogleUser instances to use for follow-up calls.
var usersByIdentifier: [String: any FSIGIDGoogleUser] = [:]
var usersByIdentifier: [String: any GIDGoogleUserProtocol] = [:]

/// The contents of GoogleService-Info.plist, if it exists.
private let googleServiceProperties: [String: Any]?

/// The view provider, to access the current Flutter view.
private let viewProvider: any FSIViewProvider
private let viewProvider: ViewProvider

public static func register(with registrar: FlutterPluginRegistrar) {
let instance = GoogleSignInPlugin(
viewProvider: FSIDefaultViewProvider(registrar: registrar))
viewProvider: DefaultViewProvider(registrar: registrar))
registrar.addApplicationDelegate(instance)
#if os(iOS)
registrar.addSceneDelegate(instance)
Expand All @@ -124,22 +124,22 @@ public final class GoogleSignInPlugin: NSObject, FlutterPlugin, FSIGoogleSignInA
}

/// Inject view provider for testing.
convenience init(viewProvider: any FSIViewProvider) {
self.init(signIn: FSIGIDSignInWrapper(), viewProvider: viewProvider)
convenience init(viewProvider: ViewProvider) {
self.init(signIn: GIDSignInWrapper(), viewProvider: viewProvider)
}

/// Inject `FSIGIDSignIn` for testing.
convenience init(signIn: any FSIGIDSignIn, viewProvider: any FSIViewProvider) {
/// Inject `GIDSignInProtocol` for testing.
convenience init(signIn: any GIDSignInProtocol, viewProvider: ViewProvider) {
self.init(
signIn: signIn,
viewProvider: viewProvider,
googleServiceProperties: loadGoogleServiceInfo())
}

/// Inject `FSIGIDSignIn` and `googleServiceProperties` for testing.
/// Inject `GIDSignInProtocol` and `googleServiceProperties` for testing.
init(
signIn: any FSIGIDSignIn,
viewProvider: any FSIViewProvider,
signIn: any GIDSignInProtocol,
viewProvider: ViewProvider,
googleServiceProperties: [String: Any]?
) {
self.signIn = signIn
Expand Down Expand Up @@ -310,7 +310,7 @@ public final class GoogleSignInPlugin: NSObject, FlutterPlugin, FSIGoogleSignInA
hint: String?,
additionalScopes: [String]?,
nonce: String?,
completion: @escaping (FSIGIDSignInResult?, Error?) -> Void
completion: @escaping (GIDSignInResultProtocol?, Error?) -> Void
) {
#if os(macOS)
signIn.signIn(
Expand All @@ -332,8 +332,8 @@ public final class GoogleSignInPlugin: NSObject, FlutterPlugin, FSIGoogleSignInA
/// Wraps the iOS and macOS scope addition methods.
private func performAddScopes(
_ scopes: [String],
for user: any FSIGIDGoogleUser,
completion: @escaping (FSIGIDSignInResult?, Error?) -> Void
for user: any GIDGoogleUserProtocol,
completion: @escaping (GIDSignInResultProtocol?, Error?) -> Void
) {
#if os(macOS)
user.addScopes(scopes, presenting: viewProvider.view?.window, completion: completion)
Expand Down Expand Up @@ -367,7 +367,7 @@ public final class GoogleSignInPlugin: NSObject, FlutterPlugin, FSIGoogleSignInA
}

private func handleAuthResult(
user: (any FSIGIDGoogleUser)?,
user: (any GIDGoogleUserProtocol)?,
serverAuthCode: String?,
error: Error?,
completion: @escaping (FSISignInResult?, FlutterError?) -> Void
Expand Down Expand Up @@ -395,7 +395,7 @@ public final class GoogleSignInPlugin: NSObject, FlutterPlugin, FSIGoogleSignInA
}

private func didSignIn(
for user: any FSIGIDGoogleUser,
for user: any GIDGoogleUserProtocol,
serverAuthCode: String?,
completion: @escaping (FSISignInResult?, FlutterError?) -> Void
) {
Expand Down
Loading
Loading