Stress App https://www.easten.knight.domains/capstone Mon, 18 Apr 2022 22:10:27 +0000 en hourly 1 https://wordpress.org/?v=5.9.3 Navigation View and Metrics Displays https://www.easten.knight.domains/capstone/uncategorized/navigation-view-and-metrics-displays/ https://www.easten.knight.domains/capstone/uncategorized/navigation-view-and-metrics-displays/#respond Mon, 18 Apr 2022 01:19:56 +0000 https://www.easten.knight.domains/capstone/?p=114 Read MoreNavigation View and Metrics Displays]]> Since my last blog update I’ve learned a lot. First and foremost, I was fortunate to have a few sit-down meetings with the CS professors to look at my code regarding HealthKit queries and the delivery of data from the Health Store. We’ve learned that, at least for heart rate, data is not regularly updated/written to the Health Store, making it difficult to grab an accurate current heart rate from a user. The difference between queries that come back with new data range anywhere from a minute or two to anywhere upwards of 20 minutes. As of right now, I am unaware of a way to force/request the heart rate to be updated.

To acknowledge this in my app, I’ve created a variable that keeps track of the current heart rate and stores its changes in an array of previous heart rates. This array, along with the time of the query at which it got new data, gets displayed on the “Your Health Data” page.

The LandingView file has a NavigationLink that allows the user to Navigate between the StatsView and StressTipsView.

Going forward I want to figure out how to add a breathing animation and also how to animate objects (such as a heart to replicate a heart beat). After that I might try to grab other data such as stand time.


Resources/tutorials I’ve been looking at:

Fetching latest HR (what the majority of my getLatestHR() fcn comes from)

Iterating through arrays (for loop in Swift):

Navigate between views (Navigation Link)

Heart Animation

HKActivitySummaryQuery (from Dr. McVey)

]]>
https://www.easten.knight.domains/capstone/uncategorized/navigation-view-and-metrics-displays/feed/ 0
iOS Application Update https://www.easten.knight.domains/capstone/uncategorized/ios-application-update/ https://www.easten.knight.domains/capstone/uncategorized/ios-application-update/#respond Tue, 29 Mar 2022 22:33:08 +0000 https://www.easten.knight.domains/capstone/?p=106 Read MoreiOS Application Update]]> For some time I was struggling with HealthKit authorization in my iOS application. I kept receiving an error asking me to update my info.plist file. Despite adding (what I thought) was the correct descriptor included I was not able to get around the error. This led me to believe that my info.plist file was set up incorrectly.

I made a new iOS project and followed a tutorial explaining that the info file does not automatically get created in newer versions of Xcode. Instead, there was a work around way to get the file created for you, which then allowed me to add the correct data usage descriptors to the info file.

Now that I know that I should have access to data types such as heart rate and stand time, I need to rewrite the functions that consistently update them. Before, the metrics were updated due to being part of a live workout session. Since the iOS application is not a live session, I’m going to attempt to write a timer function that will consistently make update queries.

]]>
https://www.easten.knight.domains/capstone/uncategorized/ios-application-update/feed/ 0
Spring Break Update https://www.easten.knight.domains/capstone/uncategorized/spring-break-update/ https://www.easten.knight.domains/capstone/uncategorized/spring-break-update/#respond Tue, 22 Mar 2022 00:40:32 +0000 https://www.easten.knight.domains/capstone/?p=100 Read MoreSpring Break Update]]> It’s been a little while since my last update due to Spring Break. I thought that I would be able to do this project entirely as a watchOS application but found this won’t be the case — I’ll have to create a partner iOS application.  This makes sense for multiple reasons such as a watch’s limited screen size (and thus limitation on displayed information) and pushing watch notifications. 

Before spring break I was following some of Apple’s scheduling local notifications documentation to test pushing notifications to users. 

Scheduling a Notification Locally from Your App | Apple Developer Documentation 

https://developer.apple.com/documentation/watchkit/notifications/enabling_and_receiving_notifications

https://developer.apple.com/documentation/usernotifications/asking_permission_to_use_notifications

https://developer.apple.com/documentation/usernotifications/untimeintervalnotificationtrigger

https://www.hackingwithswift.com/example-code/system/how-to-set-local-alerts-using-unnotificationcenter

I had been working on a function “heartRateNotification” that would get called in the heart rate query. In this function I would attempt to display a watch notification saying if a user’s HR was above or below average.

