Skip to content

Commit

Permalink
Prep for publishing
Browse files Browse the repository at this point in the history
  • Loading branch information
aritchie committed Aug 28, 2023
1 parent d8d3a83 commit 9bad260
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 76 deletions.
66 changes: 36 additions & 30 deletions Sample/HealthTestViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@
namespace Sample;


public class HealthTestViewModel : FuncViewModel
public class HealthTestViewModel : ViewModel
{
readonly IDeviceDisplay display;


public HealthTestViewModel(
BaseServices services,
IDeviceDisplay display,
IHealthService health
) : base(services)
{
this.display = display;

this.Load = ReactiveCommand.CreateFromTask(async () =>
{
var result = await health.RequestPermission(
Expand Down Expand Up @@ -48,35 +53,6 @@ IHealthService health
this.HeartRate = (await health.Query(HeartRateHealthMetric.Default, start, end, Interval.Days)).Average(x => x.Value);
});
this.BindBusyCommand(this.Load);

this.NavTo = async (_, _) =>
{
display.KeepScreenOn = true;
this.DeactivateWith.Add(Disposable.Create(() => display.KeepScreenOn = false));
this.Start = DateOnly.FromDateTime(DateTime.Now.AddDays(-1));
this.End = DateOnly.FromDateTime(DateTime.Now);
this.WhenAnyValue(x => x.Start)
.Skip(1)
.Subscribe(_ => this.Load.Execute(null))
.DisposedBy(this.DeactivateWith);
this.WhenAnyValue(x => x.End)
.Skip(1)
.Subscribe(_ => this.Load.Execute(null))
.DisposedBy(this.DeactivateWith);
//this.Load.Execute(null);
//this.Monitors = new List<MonitorViewModel>
//{
// new MonitorViewModel("Steps (total)", health.MonitorSteps().RunningAccumulation().Select(x => x.ToString())),
// new MonitorViewModel("Calories (total)", health.MonitorCalories().RunningAccumulation().Select(x => x.ToString())),
// new MonitorViewModel("Distance (total)", health.MonitorDistance().RunningAccumulation().Select(x => x.ToString())),
// new MonitorViewModel("Heart Rate (bpm)", health.MonitorHeartRate().Select(x => x.ToString()))
//};
//this.Monitors.ForEach(disp.Add);
};
}


Expand All @@ -91,6 +67,36 @@ IHealthService health
[Reactive] public double HeartRate { get; private set; }

//[Reactive] public List<MonitorViewModel> Monitors { get; private set; }

public override void OnAppearing()
{
base.OnAppearing();
display.KeepScreenOn = true;
this.DeactivateWith.Add(Disposable.Create(() => display.KeepScreenOn = false));

this.Start = DateOnly.FromDateTime(DateTime.Now.AddDays(-1));
this.End = DateOnly.FromDateTime(DateTime.Now);

this.WhenAnyValue(x => x.Start)
.Skip(1)
.Subscribe(_ => this.Load.Execute(null))
.DisposedBy(this.DeactivateWith);

this.WhenAnyValue(x => x.End)
.Skip(1)
.Subscribe(_ => this.Load.Execute(null))
.DisposedBy(this.DeactivateWith);

//this.Load.Execute(null);
//this.Monitors = new List<MonitorViewModel>
//{
// new MonitorViewModel("Steps (total)", health.MonitorSteps().RunningAccumulation().Select(x => x.ToString())),
// new MonitorViewModel("Calories (total)", health.MonitorCalories().RunningAccumulation().Select(x => x.ToString())),
// new MonitorViewModel("Distance (total)", health.MonitorDistance().RunningAccumulation().Select(x => x.ToString())),
// new MonitorViewModel("Heart Rate (bpm)", health.MonitorHeartRate().Select(x => x.ToString()))
//};
//this.Monitors.ForEach(disp.Add);
}
}

/*
Expand Down
8 changes: 4 additions & 4 deletions Sample/Sample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="5.2.0" />
<PackageReference Include="CommunityToolkit.Maui" Version="5.3.0" />
<PackageReference Include="Prism.DryIoc.Maui" Version="8.1.273-pre" />
<PackageReference Include="ReactiveUI.Fody" Version="19.2.1" />
<PackageReference Include="Shiny.Framework" Version="3.0.0-beta-0008" />
<PackageReference Include="ReactiveUI.Fody" Version="19.4.1" />
<PackageReference Include="Shiny.Framework" Version="3.0.0-beta-0010" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
<PackageReference Include="AiForms.Maui.SettingsView" Version="0.1.21-pre" />
<PackageReference Include="AiForms.Maui.SettingsView" Version="0.1.23-pre" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions Shiny.Health/Shiny.Health.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
<None Include="..\nuget.txt" Pack="true" PackagePath="readme.txt" />
<None Include="..\readme.md" Pack="true" PackagePath="\" />

<PackageReference Include="NerdBank.GitVersioning" Version="3.5.109" PrivateAssets="All" />
<PackageReference Include="NerdBank.GitVersioning" Version="3.6.133" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<None Include="Platforms\**\*.cs" />
<Compile Remove="Platforms\**\*.cs" />

<PackageReference Include="Shiny.Core" Version="3.0.0-beta-0179" />
<PackageReference Include="Shiny.Core" Version="3.0.0-beta-0282" />
<!--<PackageReference Include="UnitsNet" Version="5.0.0-rc004" />-->
</ItemGroup>

Expand Down
118 changes: 78 additions & 40 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,81 @@
# Shiny Health

## iOS
Apple Health and Google Fit for your .NET7+ .NET Mobile apps

## Features
* Read summary values between timestamps and specified interval
* Query distance, step count, calory intake, & heart rate
* TODO: Write values

## How To Use

```csharp
IHealthService health; // inject, resolve, etc
// request permissions
var result = await health.RequestPermission(
new Permission(DistanceHealthMetric.Default, PermissionType.Read),
new Permission(CaloriesHealthMetric.Default, PermissionType.Read),
new Permission(StepCountHealthMetric.Default, PermissionType.Read),
new Permission(HeartRateHealthMetric.Default, PermissionType.Read)
);
if (!result)
{
// say something useful
}

var end = DateTimeOffset.Now;
var start = DateTimeOffset.Now.AddDays(-1);

// now run your queries
var distance = (await health.Query(DistanceHealthMetric.Default, start, end, Interval.Days)).Sum(x => x.Value);
var calories = (await health.Query(CaloriesHealthMetric.Default, start, end, Interval.Days)).Sum(x => x.Value);
var steps = (await health.Query(StepCountHealthMetric.Default, start, end, Interval.Days)).Sum(x => x.Value);
var heartRate = (await health.Query(HeartRateHealthMetric.Default, start, end, Interval.Days)).Average(x => x.Value);
```

## Setup

### MAUI

Install Shiny.Health from [![NuGet](https://img.shields.io/nuget/v/Shiny.Health.svg?maxAge=2592000)](https://www.nuget.org/packages/Shiny.Health/)

Now, in your MauiProgram.cs, add:

```cshar
public static MauiApp CreateMauiApp()
{
var builder = MauiApp
.CreateBuilder()
.UseShiny()
.UseMauiApp<App>()
.UseShinyFramework(
new DryIocContainerExtension(),
prism => prism.OnAppStart("NavigationPage/HealthTestPage")
)
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
builder.Services.AddHealthIntegration();
return builder.Build();
}
```

### iOS

To use iOS (and therefore the sample), you need to have a provisioning profile with all
of the necessary Apple Health setup for your application.

Take a look at the Xamarin docs for [more info](https://learn.microsoft.com/en-us/xamarin/ios/platform/healthkit)

Add the following:

#### Info.plist

Info.plist
```xml
<key>UIRequiredDeviceCapabilities</key>
<string>healthkithealthkit</string>
Expand All @@ -12,49 +85,14 @@ Info.plist
<string>We need to say something useful here</string>
```

Entitlements.plist
#### Entitlements.plist
```xml
<key>com.apple.developer.healthkit</key>
<true />
<key>com.apple.developer.healthkit.background-delivery</key>
<true />
```

FitBit
https://vipin-johney.medium.com/fitbit-authentication-xamarin-forms-5900ed8e9caa
https://dev.fitbit.com/


Google Fit

Activity: This captures any activity that a user does. It can include health and fitness activities like running or swimming, meditation, and sleep.
Body Measurement: This captures common data related to the body. It includes capturing a user’s weight, or a user’s basal metabolic rate, among other data types.
Cycle Tracking: This captures menstrual cycles and related data points, such as the binary result of an ovulation test.
Nutrition: This captures hydration and nutrition data types. The former represents how much water a user drank in a single drink. The latter includes many optional fields, from calories to sugar and magnesium that record which nutrients the user consumed.
Sleep: This captures interval data related to a user’s length and type of sleep.
Vitals: This captures essential information about the user’s general health. It includes everything from blood glucose to body temperature and blood oxygen saturation.

https://developer.android.com/guide/health-and-fitness/health-connect


Apple Health

https://learn.microsoft.com/en-us/xamarin/ios/platform/healthkit


Watch Heart Rate and start workout
https://developer.apple.com/forums/thread/6549

* Subscribe to updates
HealthKit - HKStatisticsQuery - InitialHandler vs UpdateHandler for subscriptions
https://stackoverflow.com/questions/30306653/google-fit-add-activity-programmatically
https://stackoverflow.com/questions/58777453/reading-the-heart-rate-from-wear-os-watch-using-google-fit-from-a-paired-app

https://developers.google.com/fit/android/sensors

#### Google Fit

An explicit App ID.
A Provisioning Profile associated with that explicit App ID and with Health Kit permissions.
An Entitlements.plist with a com.apple.developer.healthkit property of type Boolean set to Yes.
An Info.plist whose UIRequiredDeviceCapabilities key contains an entry with the String value healthkit.
The Info.plist must also have appropriate privacy-explanation entries: a String explanation for the key NSHealthUpdateUsageDescription if the app is going to write data and a String explanation for the key NSHealthShareUsageDescription if the app is going to read Health Kit data.
[Official Android Documentation](https://developer.android.com/guide/health-and-fitness/health-connect)

0 comments on commit 9bad260

Please sign in to comment.