Skip to main content

Overview

Social authentication allows users to sign in to your app using their existing social media accounts. The Dynamic Swift SDK supports multiple providers including Google, Apple, and Farcaster.

Prerequisites

1. Dynamic Dashboard Configuration

Before implementing social authentication, you must enable and configure the desired providers in your Dynamic dashboard:
  1. Log in to Dynamic Dashboard
  2. Navigate to Log in and User ProfileSocial
  3. Enable the providers you want to support
  4. Configure OAuth settings for each provider
Register your app’s redirect URL in the Dynamic dashboard:
  1. Go to Dynamic Dashboard
  2. Navigate to SecurityWhitelist Mobile Deeplink
  3. Add your app’s deep link URL (e.g., yourapp://)
  4. Save the configuration

3. Info.plist Configuration

Add the following to your Info.plist to ensure authentication callbacks work properly:
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>com.yourcompany.yourapp</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>yourapp</string>
        </array>
    </dict>
</array>

Implementation

Social Login with Providers

Use the sdk.auth.social.connect() method to authenticate with social providers:
import DynamicSDKSwift

let sdk = DynamicSDK.instance()

// Google Sign-In
func signInWithGoogle() async {
    do {
        try await sdk.auth.social.connect(provider: .google)
        print("Signed in with Google!")
    } catch {
        print("Google sign-in failed: \(error)")
    }
}

// Apple Sign-In
func signInWithApple() async {
    do {
        try await sdk.auth.social.connect(provider: .apple)
        print("Signed in with Apple!")
    } catch {
        print("Apple sign-in failed: \(error)")
    }
}

// Farcaster Sign-In
func signInWithFarcaster() async {
    do {
        try await sdk.auth.social.connect(provider: .farcaster)
        print("Signed in with Farcaster!")
    } catch {
        print("Farcaster sign-in failed: \(error)")
    }
}

Supported Providers

The SDK supports the following social providers:
ProviderEnum Value
Google.google
Apple.apple
Farcaster.farcaster

Complete Social Authentication Example

Here’s a complete example showing how to implement social authentication in a SwiftUI view:
import SwiftUI
import DynamicSDKSwift
import Combine

struct SocialLoginView: View {
    @StateObject private var viewModel = SocialLoginViewModel()
    
    var body: some View {
        VStack(spacing: 16) {
            // Google button
            Button {
                viewModel.signInWithGoogle()
            } label: {
                HStack {
                    Text("G")
                        .font(.headline)
                        .foregroundColor(.blue)
                    Text("Continue with Google")
                }
                .frame(maxWidth: .infinity)
                .padding()
                .background(Color(.systemGray6))
                .cornerRadius(10)
            }
            
            // Apple button
            Button {
                viewModel.signInWithApple()
            } label: {
                HStack {
                    Image(systemName: "applelogo")
                        .font(.title3)
                    Text("Continue with Apple")
                }
                .frame(maxWidth: .infinity)
                .padding()
                .background(Color(.systemGray6))
                .cornerRadius(10)
            }
            
            // Farcaster button
            Button {
                viewModel.signInWithFarcaster()
            } label: {
                HStack {
                    Text("🟣")
                        .font(.title3)
                    Text("Continue with Farcaster")
                }
                .frame(maxWidth: .infinity)
                .padding()
                .background(Color(.systemGray6))
                .cornerRadius(10)
            }
            
            // Error message
            if let error = viewModel.errorMessage {
                Text(error)
                    .foregroundColor(.red)
                    .font(.caption)
            }
        }
        .padding()
    }
}

@MainActor
class SocialLoginViewModel: ObservableObject {
    @Published var errorMessage: String?
    
    private let sdk = DynamicSDK.instance()
    
    func signInWithGoogle() {
        errorMessage = nil
        Task {
            do {
                try await sdk.auth.social.connect(provider: .google)
                // User is authenticated - navigation handled by auth state listener
            } catch {
                errorMessage = "Google sign-in failed: \(error.localizedDescription)"
            }
        }
    }
    
    func signInWithApple() {
        errorMessage = nil
        Task {
            do {
                try await sdk.auth.social.connect(provider: .apple)
            } catch {
                errorMessage = "Apple sign-in failed: \(error.localizedDescription)"
            }
        }
    }
    
    func signInWithFarcaster() {
        errorMessage = nil
        Task {
            do {
                try await sdk.auth.social.connect(provider: .farcaster)
            } catch {
                errorMessage = "Farcaster sign-in failed: \(error.localizedDescription)"
            }
        }
    }
}

Listening for Authentication State

After social authentication succeeds, use the Combine publisher to handle the authenticated user:
import DynamicSDKSwift
import Combine

class AuthManager: ObservableObject {
    @Published var user: UserProfile?
    
    private let sdk = DynamicSDK.instance()
    private var cancellables = Set<AnyCancellable>()
    
    func startListening(onAuthenticated: @escaping () -> Void) {
        // Check if already authenticated
        if sdk.auth.authenticatedUser != nil {
            onAuthenticated()
            return
        }
        
        // Listen for authentication changes
        sdk.auth.authenticatedUserChanges
            .receive(on: DispatchQueue.main)
            .sink { [weak self] user in
                self?.user = user
                if user != nil {
                    onAuthenticated()
                }
            }
            .store(in: &cancellables)
    }
}

Best Practices

  • Use a consistent deep link URL format
  • Ensure the URL is whitelisted in your Dynamic dashboard
  • Test deep link handling in your app
  • Make sure the redirectUrl in ClientProps matches your URL scheme

2. User Experience

  • Show loading states during authentication
  • Provide clear error messages
  • Handle user cancellation gracefully

3. Security

  • Never store sensitive authentication data
  • Use secure network connections
  • Implement proper session management

Troubleshooting

Callback Not Working

  • Verify your app’s URL scheme is configured correctly in Info.plist
  • Check that the redirectUrl in ClientProps matches your URL scheme
  • Ensure your deep link URL is whitelisted in Dynamic dashboard

Provider Not Working

  • Confirm provider is enabled in Dynamic dashboard
  • Check that OAuth settings are properly configured
  • Verify you have the correct permissions/scopes configured

Authentication Fails

  • Check network connectivity
  • Verify provider credentials in Dynamic dashboard
  • Ensure the user’s account with the provider is valid
  • Check for any error messages in the console