func heartRateNotification() { //left off here..enters but no notification show on watch...
        print("in heartRateNotification..count: \(countHRNotifs)")

        if countHRNotifs == 20{
            print("should send notification to user...")
            let center = UNUserNotificationCenter.current()

            let content = UNMutableNotificationContent()
            content.title = "Stress Update"
            content.subtitle = "Avg HR is: \(self.averageHeartRate)"
            
            if heartRate > averageHeartRate{
                content.body = "current HR \(self.heartRate) above avg!"
            }
            else{
                content.body = "current HR \(self.heartRate) below avg!"
            }
            
        
            content.categoryIdentifier = "alarm"
            content.userInfo = ["customData": "fizzbuzz"]
            content.sound = UNNotificationSound.default

            //deliver notification after specified time interval...60 seconds * 1 for one minute..
            //notification only goes once ...repeats:false
            let trigger = UNTimeIntervalNotificationTrigger(timeInterval: (1*60), repeats: false)

            let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
            center.add(request)
            
            //**EVENTUALLY SOLVE THIS WITH TIME INTERVAL/REPEATS on timeintervalnotification trigger
            countHRNotifs = 0 //reset count to space out notifications user gets
        }
        else{
            countHRNotifs += 1 //work way back up to 20
        }
        
    }//end heartRateNotification
case HKQuantityType.quantityType(forIdentifier: .heartRate):
                let heartRateUnit = HKUnit.count().unitDivided(by:   HKUnit.minute())
                self.heartRate = statistics.mostRecentQuantity()?.doubleValue(for: heartRateUnit) ?? 0
                self.averageHeartRate = statistics.averageQuantity()?.doubleValue(for: heartRateUnit) ?? 0
                print("curr HR: \(self.heartRate)")
                self.heartRateNotification() //call to notification fcn!

 I was unable to get any notifications to appear…my thoughts on this are that the documentation I was following was for pushing notifications on an iOS device and not a watch. To test this, I’m going to create an iOS application that is paired with the watch app and see if I am able to get notifications to show. If this does not work there may simply be an error in my code, or I will need to attempt to use Apple Push Notifications (APNs).   

Registering Your App with APNs | Apple Developer Documentation 

However, APN requires a server and may involve a lot of unnecessary work.  Instead, I could idealistically utilize the iOS app and use it to display metrics gathered from my watch application’s session and give appropriate feedback/suggestions from there.  

A lot of these thoughts are just speculating on what’s next, so for now I’ll take it one step at a time. No matter what I’d like to create an iOS application to display not only metrics but also tips about stress information and suggestions on what to do in stressful scenarios.  Getting push notifications to work with an app would be a nice add-on to this. 

]]>
https://www.easten.knight.domains/capstone/uncategorized/spring-break-update/feed/ 0
Metrics Update https://www.easten.knight.domains/capstone/uncategorized/metrics-update/ https://www.easten.knight.domains/capstone/uncategorized/metrics-update/#respond Thu, 10 Mar 2022 01:19:23 +0000 https://www.easten.knight.domains/capstone/?p=95 Read MoreMetrics Update]]> On Sunday I finally made a small breakthrough with my project. After staring at my WorkoutManager for some time I realized that the reason I could not display the amount of distance a user had travelled was simply because I never asked from that data from HealthKit. In order to read/write data, I created a set of  HealthKit data types such as .heartRate, .activeEnergyBurned, etc but did not ask for .distanceWalkingRunning. After including this last data type in my read set I am now able to display the distance a user travels in a session.  

I was having some problems with updating values such as step count, supposedly because the update requests to display the live data resides in a switch case. To go around the possibility of never reaching an update value request, I wrote a getStepCount function that gets called in the case for updating a user’s distance travelled and am able to display an accurate-ish step count that correlates to a user’s distance travelled. 

Now that I have an idea of how to display and look at data, my next steps are to start getting into the stress side of the project. To start, my goal is to learn how to push notifications to a user based on heart rate. Apple has a series of HKQuantitiyTypeIdentifiers relating to heartRate: lowHeartRate, highHeartRate, irregularHeartRhythmEvent, and restingHeartRate.

I’d like to write a function that gets placed in the active heart rate update case that compares/utilizes these identifiers to see if a user is stressed. Eventually I’d like to pair this analysis with other identifiers that look at bloodPressure and respiratoryRate. Typical health identifiers such as AppleExerciseTime or AppleStandTime may also be nice to utilize as gentle reminders to users to get up and move around in a time period. 

