Share
Embed
Prioritizing Health: Developing a Personalized App
tatetate55
March 24, 2024
Transcript
35 slides
-
Some people might say “I haven't done any personal development
lately.” Ҏલ͍͚ͯͨ͠Ͳɺ࠷͍ۙͯ͠ͳ͍ɾɾ -
I want only one function. However, that would likely result
in rejection from the App Review. ̍ͭͷػೳ͚ͩཉ͍͚͠ͲɺͦΕͰϦδΣΫτ͞Εͦ͏ɾɾ -
Why don't you develop your own app only for yourself?
ࣗͷͨΊ͚ͩͷΞϓϦ։ൃͲ͏Ͱ͠ΐ͏ʂʁ -
Background ࡞ͬͨഎܠ • I know we need to walk for
our health. • But I rarely go out. 🏃.. -
I have an incentive Πϯηڅ༩ͷࢧڅʂ I can receive an incentive
from my company if I walk over 4,000 steps a day! https://about.yahoo.co.jp/info/blog/20210719/walking.html ※2021࣌ -
I have an incentive Πϯηڅ༩ͷࢧڅʂ I can receive an incentive
from my company if I walk over 4,000 steps a day! https://about.yahoo.co.jp/info/blog/20210719/walking.html I'm gonna do it! ※2021࣌ -
How the app measures the number of steps There are
two patterns 1. CMPedometer of CoreMotion 2. HealthKit I won't use it this time -> -
CMPedometer of CoreMotion 1. It can measure in real time
2. It can measure the number of steps on that device. 3. It can count steps from iOS 8. -
How to use CMPedometer of CoreMotion import CoreMotion class PedometerManager
{ let pedometer = CMPedometer() // ϖυϝʔλʔ͕ར༻Մೳ͔νΣοΫ func isPedometerAvailable() -> Bool { return CMPedometer.isStepCountingAvailable() } // ϦΞϧλΠϜͰาΛऔಘ func startPedometerUpdates() { guard CMPedometer.isStepCountingAvailable() else { print("Step counting is not available.") return } pedometer.startUpdates(from: Date()) { (data, error) in guard error == nil else { print("There was an error starting pedometer updates: \(error!.localizedDescription)") return } if let pedometerData = data { print("Steps taken: \(pedometerData.numberOfSteps)") // ଞͷσʔλಉ༷ʹΞΫηεՄೳ } } } } -
HealthKit As you know, we can get information from HealthKit
← 📱 Same as this -> -
HealthKit method is popular. And, it’s used for the company’s
app. So, I use Health Kit. -
How to use HealthKit • Add Capability • Add permission
settings for HealthKit data access to info.plist -
How to use import HealthKit class HealthKitManager { let healthStore
= HKHealthStore() // HealthKitͷηοτΞοϓ init() { if HKHealthStore.isHealthDataAvailable() { let allTypes = Set([HKObjectType.quantityType(forIdentifier: .stepCount)!]) healthStore.requestAuthorization(toShare: nil, read: allTypes) { (success, error) in if !success { // ΤϥʔϋϯυϦϯά } } } } // ಛఆͷͷาΛऔಘ func getSteps(forDate date: Date, completion: @escaping (Double) -> Void) { guard let stepCountType = HKQuantityType.quantityType(forIdentifier: .stepCount) else { completion(0) return } let startOfDay = Calendar.current.startOfDay(for: date) let endOfDay = Calendar.current.date(byAdding: .day, value: 1, to: startOfDay) let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: endOfDay, options: .strictStartDate) let query = HKStatisticsQuery(quantityType: stepCountType, quantitySamplePredicate: predicate, options: .cumulativeSum) { (query, statistics, error) in var steps: Double = 0 if error != nil { // ΤϥʔϋϯυϦϯά } else if let quantity = statistics?.sumQuantity() { steps = quantity.doubleValue(for: HKUnit.count()) } DispatchQueue.main.async { completion(steps) } } healthStore.execute(query) } } -
Completion of the iOS version This is what it looks
like when displayed in Swift Charts → -
But Xcode 14 doesn’t have HealthKit capability • Watch’s Widget
of Xcode 14 doesn’t have HealthKit capability. • Therefore, I need to transfer data from my watch or iPhone. ← Nothing… -
I can get the same method as iOS! ΓํiOSͱಉ͡ʂ //
HealthStoreʹࠓͷาΛऔಘ͢ΔϝιουΛՃ extension HealthStore { func fetchTodaysSteps(completion: @escaping (Int) -> Void) { // HealthKitετΞ͕͋Δ͜ͱΛ֬ೝ guard let healthStore = healthStore else { return } // าλΠϓΛఆٛ͠ɺࠓͷൣғΛઃఆ let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)! let now = Date() let startOfDay = Calendar.current.startOfDay(for: now) // ΫΤϦͷൣғΛઃఆ͢ΔͨΊͷड़ޠΛ༻ let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now, options: .strictStartDate) // าͷ߹ܭΛऔಘ͢ΔͨΊͷΫΤϦΛ࡞ let query = HKStatisticsQuery(quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum) { _, statistics, _ in let steps = statistics?.sumQuantity()?.doubleValue(for: HKUnit.count()) ?? 0 completion(Int(steps)) } // ΫΤϦΛ࣮ߦ healthStore.execute(query) } } -
Reload & Display 3FMPBE struct NumberStepsWatchExtensionEntryView : View { var
entry: Provider.Entry var body: some View { VStack { Text(String(Date().timetoString())) .font(.footnote) Text(String(entry.steps)) } .containerBackground(for: .widget) { Color.white } } } func getTimeline(in context: Context, completion: @escaping (Timeline<StepEntry>) -> ()) { let healthStore = HealthStore() healthStore.fetchTodaysSteps { stepCount in let currentDate = Date() let entries = [ StepEntry(date: currentDate, steps: stepCount) ] // ࣍ͷߋ৽࣌ࠁΛݱࡏ͔Β5ޙʹઃఆ let nextUpdateDate = Calendar.current.date(byAdding: .minute, value: 5, to: currentDate)! let timeline = Timeline(entries: entries, policy: .after(nextUpdateDate)) completion(timeline) } } %JTQMBZ -
I can see it on the main screen now! I
can always see it on my Apple Watch! -
As a result I can always walk over 4,000 steps
a day 🎉 ← 4000 Steps -
Conclusion • It is di ffi cult to achieve exercise
with the goal of health alone. • I enjoy solving my own problems with programming. • Especially for watchOS, there are still very few in the world.