In the watchOS Fitness app, when you change your goals using the Digital Crown, a focus ring appears around the stepper. Something I can't understand is how the green focus ring is not centered around the stepper buttons (which is the default behavior). Furthermore, I don't understand how the goal text and captions inside the stepper label are also not centered within the stepper.
A final behavior I don't understand is when the goal number transitions from 999 to 1000, the stepper changes height, but doesn't affect the height of any parent views.
import SwiftUI
struct ContentView: View {
@State private var value = 999.0
var body: some View {
VStack {
Text("MOVE GOAL")
.font(.subheadline)
.foregroundStyle(.red)
.padding(.top)
Stepper {
VStack {
Text("\(Int(value))")
.allowsTightening(true)
.minimumScaleFactor(value > 999 ? 0.70 : 1.0)
.lineLimit(1)
Text("CALORIES")
.font(.subheadline)
.foregroundStyle(.red)
}
} onIncrement: {
value += 1
} onDecrement: {
value -= 1
}
.tint(.red)
.digitalCrownRotation(
$value,
from: 1,
through: 9999,
by: 1,
sensitivity: .high,
isContinuous: false,
isHapticFeedbackEnabled: true
)
Button {
print("added")
} label: {
Text("Set")
.foregroundStyle(.black)
}
.tint(.red)
.buttonStyle(.borderedProminent)
.padding(.top)
}
}
}
This is the code I've been able to get as close as possible without delving into GeometryReader, where I've had zero luck modifying the positioning of the label within the stepper.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Why doesn’t deinit support async? At the end of a test, I want to wipe data from HealthKit, and it’s delete function is asynchronous.
I've been trying to figure out what the bare minimum is required for HKWorkoutBuilder to create a workout that adds time the appleExerciseTime. I couldn't find the documentation for this. This is my code so far.
func createWorkoutSample(
expectedActiveEnergyData: [Double],
expectedExerciseMinutesData: [Double],
calendar: Calendar,
startDate: Date
) async throws -> [HKSample] {
var testData: [HKSample] = []
let workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
let results = try await withThrowingTaskGroup(of: HKSample?.self) { group in
for (index) in 0..<expectedActiveEnergyData.count {
guard let date = calendar.date(byAdding: .day, value: index, to: startDate) else {
continue
}
group.addTask {
let builder = HKWorkoutBuilder(
healthStore: self.manager.healthStore,
configuration: workoutConfiguration,
device: .local()
)
let endDate = date.addingTimeInterval(expectedExerciseMinutesData[index] * 60)
try await builder.beginCollection(at: date)
let energyType = HKQuantityType.quantityType(
forIdentifier: .activeEnergyBurned
)!
let energyQuantity = HKQuantity(
unit: HKUnit.kilocalorie(),
doubleValue: expectedActiveEnergyData[index]
)
let energySample = HKQuantitySample(
type: energyType,
quantity: energyQuantity,
start: date,
end: endDate
)
return try await withCheckedThrowingContinuation { continuation in
builder.add([energySample]) { (success, error) in
if let error = error {
continuation.resume(throwing: error)
return
}
builder.endCollection(withEnd: endDate) { (success, error) in
if let error = error {
continuation.resume(throwing: error)
return
}
builder.finishWorkout { (workout, error) in
if let error = error {
continuation.resume(throwing: error)
return
}
continuation.resume(returning: workout)
}
}
}
}
}
}
for try await workout in group {
if let workout = workout {
testData.append(workout)
} else {
print("Skipping nil workout result.")
}
}
return testData
}
print("Total samples created: \(results.count)")
return results
}
When I query appleExerciseTime, there are no results. I've looked at the HKWorkoutBuilder documentation, and most of the information expands on adding samples related to the deprecated HKWorkout.
I'm dealing with a strange bug where I am requesting read access for 'appleExerciseTime' and 'activitySummaryType', and despite enabling both in the permission sheet, they are being set to 'sharingDenied'.
I'm writing a Swift Test for making sure permissions are being granted.
@Test
func PermissionsGranted() {
try await self.manager.getPermissions()
for type in await manager.allHealthTypes {
let status = await manager.healthStore.authorizationStatus(for: type)
#expect(status == .sharingAuthorized, "\(type) authorization status is \(status)")
}
}
let healthTypesToShare: Set<HKSampleType> = [
HKQuantityType(.bodyMass),
HKQuantityType(.bodyFatPercentage),
HKQuantityType(.leanBodyMass),
HKQuantityType(.activeEnergyBurned),
HKQuantityType(.basalEnergyBurned),
HKObjectType.workoutType()
]
let allHealthTypes: Set<HKObjectType> = [
HKQuantityType(.bodyMass),
HKQuantityType(.bodyFatPercentage),
HKQuantityType(.leanBodyMass),
HKQuantityType(.activeEnergyBurned),
HKQuantityType(.basalEnergyBurned),
HKQuantityType(.appleExerciseTime),
HKObjectType.activitySummaryType()
]
let healthStore = HKHealthStore()
func getPermissions() async throws {
try await healthStore.requestAuthorization(toShare: self.healthTypesToShare, read: self.allHealthTypes)
}
After 'getPermissions' runs, the permission sheet shows up on the Simulator, and I accept all. I've double checked that the failing permissions show up on the sheet and are enabled. Then the test fails with:
Expectation failed: (status → HKAuthorizationStatus(rawValue: 1)) == (.sharingAuthorized → HKAuthorizationStatus(rawValue: 2)) HKActivitySummaryTypeIdentifier authorization status is HKAuthorizationStatus(rawValue: 1)
Expectation failed: (status → HKAuthorizationStatus(rawValue: 1)) == (.sharingAuthorized → HKAuthorizationStatus(rawValue: 2)) HKActivitySummaryTypeIdentifier authorization status is HKAuthorizationStatus(rawValue: 1)
With the rawValue of '1' being 'sharingDenied'. All other permissions are granted. Is there a workaround here, or something I'm potentially doing wrong?
Does Swift Testing support using ‘any’ values as parameters like seen here for ‘any ChartDataPoint.Type’
@Test(arguments: [
(expectedBodyFatValues,
HKQuantityTypeIdentifier.bodyFatPercentage,
HKUnit.percent(),
BodyFatPoint.self),
(expectedActiveEnergyValues,
HKQuantityTypeIdentifier.activeEnergyBurned,
HKUnit.kilocalorie(),
ActiveCaloriesPoint.self),
(expectedBodyMassValues,
HKQuantityTypeIdentifier.bodyMass,
HKUnit.pound(),
BodyMassPoint.self),
(expectedBasalEnergyValues,
HKQuantityTypeIdentifier.basalEnergyBurned,
HKUnit.kilocalorie(),
BasalEnergyPoint.self)
])
func healthKitDataReading(
expectedData: [Double],
identifier: HKQuantityTypeIdentifier,
unit: HKUnit,
dataChartType: any ChartDataPoint.Type
) async throws {...}
Currently I can’t get this code to work, and see the error
… Conflicting arguments to generic parameter 'C' ('[([Double], HKQuantityTypeIdentifier, HKUnit, BodyFatPoint.Type)]' vs. '[([Double], HKQuantityTypeIdentifier, HKUnit, ActiveCaloriesPoint.Type)]' vs. '[([Double], HKQuantityTypeIdentifier, HKUnit, BodyMassPoint.Type)]' vs. '[([Double], HKQuantityTypeIdentifier, HKUnit, BasalEnergyPoint.Type)]')
Also, I can’t seem to use variables like ‘expectedBodyFatValues’ due to the error
Instance member 'expectedBodyFatValues' cannot be used on type 'Health_Mix_Swift_Tests'; did you mean to use a value of this type instead?
Only way I’ve found around this is including the entire array of values as the parameter, but it’s very cumbersome.