Adiciona Plano Bíblia em 180 Dias com lembrete diário e ícone do app
- Leitor bíblico consumindo a API NBV (bible.falehandix.com.br): lista de livros por testamento e leitura de capítulos - Plano de 180 dias com três trilhas diárias (História, Sabedoria e Profetas, Novo Testamento) geradas deterministicamente sobre o cânon embutido (1.189 capítulos, cobertura testada) - Lembrete diário via notificação local recorrente (UNCalendarNotificationTrigger, identificador fixo, sem duplicatas), com pedido de autorização em contexto, configurações de horário/som, e deep link da notificação para a Leitura de Hoje - Estado do plano em SwiftData: progresso, pausa/retomada, reinício e conclusão preservando preferências do lembrete - 15 testes unitários (Testing) e 2 testes de UI (XCUIAutomation) - Ícone do app a partir do logo biblia.png Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
59
Bible-Week/AppRouter.swift
Normal file
59
Bible-Week/AppRouter.swift
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// AppRouter.swift
|
||||
// Bible-Week
|
||||
//
|
||||
// Navegação global do app e tratamento do toque em notificações:
|
||||
// tocar no lembrete abre diretamente o Plano de Leitura → Leitura de Hoje.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Observation
|
||||
import UserNotifications
|
||||
|
||||
@MainActor
|
||||
@Observable
|
||||
final class AppRouter {
|
||||
enum Tab: Hashable {
|
||||
case bible
|
||||
case plan
|
||||
}
|
||||
|
||||
var selectedTab: Tab = .bible
|
||||
|
||||
/// A tela principal do plano já é a "Leitura de Hoje".
|
||||
func openTodayReading() {
|
||||
selectedTab = .plan
|
||||
}
|
||||
}
|
||||
|
||||
/// Delegate do UNUserNotificationCenter. Precisa ser registrado no launch
|
||||
/// (init do App) para capturar o toque na notificação mesmo com o app fechado.
|
||||
final class NotificationCoordinator: NSObject, UNUserNotificationCenterDelegate {
|
||||
private let router: AppRouter
|
||||
|
||||
init(router: AppRouter) {
|
||||
self.router = router
|
||||
}
|
||||
|
||||
/// Usuário tocou na notificação (app fechado, em background ou aberto).
|
||||
func userNotificationCenter(
|
||||
_ center: UNUserNotificationCenter,
|
||||
didReceive response: UNNotificationResponse
|
||||
) async {
|
||||
let userInfo = response.notification.request.content.userInfo
|
||||
let destination = userInfo[NotificationUserInfo.destinationKey] as? String
|
||||
guard destination == NotificationUserInfo.destinationReadingPlan else { return }
|
||||
await MainActor.run {
|
||||
router.openTodayReading()
|
||||
}
|
||||
}
|
||||
|
||||
/// Notificação chegou com o app em foreground: apresentação normal,
|
||||
/// sem navegar automaticamente nem interromper uma leitura em andamento.
|
||||
func userNotificationCenter(
|
||||
_ center: UNUserNotificationCenter,
|
||||
willPresent notification: UNNotification
|
||||
) async -> UNNotificationPresentationOptions {
|
||||
[.banner, .sound]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user