Skip to content

Commit 8cf208e

Browse files
author
liuhao
committed
v1.0.1
0 parents  commit 8cf208e

File tree

27 files changed

+1520
-0
lines changed

27 files changed

+1520
-0
lines changed

StepsAppDemo.xcodeproj/project.pbxproj

Lines changed: 493 additions & 0 deletions
Large diffs are not rendered by default.

StepsAppDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>SchemeUserState</key>
6+
<dict>
7+
<key>StepsAppDemo.xcscheme_^#shared#^_</key>
8+
<dict>
9+
<key>orderHint</key>
10+
<integer>1</integer>
11+
</dict>
12+
</dict>
13+
</dict>
14+
</plist>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"colors" : [
3+
{
4+
"idiom" : "universal"
5+
}
6+
],
7+
"info" : {
8+
"author" : "xcode",
9+
"version" : 1
10+
}
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"images" : [
3+
{
4+
"idiom" : "universal",
5+
"platform" : "ios",
6+
"size" : "1024x1024"
7+
}
8+
],
9+
"info" : {
10+
"author" : "xcode",
11+
"version" : 1
12+
}
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"info" : {
3+
"author" : "xcode",
4+
"version" : 1
5+
}
6+
}

StepsAppDemo/ContentView.swift

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//
2+
// ContentView.swift
3+
// StepsAppDemo
4+
//
5+
// Created by liuhao on 17/10/2023.
6+
//
7+
8+
import SwiftUI
9+
10+
struct ContentView: View {
11+
let vieWModel = HealthKitViewModel()
12+
13+
var body: some View {
14+
NavigationStack {
15+
TabView {
16+
TargetView()
17+
.tabItem {
18+
VStack {
19+
Image(systemName: "target")
20+
Text(Constants.titleTabTarget)
21+
}
22+
}
23+
StepsView(viewModel: vieWModel)
24+
.tabItem {
25+
VStack {
26+
Image(systemName: "figure.walk.circle")
27+
Text(Constants.titleTabStepCount)
28+
.foregroundColor(.mainColor)
29+
}
30+
}
31+
ResultView()
32+
.tabItem {
33+
VStack {
34+
Image(systemName: "chart.bar.fill")
35+
Text(Constants.titleTabResult)
36+
}
37+
}
38+
}
39+
.accentColor(.mainColor)
40+
}
41+
}
42+
}
43+
44+
extension ContentView {
45+
func goToSetting() {
46+
let url = URL(string: UIApplication.openSettingsURLString)
47+
if let url = url, UIApplication.shared.canOpenURL(url) {
48+
UIApplication.shared.open(url, options: [:]) { success in
49+
50+
}
51+
}
52+
}
53+
}
54+
55+
#Preview {
56+
ContentView()
57+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// Color+Extension.swift
3+
// StepsAppDemo
4+
//
5+
// Created by liuhao on 18/10/2023.
6+
//
7+
8+
import SwiftUI
9+
import Foundation
10+
11+
12+
extension Color {
13+
static let mainColor = Color(red: 24 / 255.0, green: 185 / 255.0, blue: 253 / 255.0)
14+
static let stepGray = Color(red: 181 / 255.0, green: 181 / 255.0, blue: 181 / 255.0)
15+
static let dateGray = Color(red: 110 / 255.0, green: 110 / 255.0, blue: 110 / 255.0)
16+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// Date+Extension.swift
3+
// StepsAppDemo
4+
//
5+
// Created by liuhao on 19/10/2023.
6+
//
7+
8+
import Foundation
9+
extension Date {
10+
static func sundayAt12AM() -> Date {
11+
return Calendar(identifier: .iso8601).date(from: Calendar(identifier: .iso8601).dateComponents([.yearForWeekOfYear], from: Date()))!
12+
}
13+
14+
static func from(year: Int, month: Int, day: Int) -> Date {
15+
let components = DateComponents(year: year, month: month, day: day)
16+
return Calendar.current.date(from: components)!
17+
}
18+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//
2+
// HealthDailyModel.swift
3+
// StepsAppDemo
4+
//
5+
// Created by liuhao on 19/10/2023.
6+
//
7+
8+
import Foundation
9+
struct HealthDailyModel: Identifiable {
10+
let id = UUID()
11+
12+
let date: Date
13+
let stepsCount: Double
14+
let calories: Double
15+
let distanceWalking: Double
16+
let duration: Double
17+
18+
var formattedDate: String {
19+
let formatter = DateFormatter()
20+
formatter.setLocalizedDateFormatFromTemplate("MM/dd/yyyy")
21+
return formatter.string(from: date)
22+
}
23+
}
24+
25+
struct StepsModel: Identifiable {
26+
var id = UUID()
27+
28+
let date: Date
29+
let stepsCount: Int
30+
}
31+
32+
struct DistanceWalkingModel {
33+
let date: Date
34+
let distanceWalking: Double
35+
}
36+
37+
struct CaloryModel {
38+
let date: Date
39+
let calory: Double
40+
}
41+
42+
struct DurationModel {
43+
let date: Date
44+
let duration: Int
45+
}
46+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"info" : {
3+
"author" : "xcode",
4+
"version" : 1
5+
}
6+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// ResultView.swift
3+
// StepsAppDemo
4+
//
5+
// Created by liuhao on 17/10/2023.
6+
//
7+
8+
import SwiftUI
9+
10+
struct ResultView: View {
11+
var body: some View {
12+
Text(Constants.titleTabResult)
13+
}
14+
}
15+
16+
#Preview {
17+
ResultView()
18+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// CoreRingView.swift
3+
// StepsAppDemo
4+
//
5+
// Created by liuhao on 17/10/2023.
6+
//
7+
8+
import SwiftUI
9+
struct CoreRingView: View {
10+
@ObservedObject var viewModel: HealthKitViewModel
11+
12+
var body: some View {
13+
14+
ZStack {
15+
RingAnimation(model: viewModel, radius: Constants.radiusCoreRing, lineWidth: Constants.lineWidthCoreRing, strokeWidth: Constants.strokeWidthCoreRing, type: .Step)
16+
VStack {
17+
Image(systemName: "figure")
18+
Text("\(viewModel.currentSteps)")
19+
.font(Font.system(size: 40, weight: .bold))
20+
.foregroundColor(.black)
21+
Text(Constants.textToday)
22+
.font(Font.system(size: 18, weight: .bold))
23+
.foregroundColor(.dateGray)
24+
Text("\(Constants.textTarget)\(6000)")
25+
.font(Font.system(size: 10, weight: .bold))
26+
.foregroundColor(.dateGray)
27+
}
28+
}
29+
}
30+
}
31+
32+
#Preview {
33+
CoreRingView(viewModel: HealthKitViewModel())
34+
}
35+
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//
2+
// DayView.swift
3+
// StepsAppDemo
4+
//
5+
// Created by liuhao on 17/10/2023.
6+
//
7+
8+
import SwiftUI
9+
10+
struct DayView: View {
11+
@ObservedObject var viewModel: HealthKitViewModel
12+
@State private var showingBottomSheet = false
13+
14+
var body: some View {
15+
VStack {
16+
Spacer().frame(height: 20)
17+
CoreRingView(viewModel: viewModel)
18+
Spacer().frame(height: 30)
19+
HStack {
20+
Spacer()
21+
IndexRingView(viewModel: viewModel, num: String(format: "%.1f", viewModel.currentCalories ), type: .Calory)
22+
Spacer()
23+
IndexRingView(viewModel: viewModel, num: String(format: "%.1f", viewModel.currentDistance / 1000 ), type: .Distance)
24+
Spacer()
25+
IndexRingView(viewModel: viewModel, num: String(format: "%.1f", viewModel.currentDuration), type: .Duration)
26+
Spacer()
27+
}
28+
Spacer().frame(height: 20)
29+
GradientStepLineChartView(viewModel: viewModel)
30+
}
31+
.sheet(isPresented: $showingBottomSheet) {
32+
VStack() {
33+
Spacer()
34+
Image(systemName: "figure.walk")
35+
.frame(width: 120, height: 120)
36+
.foregroundColor(.white)
37+
.background(Color.green)
38+
.font(Font.system(size: 80))
39+
.cornerRadius(20)
40+
41+
Spacer().frame(height: 30)
42+
Text(Constants.textSenserBeenOff)
43+
.font(Font.system(size: 22, weight: .bold))
44+
.foregroundColor(.black)
45+
Spacer().frame(height: 10)
46+
Text(Constants.textSenserSettingInfo)
47+
.font(Font.system(size: 14, weight: .regular))
48+
.foregroundColor(.stepGray)
49+
50+
Spacer().frame(height: 140)
51+
Button {
52+
goToSetting()
53+
} label: {
54+
Text(Constants.textSetting)
55+
.font(.headline)
56+
.foregroundColor(.black)
57+
.frame(height: 44)
58+
.frame(maxWidth: .infinity)
59+
.background(Color.mainColor.cornerRadius(10))
60+
.shadow(color: Color.mainColor.opacity(0.3), radius: 10, x: 0.0, y: 10.0)
61+
.padding(.leading,20)
62+
.padding(.trailing,20)
63+
}
64+
.cornerRadius(40)
65+
.presentationDetents([.height(550)])
66+
.interactiveDismissDisabled(true)
67+
}
68+
}
69+
.onAppear {
70+
viewModel.requestAuthorization { isSuccess in
71+
/* guard viewModel.authorizationStatus else {
72+
showingBottomSheet = true
73+
return
74+
}
75+
showingBottomSheet = false
76+
*/
77+
if isSuccess == true {
78+
viewModel.querySteps { statsCollection in
79+
if let statsCollection = statsCollection {
80+
viewModel.updateUIFromStats(statsCollection)
81+
}
82+
}
83+
viewModel.queryCalories { statsCollection in
84+
if let statsCollection = statsCollection {
85+
viewModel.updateCalorieUIFromStats(statsCollection)
86+
}
87+
}
88+
viewModel.queryDistance { statsCollection in
89+
if let statsCollection = statsCollection {
90+
viewModel.updateDistanceUIFromStats(statsCollection)
91+
}
92+
}
93+
viewModel.queryExerciseTime { statsCollection in
94+
if let statsCollection = statsCollection {
95+
viewModel.updateExerciseTimeUIFromStats(statsCollection)
96+
}
97+
}
98+
}
99+
}
100+
}
101+
}
102+
}
103+
104+
extension DayView {
105+
func goToSetting() {
106+
let url = URL(string: UIApplication.openSettingsURLString)
107+
if let url = url, UIApplication.shared.canOpenURL(url) {
108+
UIApplication.shared.open(url, options: [:]) { success in
109+
110+
}
111+
}
112+
}
113+
}
114+
115+
116+
#Preview {
117+
DayView(viewModel: HealthKitViewModel())
118+
}
119+

0 commit comments

Comments
 (0)