Open1
Swift状態管理のミスにより、何度も初期化される問題について
アプリの初期画面に戻るたびに、CounterPresenterが初期化される
onAppearで初期化が起こっている
失敗コード
App.swift
import SwiftUI
@main
struct SampleWatch_Watch_AppApp: App {
private let exerciseDataUseCase: ExerciseDataUseCase
private let initialCounter: CounterEntity
@State private var isShowAleart = false
@State private var errorMessage: String?
@StateObject var workoutManager: WorkoutManager = WorkoutManager()
init() {
AppLogger.shared.logger.debug("App init")
exerciseDataUseCase = ExerciseDataUseCase(
repository: ExerciseDataRepository()
)
var targetCount: Int = Int()
do {
if let target = try exerciseDataUseCase.getMaxRecordCount() {
targetCount = target
} else {
targetCount = 10
}
} catch {
errorMessage = error.localizedDescription
AppLogger.shared.logger.error("\(error)")
}
initialCounter = CounterEntity(
count: 0,
targetCount: targetCount
)
}
var body: some Scene {
WindowGroup {
ContentView()
.alert(isPresented: $isShowAleart) {
Alert(
title: Text(
errorMessage ?? "unknow error"
)
)
}
.environmentObject(workoutManager)
.environmentObject(
CounterPresenter(
counter: initialCounter,
counterUseCase: CounterUseCase(
exerciseDataUseCase: ExerciseDataUseCase(
repository: ExerciseDataRepository()
)
)
)
)
.onAppear() {
workoutManager.requestAuthorization()
}
}
}
}
成功したコード
StateObjectとして定義し、initで初期化する
@StateObject var counterPresenter: CounterPresenter
それを、以下のように適用させることで、毎回の初期化は行われなくなる
.environmentObject(counterPresenter)
要は、状態管理のミスだった
import SwiftUI
@main
struct SampleWatch_Watch_AppApp: App {
@State private var isShowAleart = false
@State private var errorMessage: String?
@StateObject var workoutManager: WorkoutManager = WorkoutManager()
@StateObject var counterPresenter: CounterPresenter
init() {
AppLogger.shared.logger.debug("App init")
let exerciseDataUseCase = ExerciseDataUseCase(
repository: ExerciseDataRepository()
)
var targetCount: Int = Int()
do {
if let target = try exerciseDataUseCase.getMaxRecordCount() {
targetCount = target
} else {
targetCount = 10
}
} catch {
errorMessage = error.localizedDescription
AppLogger.shared.logger.error("\(error)")
}
let initialCounter = CounterEntity(
count: 0,
targetCount: targetCount
)
let counterUseCase = CounterUseCase(exerciseDataUseCase: exerciseDataUseCase)
let presenter = CounterPresenter(
counter: initialCounter,
counterUseCase: counterUseCase
)
_counterPresenter = StateObject(wrappedValue: presenter)
}
var body: some Scene {
WindowGroup {
ContentView()
.alert(isPresented: $isShowAleart) {
Alert(
title: Text(
errorMessage ?? "unknow error"
)
)
}
.onAppear() {
workoutManager.requestAuthorization()
}
.environmentObject(workoutManager)
.environmentObject(counterPresenter)
}
}
}