Google Sign-In Button in SwiftUI: Code and the Contracts
Two contracts come with the button: Google's branding rules and Apple's requirement for a privacy-equivalent sibling.
TL;DR
A Google sign-in button in SwiftUI carries two contracts: render it per Google's branding guidelines (official G logo, approved labels, no restyling) and satisfy Apple's guideline 4.8 by offering Sign in with Apple at equal prominence beside it. The default integration is the GoogleSignIn-iOS SDK behind a thin SwiftUI wrapper resolving a presentation anchor; the manual ASWebAuthenticationSession route trades the dependency for owning PKCE yourself. Either way, authentication happens server-side: the ID token gets verified for signature and audience before your backend mints a session. A free VP0 design covers the sign-in screen balanced for two to four options.
What does adding Google sign-in actually commit you to?
Two contracts, one you expected and one you maybe did not. The expected one is Google’s: the button renders per the official branding guidelines, with the standard “G” logo, approved label text (“Sign in with Google” or “Continue with Google”), the prescribed light and dark treatments, and no creative recoloring. Brand-kit buttons are contracts; a teal Google button with a redrawn logo fails review with Google and reads as off-brand to users.
The unexpected contract is Apple’s: under App Review guideline 4.8, an app that signs users in with a third-party service must also offer a privacy-focused alternative, which in practice means Sign in with Apple, presented with equivalent prominence. Adding the Google button therefore adds the Apple button too, and the rejection that follows skipping it is routine enough to have its own checklist in the Sign in with Apple rejection fix.
Which integration route fits which app?
| Route | What you add | Most useful for |
|---|---|---|
| GoogleSignIn-iOS SDK | The official SDK, GIDSignIn flow | The default; handles token refresh and account UI |
| Manual OAuth via ASWebAuthenticationSession | No SDK; you run the OIDC dance | Dependency-averse teams comfortable with PKCE |
| Firebase Auth | SDK plus Firebase’s session layer | Apps already on Firebase for backend |
The OAuth client itself costs $0; the spend is integration time, and the SDK route minimizes it: configure the client ID, add the URL scheme, and call the sign-in flow from a presentation anchor. The manual route trades the dependency for owning the nonce, PKCE, and token exchange yourself, which is a fine trade only when someone on the team can name why.
What does the SwiftUI wiring look like?
The SDK is UIKit-shaped at the edges, so the SwiftUI work is a thin, honest wrapper:
struct GoogleSignInButton: View {
let action: () -> Void
var body: some View {
Button(action: action) {
HStack(spacing: 12) {
Image("google_g") // the official asset, unmodified
.resizable().frame(width: 20, height: 20)
Text("Continue with Google")
.font(.system(size: 17, weight: .medium))
}
.frame(maxWidth: .infinity, minHeight: 50)
}
.buttonStyle(.bordered)
}
}
The action resolves the presenting view controller (the SDK’s one awkward requirement in SwiftUI: fetch the key window’s root, or bridge through UIViewControllerRepresentable) and calls GIDSignIn.sharedInstance.signIn(withPresenting:). On success you hold a user object whose ID token is the only thing your backend should trust: send it server-side, verify the signature and audience against your client ID, and mint your own session. Accepting the client’s word that sign-in happened, without server-side token verification, is the integration’s classic security hole.
Restore-previous-session belongs at launch (restorePreviousSignIn), so returning users skip the button entirely, and sign-out clears both the SDK state and your own session, since clearing only one produces the half-logged-in limbo users describe as “the app forgot me but not really.”
How should the button sit among its siblings?
With equal billing and honest order. The sign-in screen lists its options as peers, Apple and Google at matching size and visual weight (Apple’s guideline language pushes parity, and mismatched prominence is a soft rejection trigger), with email/password where it belongs in your model. Auto-triggering the Google flow on screen appearance, pre-selecting it, or rendering competitors as ghost buttons all read as dark-pattern adjacent and buy nothing: the user’s identity choice is the consent moment, the same principle that governs state-operated identity buttons at higher stakes.
One layout note saves a redesign later: leave room for the third button. Apps add sign-in methods over time, and a screen designed as exactly-two-buttons becomes a refactor when the product adds another route. A free VP0 design covers the sign-in screen with the spacing system already balanced for two to four options, which an agent generates against your auth stack directly.
Key takeaways: the Google button done right
- Two contracts: Google’s branding rules on the button, Apple’s 4.8 requiring a privacy-equivalent sibling.
- The SDK route is the default; manual ASWebAuthenticationSession OAuth is for teams that can name why they own PKCE.
- The ID token goes server-side for verification; client-side success alone is not authentication.
- Restore at launch, clear both states at sign-out, and keep the buttons peers in size and order.
- Design the screen for n options, not two.
Frequently asked questions
How do I add a Google sign-in button in SwiftUI? Wrap the official artwork and approved label in a SwiftUI Button per Google’s branding guidelines, resolve a presenting view controller, and call GIDSignIn’s sign-in flow, then verify the resulting ID token on your backend before minting a session. A free VP0 design supplies the sign-in screen layout an agent generates the wiring into.
Does adding Google sign-in require Sign in with Apple? Yes in practice: App Review guideline 4.8 requires apps using third-party login to offer a privacy-focused equivalent, and Sign in with Apple presented at equal prominence is the accepted answer. Plan both buttons from the start.
Can I restyle the Google button to match my app’s design? No: the branding guidelines fix the logo, label text, and color treatments, and modified buttons risk rejection and user distrust. Choose among the approved variants and spend the design freedom on the rest of the screen.
Do I need the GoogleSignIn SDK or can I use plain OAuth? Either works: the SDK handles token refresh, session restore, and the account sheet with minimal code, while a manual ASWebAuthenticationSession flow with PKCE removes the dependency at the cost of owning the OIDC details yourself. Default to the SDK unless you can articulate the trade.
Why must the backend verify the Google ID token? Because client-side success is just the client’s claim: any caller can assert a sign-in. The backend verifies the token’s signature and audience against your client ID, then issues your own session, which is the actual authentication event.
Questions from the VP0 Vibe Coding community
How do I add a Google sign-in button in SwiftUI?
Wrap the official artwork and an approved label in a SwiftUI Button per the branding guidelines, resolve a presenting view controller for GIDSignIn's flow, and send the resulting ID token to your backend for signature and audience verification before creating a session. A free VP0 design supplies the sign-in screen layout.
Does adding Google sign-in require Sign in with Apple too?
Effectively yes: App Review guideline 4.8 requires a privacy-focused equivalent when third-party login is offered, and Sign in with Apple at equal prominence is the standard answer. Plan both buttons from the first design.
Can I restyle the Google sign-in button?
No. The branding guidelines fix the G logo, label wording, and light/dark treatments; modified buttons risk review trouble with Google and read as untrustworthy. Pick an approved variant and design the rest of the screen around it.
Should I use the GoogleSignIn SDK or implement OAuth manually?
Default to the SDK: it handles token refresh, session restore, and presentation with little code. Manual OAuth through ASWebAuthenticationSession with PKCE is legitimate for dependency-averse teams that want to own the OIDC details deliberately.
Why does the backend need to verify the Google ID token?
Client-side success is only a claim. The backend verifies the token's signature and that its audience matches your client ID, then mints your own session; that server-side check is the actual authentication event.
Part of the Native Apple & SwiftUI: The iOS Ecosystem hub. Browse all VP0 topics →
Keep reading
Apple Sign In Required Rejection: Fix It in SwiftUI
Rejected because Sign in with Apple is missing? If you offer Google or Facebook login, Apple requires it too. Here is the SwiftUI fix that clears review.
Native iOS Settings Page Boilerplate in SwiftUI
Settings is review-critical and AI builders generate it worst: a grouped native List, persisted toggles, required account-deletion and legal rows, done right.
Build a Stock Market Heat Map Grid UI in SwiftUI
A market heat map colors and sizes tiles by gain and market cap. Here is how to build the stock market heat map grid in SwiftUI, with an accessible color scale.
Build a Booking.com-Style Availability Calendar in SwiftUI
A Booking.com-style availability picker is more than a date picker. Here is how to build the availability calendar in SwiftUI, with real open and booked dates.
Build a Sideloading iOS App Install Animation in SwiftUI
In the EU, an alt-marketplace install is a real, system-gated flow. Here is how to build the sideloading install animation in SwiftUI, honestly.
Build a Smooth, Scrolling Social Media Feed in SwiftUI
A social media feed in SwiftUI is a scrolling list of post cards. Here is how to build it so it stays smooth with images, likes, and infinite scroll.