## StoreKit 2 Refactor - Rewrote IAPManager with clean enum-based state model (SubscriptionState) - Added native SubscriptionStoreView for iOS 17+ purchase UI - Subscription status now checked on every app launch - Synced subscription status to UserDefaults for widget access - Simplified PurchaseButtonView and IAPWarningView - Removed unused StatusInfoView ## Interactive Vote Widget - New FeelsVoteWidget with App Intents for mood voting - Subscribers can vote directly from widget, shows stats after voting - Non-subscribers see "Tap to subscribe" which opens subscription store - Added feels:// URL scheme for deep linking ## Firebase Removal - Commented out Firebase imports and initialization - EventLogger now prints to console in DEBUG mode only ## Other Changes - Added fallback for Core Data when App Group unavailable - Added new localization strings for subscription UI - Updated entitlements and Info.plist 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
68 lines
2.6 KiB
Swift
68 lines
2.6 KiB
Swift
//
|
|
// FeelsApp.swift
|
|
// Shared
|
|
//
|
|
// Created by Trey Tartt on 1/5/22.
|
|
//
|
|
|
|
import SwiftUI
|
|
import BackgroundTasks
|
|
import WidgetKit
|
|
|
|
@main
|
|
struct FeelsApp: App {
|
|
@Environment(\.scenePhase) private var scenePhase
|
|
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
|
|
|
let persistenceController = PersistenceController.shared
|
|
@StateObject var iapManager = IAPManager()
|
|
@AppStorage(UserDefaultsStore.Keys.firstLaunchDate.rawValue, store: GroupUserDefaults.groupDefaults) private var firstLaunchDate = Date()
|
|
@State private var showSubscriptionFromWidget = false
|
|
|
|
init() {
|
|
BGTaskScheduler.shared.cancelAllTaskRequests()
|
|
BGTaskScheduler.shared.register(forTaskWithIdentifier: BGTask.updateDBMissingID, using: nil) { (task) in
|
|
BGTask.runFillInMissingDatesTask(task: task as! BGProcessingTask)
|
|
}
|
|
UIApplication.shared.applicationIconBadgeNumber = 0
|
|
// PersistenceController.shared.clearDB()
|
|
// PersistenceController.shared.populateMemory()
|
|
}
|
|
|
|
var body: some Scene {
|
|
WindowGroup {
|
|
// build these here so when tints and other things get updated the views / their data dont
|
|
// have to get redrawn#imageLiteral(resourceName: "simulator_screenshot_0017B4DC-100B-42A3-A406-9019704AE275.png")
|
|
MainTabView(dayView: DayView(viewModel: DayViewViewModel(addMonthStartWeekdayPadding: false)),
|
|
monthView: MonthView(viewModel: DayViewViewModel(addMonthStartWeekdayPadding: true)),
|
|
yearView: YearView(viewModel: YearViewModel()),
|
|
customizeView: CustomizeView())
|
|
.environment(\.managedObjectContext, persistenceController.viewContext)
|
|
.environmentObject(iapManager)
|
|
.sheet(isPresented: $showSubscriptionFromWidget) {
|
|
FeelsSubscriptionStoreView()
|
|
.environmentObject(iapManager)
|
|
}
|
|
.onOpenURL { url in
|
|
if url.scheme == "feels" && url.host == "subscribe" {
|
|
showSubscriptionFromWidget = true
|
|
}
|
|
}
|
|
}.onChange(of: scenePhase) { phase in
|
|
if phase == .background {
|
|
//BGTask.scheduleBackgroundProcessing()
|
|
WidgetCenter.shared.reloadAllTimelines()
|
|
}
|
|
|
|
if phase == .active {
|
|
UIApplication.shared.applicationIconBadgeNumber = 0
|
|
// Check subscription status on each app launch
|
|
Task {
|
|
await iapManager.checkSubscriptionStatus()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|