0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

エントリーポイント

0
Posted at

EchoLog アプリの構成を わかりやすく解説してみる

この記事では、SwiftUI を使って構築した EchoLog アプリのエントリーポイント周りのコードについて、文章とコードを交えて解説します。


🎯 アプリ全体の概要

このアプリは App プロトコルを採用しており、以下の状態オブジェクトをアプリ全体で扱います。

  • AuthViewModel — 認証状態を管理
  • SyncManager — データ同期の管理
  • NetworkMonitor — ネットワーク状態監視
  • AppState — 画面遷移などアプリ全体の状態管理

まずはアプリ入口となる EchoLogApp から見ていきます。


🛠 EchoLogApp — アプリのエントリーポイント

import SwiftUI
import UserNotifications

@main
struct EchoLogApp: App {
    @StateObject private var authViewModel = AuthViewModel()
    @StateObject private var syncManager = SyncManager.shared
    @StateObject private var networkMonitor = NetworkMonitor.shared
    @StateObject private var appState = AppState.shared
    
    init() {
        setupAppearance()
        requestNotificationPermission()
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(authViewModel)
                .environmentObject(syncManager)
                .environmentObject(networkMonitor)
                .environmentObject(appState)
                .preferredColorScheme(.dark) // ダークモードオンリー
        }
    }
}

🎨 NavigationBar / TabBar の外観設定

private func setupAppearance() {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = UIColor(Color(hex: "0A0E14"))
    appearance.titleTextAttributes = [.foregroundColor: UIColor(Color(hex: "E2E8F0"))]
    appearance.largeTitleTextAttributes = [.foregroundColor: UIColor(Color(hex: "E2E8F0"))]
    
    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
    UINavigationBar.appearance().compactAppearance = appearance
    UINavigationBar.appearance().tintColor = UIColor(Color(hex: "00D9FF"))
    
    let tabBarAppearance = UITabBarAppearance()
    tabBarAppearance.configureWithOpaqueBackground()
    tabBarAppearance.backgroundColor = UIColor(Color(hex: "0A0E14"))
    
    UITabBar.appearance().standardAppearance = tabBarAppearance
    UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance
    UITabBar.appearance().tintColor = UIColor(Color(hex: "00D9FF"))
    UITabBar.appearance().unselectedItemTintColor = UIColor(Color(hex: "6B7280"))
}

🔔 通知許可

private func requestNotificationPermission() {
    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
        if granted {
            print("✅ Notification permission granted")
        } else if let error = error {
            print("❌ Notification permission error: \(error)")
        } else {
            print("⚠️ Notification permission denied")
        }
    }
}

📱 ContentView — 認証状態に応じた画面切り替え

struct ContentView: View {
    @EnvironmentObject var authViewModel: AuthViewModel
    
    var body: some View {
        Group {
            if authViewModel.isAuthenticated {
                MainTabView()
            } else {
                LoginView()
            }
        }
        .animation(.easeInOut, value: authViewModel.isAuthenticated)
    }
}

🗂 MainTabView — タブ UI

struct MainTabView: View {
    @EnvironmentObject var appState: AppState
    @State private var selectedTab = 0
    
    var body: some View {
        TabView(selection: $selectedTab) {
            HomeView()
                .tabItem {
                    Label("ホーム", systemImage: "house.fill")
                }
                .tag(0)
            
            ChatLogView()
                .tabItem {
                    Label("ログ", systemImage: "bubble.left.and.bubble.right.fill")
                }
                .tag(1)
            
            EcomokoView()
                .tabItem {
                    Label("エコモコ", systemImage: "heart.fill")
                }
                .tag(2)
        }
        .accentColor(Color.theme.primary)
        .onChange(of: appState.shouldNavigateToHome) { shouldNavigate in
            if shouldNavigate {
                selectedTab = 0
                appState.shouldNavigateToHome = false
            }
        }
    }
}

🧪 Preview

#Preview {
    ContentView()
        .environmentObject(AuthViewModel())
        .environmentObject(SyncManager.shared)
        .environmentObject(NetworkMonitor.shared)
        .environmentObject(AppState.shared)
}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?