|
2 | 2 | // OneKDayApp.swift
|
3 | 3 | // OneKDay
|
4 | 4 | //
|
5 |
| -// Created by Elijah Biede on 11/8/22. |
| 5 | +// Created by Hundter Biede on 11/8/22. |
6 | 6 | //
|
7 | 7 |
|
8 |
| -import BackgroundTasks |
9 | 8 | import HealthKit
|
10 |
| -import UserNotifications |
11 | 9 | import SwiftUI
|
| 10 | +import WidgetKit |
12 | 11 |
|
13 | 12 | @main
|
14 | 13 | struct OneKDayApp: App {
|
15 | 14 | private let userDefaults = UserDefaults()
|
16 | 15 | private let notificationCenter = UNUserNotificationCenter.current()
|
| 16 | + |
| 17 | + @State private var hasCheckedHealthAccess = false |
| 18 | + @State private var canReadHealthData = false |
17 | 19 |
|
| 20 | + @ViewBuilder |
18 | 21 | var body: some Scene {
|
19 | 22 | WindowGroup {
|
20 |
| - ContentView() |
21 |
| - .onAppear { |
22 |
| - notificationCenter.requestAuthorization(options: [.alert, .provisional, .sound]) { granted, _ in |
23 |
| - if granted { |
24 |
| - print("User allowed alerts") |
25 |
| - } else { |
26 |
| - print("User denied alerts") |
| 23 | + if canReadHealthData { |
| 24 | + ContentView() |
| 25 | + } else if hasCheckedHealthAccess { |
| 26 | + Text("Enable access to health data to use OneK Day") |
| 27 | + } else { |
| 28 | + VStack {} |
| 29 | + .onAppear { |
| 30 | + WidgetCenter.shared.reloadTimelines(ofKind: STEP_COUNT_WIDGET_KIND) |
| 31 | + HealthData.requestHealthDataAccessIfNeeded { success in |
| 32 | + print("didLoadHealthData: \(success)") |
| 33 | + hasCheckedHealthAccess.toggle() |
| 34 | + if success { |
| 35 | + canReadHealthData.toggle() |
| 36 | + } |
27 | 37 | }
|
28 | 38 | }
|
29 |
| - BGTaskScheduler.shared.register(forTaskWithIdentifier: BACKGROUND_ID, using: .main) { task in |
30 |
| - // swiftlint:disable:next force_cast |
31 |
| - handleBackgroundUpdate(task: task as! BGAppRefreshTask) |
32 |
| - } |
33 |
| - requestAppRefresh() |
34 |
| - HealthData.requestHealthDataAccessIfNeeded { success in |
35 |
| - print("didLoadHealthData: \(success)") |
36 |
| - } |
37 |
| - let content = UNMutableNotificationContent() |
38 |
| - content.title = "Get Stepping!" |
39 |
| - content.body = "Get your \(1000) steps in the next \(15) minutes!" |
40 |
| - let request = UNNotificationRequest( |
41 |
| - identifier: "stepGoalNotAchieved", |
42 |
| - content: content, |
43 |
| - trigger: nil |
44 |
| - ) |
45 |
| - notificationCenter.add(request) |
46 |
| - } |
47 |
| - } |
48 |
| - } |
49 |
| - |
50 |
| - func handleBackgroundUpdate(task: BGAppRefreshTask) { |
51 |
| - let components = Calendar.current.dateComponents([.hour, .minute], from: Date()) |
52 |
| - let contentTest = UNMutableNotificationContent() |
53 |
| - contentTest.title = "TEST: Get Stepping!" |
54 |
| - contentTest.body = "Get your \(1000) steps in the next \(components.hour!) minutes!" |
55 |
| - let request1 = UNNotificationRequest(identifier: "testNotifSteps", content: contentTest, trigger: nil) |
56 |
| - notificationCenter.add(request1) |
57 |
| - |
58 |
| - // Only run from 8 AM to 8 PM |
59 |
| - if components.hour! >= 8 && components.hour! < 20 { |
60 |
| - HealthData.getHourlyMetricCount(for: .stepCount) { result in |
61 |
| - let stepGoal = userDefaults.integer(forKey: STEP_GOAL_KEY) |
62 |
| - |
63 |
| - let minutesEarly = 60 - components.minute! |
64 |
| - if result.isEmpty || (Int(result[0].metric) < minutesEarly && Int(result[0].metric) > 0) { |
65 |
| - let content = UNMutableNotificationContent() |
66 |
| - content.title = "Get Stepping!" |
67 |
| - content.body = "Get your \(stepGoal) steps in the next \(minutesEarly) minutes!" |
68 |
| - let request = UNNotificationRequest( |
69 |
| - identifier: "stepGoalNotAchieved", |
70 |
| - content: content, |
71 |
| - trigger: nil |
72 |
| - ) |
73 |
| - notificationCenter.add(request) |
74 |
| - } |
75 | 39 | }
|
76 | 40 | }
|
77 |
| - requestAppRefresh() |
78 |
| - } |
79 |
| - |
80 |
| - func requestAppRefresh() { |
81 |
| - let components = Calendar.current.dateComponents([.hour], from: Date()) |
82 |
| - let request = BGAppRefreshTaskRequest(identifier: BACKGROUND_ID) |
83 |
| - request.earliestBeginDate = Date( |
84 |
| - // 15 minutes in the future, unless it's between 8 PM or before 8 AM, in which case 60 minutes |
85 |
| - timeIntervalSinceNow: components.hour! >= 8 && components.hour! < 20 ? 900 : 3600 |
86 |
| - ) |
87 |
| - do { |
88 |
| - try BGTaskScheduler.shared.submit(request) |
89 |
| - } catch { |
90 |
| - print("Could not schedule app refresh: \(error)") |
91 |
| - } |
92 | 41 | }
|
93 | 42 | }
|
0 commit comments