Although I’m not quite sure how any of this data looks coming in/what statistics I’ll need to compare live data to, I think this will be a good starting place for giving stress suggestions. 

]]>
https://www.easten.knight.domains/capstone/uncategorized/metrics-update/feed/ 0
Screens, Metrics, and Logs! https://www.easten.knight.domains/capstone/uncategorized/screens-metrics-and-logs/ https://www.easten.knight.domains/capstone/uncategorized/screens-metrics-and-logs/#respond Mon, 28 Feb 2022 16:14:55 +0000 https://www.easten.knight.domains/capstone/?p=79 Read MoreScreens, Metrics, and Logs!]]> After a slow week I finally made some progress over this last weekend. I found out that a chunk of the code/examples I had been following in this 2021 Apple Developer Workout tutorial had been depreciated/updated after looking at some project source code. I spent some time going through my project and making the necessary updates — particularly to my Views and to my WorkoutManger files. After running the app through my iPhone (connected to my computer) I was able to start a session, see the metrics view/controls view/now playing view (all setup through session paging view), and finally save a workout through the summaryView.

Starting a session, being able to pause/resume a session, and move through the different screens

See that we have a working time count, calorie count, and heart rate. Finally, after a session is ended we get to see a summary.

Currently the Metrics View still needs some work. I have been unable to successfully measure distance traveled or steps taken by a user. My plans for the upcoming week are to continue debugging to find out how to successfully request/update these values in order to grab other data that is more related this project. For example, once I can successfully grab and step counts I know I will be able to look at other data such as respiratory rate and stand time.

On Sunday night I was able to successfully able to log metrics values that were working such as heart rate. The log, paired with other documentation will hopefully help me grab other data correctly.

The log shows the progression of calories burned during the session, with the ending value being 5
]]>
https://www.easten.knight.domains/capstone/uncategorized/screens-metrics-and-logs/feed/ 0
Progress Update https://www.easten.knight.domains/capstone/uncategorized/progress-update/ https://www.easten.knight.domains/capstone/uncategorized/progress-update/#respond Mon, 21 Feb 2022 05:22:27 +0000 https://www.easten.knight.domains/capstone/?p=75 Read MoreProgress Update]]> I’ve been working on implementing a version of my StressApp with the metrics I’d like to display to the user. The tutorials I’ve followed in the past were helpful in showing how to request user data and making queries for the data I would like to read (and later display) to the user. However, I’ve run into a problem with the Navigation of the screen and have been unsuccessful in going from the Start View to the SessionPagingView (the view a user will see with their metrics along with some controls to pause/stop the session).

My plan for going forward to go back and reference the old tutorials I did and maybe look for some example code to figure out if I missed something here. Once I get this figured out I plan to start working on displaying live metrics on the MetricsView tab of the SessionPagingView.

Issues with the NavigationLink here…can’t quite figure out how to get the destination/Tag to actually go to SessionPagingView

]]>
https://www.easten.knight.domains/capstone/uncategorized/progress-update/feed/ 0
A Slow Week https://www.easten.knight.domains/capstone/uncategorized/a-slow-week/ https://www.easten.knight.domains/capstone/uncategorized/a-slow-week/#respond Mon, 14 Feb 2022 04:24:37 +0000 https://www.easten.knight.domains/capstone/?p=67 Read MoreA Slow Week]]> Progress was slow this week, I looked for some tutorials that would show me how to display a user’s active metrics and came across some tutorials by Apple for WWDC going through some introductory HealthKit information. The Getting Started with HealthKit tutorial is paired with a sample code project called Smooth Walker that I’ve been looking through to see how to display different screens. Although the tutorial was made for a phone application, I’m hoping to use it as a model of sorts for the watch app I create.

Here’s another basic example I found on GitHub.

Although I haven’t quite figured out the live metrics thing, I’m hoping to just dive straight into making a watch app and with some trial and error figure things out.

]]>
https://www.easten.knight.domains/capstone/uncategorized/a-slow-week/feed/ 0
A Tiny Success! https://www.easten.knight.domains/capstone/uncategorized/a-tiny-success/ https://www.easten.knight.domains/capstone/uncategorized/a-tiny-success/#respond Wed, 09 Feb 2022 01:15:20 +0000 https://www.easten.knight.domains/capstone/?p=58 Read MoreA Tiny Success!]]> The tutorial I had originally been following was taken down from YouTube so I had to a new one that would guide me through the process of accessing a user’s data from HealthKit. I found a tutorial about counting steps using HealthKit that took me just a few hours to complete.

