Guideline 4.8
Guideline 4.8 - Design: Missing Sign in with Apple
Our Take
Apple rejected your app under Guideline 4.8 because it offers third-party login options (Google, Facebook, Twitter, etc.) without also providing Sign in with Apple as an equivalent option. Since September 2019, Apple requires that any app offering third-party or social login must also offer Sign in with Apple and place that signin option at the top of the list. The Sign in with Apple button must be given equal or greater prominence compared to other login options. This is one of the most common and easiest rejections to fix.
Resolution Guide
**Add the Sign in with Apple capability** — In Xcode, go to your target → Signing & Capabilities → + Capability → Sign in with Apple. This enables the entitlement.
**Add the Sign in with Apple button in SwiftUI**:
```swift
import AuthenticationServices
SignInWithAppleButton(.signIn) { request in
request.requestedScopes = [.fullName, .email]
} onCompletion: { result in
switch result {
case .success(let auth):
handleAppleSignIn(auth)
case .failure(let error):
print("Sign in with Apple failed: \(error)")
}
}
.signInWithAppleButtonStyle(.black) // or .white, .whiteOutline
.frame(height: 50)
```
**Position it with equal or greater prominence** — Place the Sign in with Apple button at the top of your login options, or at minimum the same size and position as other social login buttons:
```swift
VStack(spacing: 12) {
SignInWithAppleButton(...)
.frame(height: 50)
GoogleSignInButton()
.frame(height: 50)
FacebookLoginButton()
.frame(height: 50)
}
```
**Handle the Apple ID credential** — On first sign-in, Apple provides a user identifier, optional full name, and optional email. Cache the user identifier because Apple only sends the name and email on the FIRST authorization:
```swift
func handleAppleSignIn(_ authorization: ASAuthorization) {
guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential else { return }
let userId = credential.user // Always provided
let email = credential.email // Only on first auth
let fullName = credential.fullName // Only on first auth
// Send to your backend and create/link account
}
```
**Check credential state on app launch** — Verify the Apple ID is still valid:
```swift
ASAuthorizationAppleIDProvider().getCredentialState(forUserID: savedUserId) { state, error in
switch state {
case .authorized: break // all good
case .revoked: signOut() // user revoked access
case .notFound: signOut() // no credential found
default: break
}
}
```
**Use the system-provided button style** — Apple requires using `SignInWithAppleButton` (SwiftUI) or `ASAuthorizationAppleIDButton` (UIKit). Do not create a custom button with the Apple logo.
**Test with a sandbox Apple ID** — Create a sandbox test account in App Store Connect to test the full sign-in flow before submitting.
Example Rejection Email
Consider Appealing
Do not appeal. This requirement is non-negotiable if you offer any third-party login. The only exception is apps that exclusively use email/password or phone number authentication with no social login buttons — if that’s your case, clarify this in Resolution Center. Otherwise, add Sign in with Apple and resubmit — it’s a 2–4 hour fix.
Before & After
// Login screen with only third-party options — no Sign in with Apple
struct LoginView: View {
var body: some View {
VStack(spacing: 16) {
Text("Welcome")
.font(.largeTitle)
Button(action: { signInWithGoogle() }) {
HStack {
Image("google-logo")
Text("Sign in with Google")
}
.frame(maxWidth: .infinity, minHeight: 50)
.background(Color.white)
.cornerRadius(8)
.overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray))
}
Button(action: { signInWithFacebook() }) {
HStack {
Image("facebook-logo")
Text("Sign in with Facebook")
}
.frame(maxWidth: .infinity, minHeight: 50)
.background(Color(red: 0.23, green: 0.35, blue: 0.60))
.foregroundColor(.white)
.cornerRadius(8)
}
}
.padding()
}
}
// Login screen with Sign in with Apple at top prominence
import AuthenticationServices
struct LoginView: View {
var body: some View {
VStack(spacing: 16) {
Text("Welcome")
.font(.largeTitle)
// Sign in with Apple — FIRST and equal prominence
SignInWithAppleButton(.signIn) { request in
request.requestedScopes = [.fullName, .email]
} onCompletion: { result in
handleAppleSignIn(result)
}
.signInWithAppleButtonStyle(.black)
.frame(maxWidth: .infinity, minHeight: 50)
.cornerRadius(8)
Button(action: { signInWithGoogle() }) {
HStack {
Image("google-logo")
Text("Sign in with Google")
}
.frame(maxWidth: .infinity, minHeight: 50)
.background(Color.white)
.cornerRadius(8)
.overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray))
}
Button(action: { signInWithFacebook() }) {
HStack {
Image("facebook-logo")
Text("Sign in with Facebook")
}
.frame(maxWidth: .infinity, minHeight: 50)
.background(Color(red: 0.23, green: 0.35, blue: 0.60))
.foregroundColor(.white)
.cornerRadius(8)
}
}
.padding()
}
}
What changed: The Sign in with Apple button is added as the first option with equal size (50pt height) and full width. It uses the system-provided SignInWithAppleButton with the .black style, which Apple requires instead of custom buttons. Placing it first ensures equal or greater prominence.
Community Solutions · 0
Sign in to share your solution.
More Guideline 4 (Design) rejections
- Guideline 4.0 - Design: App Does Not Include iOS Features
- Guideline 4.0 - Design: App Looks Like a Website
- Guideline 4.0 - Design: Apple Pay Button Not Following Guidelines
- Guideline 4.0 - Design: Blurry Icons or Low-Resolution Assets
- Guideline 4.0 - Design: Broken Layout on iPad
- Guideline 4.0 - Design: Content Clipped by Notch or Safe Area