EasyApp

Setting

Learn how to implement setting page in your app

settings

Settings Page Module

The Settings module provides complete app settings functionality, including user profile management, subscription status, system configuration, help information, and other core features.

Module Structure

Settings/
├── View/
│   └── SettingsView.swift           # Main settings page
└── SubPages/
    ├── UserProfile/                 # User profile management
    │   ├── View/UserProfile.swift
    │   ├── ViewModel/
    │   └── Model/
    ├── About/                       # About page
    │   └── View/AboutView.swift
    ├── Policy/                      # Privacy policy
    │   └── View/PrivacyPolicyView.swift
    └── FQA/                         # Frequently asked questions
        ├── View/FQAView.swift
        ├── Model/
        └── Datas/

Core Features

1. User Information Management

Feature Characteristics:

  • User avatar display and updates
  • Username and email information
  • Subscription status display
  • Personal profile editing
struct UserInfoView: View {
    @EnvironmentObject private var authManager: AuthManager
    var viewModel: UserProfileVM
    
    var body: some View {
        HStack {
            AvatarImage(data: viewModel.avatarData, width: 40)
            
            VStack(alignment: .leading) {
                Text(viewModel.email)
                    .font(.headline)
                
                Text(viewModel.username)
                    .font(.subheadline)
                    .foregroundColor(.secondary)
                
                // Subscription status display
                Text(
                    String(
                        format: String(localized: "current_membership_format"),
                        authManager.storeKitProduct?.displayName ?? String(localized: "free")
                    )
                )
                .font(.subheadline)
                .foregroundColor(.secondary)
            }
        }
    }
}

2. Navigation Routing System

Use enums to define clear navigation paths:

enum SettingsPath: Hashable, Equatable {
    case userInfo           // User information
    case inAppPurchases     // In-app purchases
    case policy             // Privacy policy
    case about              // About page
    case fqa                // FAQ
}

3. Grouped Settings Layout

User Information Section

Section(header: Text("user_information")) {
    EANavigationLink(value: SettingsPath.userInfo) {
        UserInfoView(viewModel: viewModel)
            .redacted(if: viewModel.state.isLoading)
    }
}

In-App Purchase Management

Section(header: Text("in_app_purchases")) {
    EANavigationLink(value: SettingsPath.inAppPurchases) {
        HStack(spacing: 12) {
            Image(systemName: "creditcard.fill")
                .resizable()
                .frame(width: 30, height: 30)
                .foregroundStyle(Color.onboardingBackground)
            
            VStack(alignment: .leading, spacing: 6) {
                Text("in_app_purchases")
                    .font(.headline)
                Text("manage_in_app_purchases")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
        }
    }
}

4. System Settings Integration

Language Settings

EANavigationLink(action: {
    OpenApp.openUrlOutsideApp(UIApplication.openSettingsURLString)
}) {
    HStack {
        Label("language", systemImage: "globe.americas.fill")
        Spacer()
        Image(systemName: "chevron.right")
            .foregroundColor(Color(UIColor.tertiaryLabel))
    }
}

5. User Profile Page

Supports complete user profile management:

struct UserProfileView: View {
    @StateObject private var viewModel = UserProfileVM()
    @EnvironmentObject private var authManager: AuthManager
    
    var body: some View {
        List {
            // Avatar selection area
            Section {
                HStack {
                    Spacer()
                    Group {
                        if viewModel.uploadLoading {
                            ProgressView()
                                .frame(width: 100, height: 100)
                        } else {
                            AvatarImage(data: viewModel.avatarData, width: 100)
                                .onTapGesture {
                                    viewModel.showPhotosPicker = true
                                }
                        }
                    }
                    Spacer()
                }
            }
            
            // User information editing area
            // ...
        }
        .photosPicker(
            isPresented: $viewModel.showPhotosPicker,
            selection: $viewModel.imageSelection,
            matching: .images
        )
    }
}

6. About Page

Display app basic information and contact details:

struct AboutView: View {
    var body: some View {
        ScrollView {
            VStack(spacing: 24) {
                // App icon
                if let logo = UIImage(named: "appicon") {
                    Image(uiImage: logo)
                        .resizable()
                        .frame(width: 100, height: 100)
                        .circle()
                        .shadowCompat(radius: 2)
                }
                
                // App information
                VStack(spacing: 8) {
                    Text(AppData.appName)
                        .font(.title)
                        .bold()
                    
                    Text(
                        String(
                            format: "version_build", 
                            AppData.appVersion,
                            AppData.appBuildNumber
                        )
                    )
                    .font(.subheadline)
                    .foregroundColor(.secondary)
                }
                
                // Contact information
                SocialLinkView(
                    url: "mailto:\(AppData.supportEmail)", 
                    image: "envelope", 
                    title: "Support Email"
                )
                
                SocialLinkView(
                    url: AppData.websiteURL, 
                    image: "globe", 
                    title: "Website"
                )
            }
        }
    }
}

7. Account Management Features

Sign Out Function

Section {
    Button(action: {
        showSignOutAlert.toggle()
    }) {
        Text("sign_out")
            .multilineTextAlignment(.center)
            .frame(maxWidth: .infinity)
    }
    .tint(.red)
}

Delete Account Function

Section {
    Button(action: {
        showDeleteUserAlert.toggle()
    }) {
        Text("delete_user")
            .multilineTextAlignment(.center)
            .frame(maxWidth: .infinity)
    }
    .tint(.red)
}

8. Security Confirmation Dialogs

.alert("delete_user", isPresented: $showDeleteUserAlert) {
    Button("cancel", role: .cancel) {
        showDeleteUserAlert.toggle()
    }
    
    Button("ok", role: .destructive) {
        Task {
            await authManager.deleteUser()
        }
    }
}

Use SwiftUI's NavigationStack to implement page navigation:

.navigationDestination(for: SettingsPath.self) { path in
    switch path {
    case .userInfo:
        UserProfileView()
    case .inAppPurchases:
        InAppPurchasesView()
    case .policy:
        PrivacyPolicyView()
    case .about:
        AboutView()
    case .fqa:
        FQAView()
    }
}

1. Subscription Status Integration

  • Support for both RevenueCat and StoreKit2 subscription management
  • Real-time display of user's current subscription status

2. Avatar Management

  • Support for selecting avatar from photo library
  • Avatar caching and optimized display

3. Multi-language Support

  • Complete internationalization support
  • System language settings navigation
  • Localized string management

4. State Management

  • Uses MVVM architecture
  • Reactive data binding
  • Error handling and retry mechanisms

Last updated on