One of the most important things I learned from this tutorial was how to generate a query using HKStatisticsCollection. The query takes a quantity type (this will be the type of metric I request from the user), a predicate (a time range to grab data from…this tutorial looks at the last seven days from the current date), and a few other things. I ideally want to grab data consistently so I’ll be looking into how to actively grab data (probably by having an app that can run in the background?).

The way the code comes together is pretty neat. Essentially there’s a struct “Step” that contains a UUID, step count, and date. In the ContentView file (what the user will see) we create a Step array called “steps” that saves Step instances when initialized. The “body” of the watch screen then gets a steps List and displays them in a VStack.


By connecting my phone to my laptop I was able to run the application on my watch. In order to access step count data I again had to request authorization from the user.

Opens to another screen asking what data to share (in this case only “steps” are requested, but the user has the ability to select all available data options or particular ones.
Doesn’t show much but we can see dates and step counts!
In the video above we can see that on the current date (February 8) I had 4,848 steps. I compared this to the steps I saw on my phone’s health app (along with the other dates) and found them to be the same…nice!
]]>
https://www.easten.knight.domains/capstone/uncategorized/a-tiny-success/feed/ 0
Week 2 https://www.easten.knight.domains/capstone/uncategorized/week-2/ https://www.easten.knight.domains/capstone/uncategorized/week-2/#respond Mon, 07 Feb 2022 04:56:02 +0000 https://www.easten.knight.domains/capstone/?p=54 Read MoreWeek 2]]> My goal for this week was originally to finish the video tutorial I’ve been following to practice Swift/SwiftUI for Apple Watch app development. I ran in to a bit of a delay about half way through the tutorial when it came to accessing HealthKit data. Dr. McVey was lots of help with this and set up an Apple Developer license for me to use, which grants me access to the HealthKit framework. It took a few days for this license to register so my progress was paused for a little bit. After the license was confirmed it then took me a little longer than anticipated to figure out the project’s bundle name. Although the code I had was error-free, I was unable to compile due to some project-naming errors.

One of the errors I kept running into that prohibited me from running a Series 7 watch simulator

After a lot of digging online (and some closer reading of the error), I finally came across an article that lead me to resolving the issue!

Video of the current app running, basically showing that we can attempt to track user’s health data with their permission!

With this progress I hope to finish the video tutorial early this week. I’d also like to try running the app on an actual watch too.

]]>
https://www.easten.knight.domains/capstone/uncategorized/week-2/feed/ 0
Starting Swift https://www.easten.knight.domains/capstone/uncategorized/starting-swift/ https://www.easten.knight.domains/capstone/uncategorized/starting-swift/#respond Wed, 02 Feb 2022 05:14:39 +0000 https://www.easten.knight.domains/capstone/?p=32 Read MoreStarting Swift]]> To get started I decided to follow a video tutorial on Youtube that walks through setting up a workout app on an Apple Watch. For this, I am building a Watch App on XCode using Swift/SwiftUI. Apple provides WatchKit and HealthKit imports, which are framework imports specifically designed to develop content for Apple Watches.

The tutorial was really helpful for starting to create screens and learn some of the specifics of Swift (I think it might take me a minute to fully grasp the syntax of Swift), as well as learn some of the features of HealthKit and WatchKit. HeathKit in particular is interesting because it will provide access to user health data — through it you are able to request that data such as current BPM or calories burned are communicated with your watch application.

Inside of the WorkoutManager File we wrote a “request authorization” function to grab information from the healthStore

Here is where I ran into my first issue: needing a developer account in order to access HealthKit data. In order to continue testing this I’ll need to sign up for the Apple Developer Program.

Below is a live preview of what the “SummaryView” of a workout would look like. Each subsection you see is a SummaryMetricView containing a title (TextView) and some sort of value that will eventually reflect user data instead of default values.

Inside of SessionPagingView…when inside of an active workout, there are 3 active tabs:
ControlsView().tag(Tab.controls), MetricsView().tag(Tab.metrics), NowPlayingView().tag(Tab.nowPlaying) 

]]>
https://www.easten.knight.domains/capstone/uncategorized/starting-swift/feed/ 0