If you have an ethernet cable plugged into your Apple TV, unplug it so the Apple TV is only communicating using Wi-Fi before attempting to pair it with Xcode.
Post
Replies
Boosts
Views
Activity
I think I found the solution. I think it was just a matter of adding a distance sample. Here is a bunch of HealthKit-related code that might help others with similar issues:
import HealthKit
class HealthKitManager: ObservableObject {
private let store = HKHealthStore()
func addWorkout(
workoutType: String,
startTime: Date,
endTime: Date,
distance: Double,
calories: Int
) async throws {
guard let activityType = activityMap[workoutType] else {
throw "no activity type found for \(workoutType)"
}
let preferKM = UserDefaults.standard.bool(forKey: "preferKilometers")
let unit: HKUnit = preferKM ? HKUnit.meter() : HKUnit.mile()
let unitDistance = !distanceWorkouts.contains(workoutType) ?
0 :
(preferKM ? distance * 1000 : distance)
let distanceQuantity = HKQuantity(
unit: unit,
doubleValue: unitDistance
)
let energyBurnedQuantity = HKQuantity(
unit: .largeCalorie(),
doubleValue: Double(calories)
)
let workout = HKWorkout(
activityType: activityType,
start: startTime,
end: endTime,
duration: 0, // compute from start and end data
totalEnergyBurned: energyBurnedQuantity,
totalDistance: distanceQuantity,
metadata: nil
)
try await store.save(workout)
let distanceType = HKObjectType.quantityType(
forIdentifier: .distanceCycling
)!
let distanceSample = HKQuantitySample(
type: distanceType,
quantity: distanceQuantity,
start: startTime,
end: endTime
)
let energyBurnedType = HKObjectType.quantityType(
forIdentifier: .activeEnergyBurned
)!
let energySample = HKQuantitySample(
type: energyBurnedType,
quantity: energyBurnedQuantity,
start: startTime,
end: endTime
)
try await store.addSamples([distanceSample, energySample], to: workout)
}
func authorize(identifiers: [HKQuantityTypeIdentifier]) async throws {
let readSet: Set<HKSampleType> = Set(
identifiers.map { .quantityType(forIdentifier: $0)! }
)
let writeSet: Set<HKSampleType> = [
.quantityType(
forIdentifier: HKQuantityTypeIdentifier.activeEnergyBurned
)!,
.quantityType(
forIdentifier: HKQuantityTypeIdentifier.distanceCycling
)!,
HKWorkoutType.workoutType()
]
try await store.requestAuthorization(toShare: writeSet, read: readSet)
}
func average(
identifier: HKQuantityTypeIdentifier,
unit: HKUnit,
startDate: Date,
endDate: Date
) async throws -> Double {
try await withCheckedThrowingContinuation { completion in
let quantityType = HKQuantityType.quantityType(
forIdentifier: identifier
)!
let predicate: NSPredicate? = HKQuery.predicateForSamples(
withStart: startDate,
end: endDate
)
let query = HKStatisticsQuery(
quantityType: quantityType,
quantitySamplePredicate: predicate,
options: .discreteAverage
) { (_: HKStatisticsQuery, result: HKStatistics?, error: Error?) in
if let error {
completion.resume(throwing: error)
} else {
let quantity: HKQuantity? = result?.averageQuantity()
let result = quantity?.doubleValue(for: unit)
completion.resume(returning: result ?? 0)
}
}
store.execute(query)
}
}
func sum(
identifier: HKQuantityTypeIdentifier,
unit: HKUnit,
startDate: Date,
endDate: Date
) async throws -> Double {
try await withCheckedThrowingContinuation { completion in
let quantityType = HKQuantityType.quantityType(
forIdentifier: identifier
)!
let predicate: NSPredicate? = HKQuery.predicateForSamples(
withStart: startDate,
end: endDate
)
let query = HKStatisticsQuery(
quantityType: quantityType,
quantitySamplePredicate: predicate,
options: .cumulativeSum
) { (_: HKStatisticsQuery, result: HKStatistics?, error: Error?) in
if let error {
completion.resume(throwing: error)
} else {
let quantity: HKQuantity? = result?.sumQuantity()
let result = quantity?.doubleValue(for: unit)
completion.resume(returning: result ?? 0)
}
}
store.execute(query)
}
}
}
It turns out I needed to add a sample to the workout as shown below. But see the comments in the code below about an issue with using the async version of the add method.
let energyBurned = HKQuantity(
unit: .largeCalorie(),
doubleValue: Double(calories)
)
let workout = HKWorkout(
activityType: HKWorkoutActivityType.cycling,
start: startTime,
end: endTime,
duration: 0, // compute from start and end data
totalEnergyBurned: energyBurned,
totalDistance: HKQuantity(unit: .mile(), doubleValue: distance),
metadata: nil
)
try await store.save(workout)
let energyBurnedType = HKObjectType.quantityType(
forIdentifier: HKQuantityTypeIdentifier.activeEnergyBurned
)!
let sample = HKQuantitySample(
type: energyBurnedType,
quantity: energyBurned,
start: startTime,
end: endTime
)
// Says "Missing argument for parameter 'completion' in call".
// await store.add([sample], to: workout)
// Says "Consider using asynchronous alternative version",
// but I tried that above and it doesn't work!
store.add([sample], to: workout) { _, error in
if let error {
print("error adding sample:", error)
}
}
Thank you SO MUCH @MTBff! That solves it for me!
You recommended watching the video "Implementing proactive in-app purchase restore". I've already watched that a few times. I think I'm doing exactly what it recommends and it is not enough to get my app past App Review. My in-app purchase is the simplest possible case. It is a one-time, non-consumable purchase that simply unlocks some functionality in my app. The part of my code that enables making the purchase and unlocking functionality is working perfectly. I just don't have the part to restore previous purchases working. I bet the solution is less than 10 lines of code. It's maddening that I can't find a working example online.
I landed on a solution where I set the background color of the TabView to clear with this:
UITabBar.appearance().backgroundColor = .clear
Then I added a background color that is the color I want for the entire screen, including the TabView with this:
ZStack {
Color.fromJSON(backgroundColor).ignoresSafeArea()
VStack(alignment: .leading) {
content()
.padding(.horizontal)
Spacer() // pushes content to top
}
}
Of course one could position a Color behind only the tab bar to change the background color of just that part of the screen.
I would prefer to use a SwiftUI only approach if there is one. If not, I prefer to use UIKit in the most natural way I can. What would you recommend if I can't require iOS 16 yet? The key requirement is that I need to be able to set the tab bar background color when the app starts AND change it later based on user interaction. Is the answer that it can't be done without iOS 16?
I am hitting the same situation. I understand why it is happening. In my project "Build Settings" I have "Supported Platforms" set to "iOS". But if I change it to "watchOS" then my app no longer builds. I don't know what changes I need to make in my project settings to produce a watchOS binary. I could use suggestions.
Editor ... Vim Mode
This seems to work flawlessly on real devices, so perhaps it is only inconsistent when running in the simulator.
This new project works sometimes. The results are inconsistent. I wonder if there is a timing issue with establishing a connection and sending a message.
I created a new version of the project that is much smaller and exhibits the same issue. See https://github.com/mvolkmann/watch-with-ios-2.
I get the same result regardless of the order in which I start the two apps.
The missing feature I want the most is support for the period key to repeat the last command.
For example, I frequently execute something like "cwfoo" to change the word under the cursor to "foo".
Then I want to move somewhere else in the file and press "." to repeat that command.