I'm implementing an App Intent for my iOS app that helps users plan trip activities. It only works when run as a shortcut but not using voice through Siri. There are 2 issues:
The ShortcutsTripEntity will only accept a voice input for a specific trip but not others.
I'm stuck with a throwing error when trying to use requestDisambiguation() on the activity day @Parameter property.
How do I rectify these issues.
This is blocking me from completing a critical feature that lets users quickly plan activities through Siri and Shortcuts.
Expected behavior for trip input: The intent should make Siri accept the spoken trip input from any of the options.
Actual behavior for trip input: Siri only accepts the same trip when spoken but accepts any when selected by click/touch.
Expected behavior for day input: Siri should accept the spoken selected option.
Actual behavior for day input: Siri only accepts an input by click/touch but yet throws an error at runtime I'm happy to provide more code. But here's the relevant code:
struct PlanActivityTestIntent: AppIntent {
@Parameter(title: "Activity Day")
var activityDay: ShortcutsItineraryDayEntity
@Parameter(
title: "Trip",
description: "The trip to plan an activity for",
default: ShortcutsTripEntity(id: UUID().uuidString, title: "Untitled trip"),
requestValueDialog: "Which trip would you like to add an activity to?"
)
var tripEntity: ShortcutsTripEntity
@Parameter(title: "Activity Title", description: "The title of the activity", requestValueDialog: "What do you want to do or see?")
var title: String
@Parameter(title: "Activity Day", description: "Activity Day", default: ShortcutsItineraryDayEntity(itineraryDay: .init(itineraryId: UUID(), date: .now), timeZoneIdentifier: "UTC"))
var activityDay: ShortcutsItineraryDayEntity
func perform() async throws -> some ProvidesDialog {
// ...other code...
let tripsStore = TripsStore()
// load trips and map them to entities
try? await tripsStore.getTrips()
let tripsAsEntities = tripsStore.trips.map { trip in
let id = trip.id ?? UUID()
let title = trip.title
return ShortcutsTripEntity(id: id.uuidString, title: title, trip: trip)
}
// Ask user to select a trip. This line would doesn't accept a voice // answer. Why?
let selectedTrip = try await $tripEntity.requestDisambiguation(
among: tripsAsEntities,
dialog: .init(
full: "Which of the \(tripsAsEntities.count) trip would you like to add an activity to?",
supporting: "Select a trip",
systemImageName: "safari.fill"
)
)
// This line throws an error
let selectedDay = try await $activityDay.requestDisambiguation(
among: daysAsEntities,
dialog:"Which day would you like to plan an activity for?"
)
}
}
Here are some related images that might help:
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm currently testing subscriptions in Sandbox. In AppstoreConnect, I set a grace period of 3 days. I subscribed for a service which expired and now it's inBillingRetryPeriod state. I thought it had to do with my payment method. After updating my payment method, it still remains in that state. I checked Status.RenewalInfo's gracePeriodExpiration and expirationReason values but both produced nil. How do I exit the inBillingRetry state? I'm new to in-app purchases. Thanks. Here's the relevant code that updates subscription status:
@MainActor
func updateSubscriptionStatus() async {
do {
guard let product = storeManager.renewables.first,
let statuses = try await product.subscription?.status else {return}
var highestProduct: Product? = nil
var highestStatus: Product.SubscriptionInfo.Status? = nil
for status in statuses {
switch status.state {
case .expired, .revoked:
continue
default:
let verifiedRenewalInfo = try storeManager.checkVerified(status.renewalInfo)
//Find the first subscription in the store that matches id on the `status.renewalInfo`
guard let newSubscription = storeManager.renewables.first(where: {$0.id == verifiedRenewalInfo.autoRenewPreference}) else { continue }
guard let currentProduct = highestProduct else {
highestProduct = newSubscription
highestStatus = status
// next status
continue
}
let currentProductTier = storeManager.tierDuration(for: currentProduct.id)
let newTier = storeManager.tierDuration(for: newSubscription.id)
if newTier > currentProductTier {
//updated product and status
highestProduct = newSubscription
highestStatus = status
}
}
}
currentSubscription = highestProduct // currentSubscription is an @State
status = highestStatus // status is an @State
if let mySubcriptionStatus = status,
case .verified(let renewalInfo) = highestStatus?.renewalInfo {
print(mySubcriptionStatus.state) //
StoreKit.Product.SubscriptionInfo.RenewalState(rawValue: 3))-- inBillingRetry.
print(renewalInfo.expirationReason) // nil
print(renewalInfo.gracePeriodExpirationDate) // nil
}
} catch {
print(error)
}
}
I'm currently testing subscriptions in Sandbox. In AppstoreConnect, I set a grace period of 3 days. I subscribed for a service which expired and now it's inBillingRetryPeriod state. I thought it had to do with my payment method. After updating my payment method, it still remains in that state. I am checking Status.RenewalInfo's gracePeriodExpiration and expirationReason values produce nil. How do I exit the inBillingRetry state? I'm new to in-app purchases. Thanks. Here's the relevant code:
...
@MainActor
func updateSubscriptionStatus() async {
do {
guard let product = storeManager.renewables.first,
let statuses = try await product.subscription?.status else {return}
var highestProduct: Product? = nil
var highestStatus: Product.SubscriptionInfo.Status? = nil
for status in statuses {
switch status.state {
case .expired, .revoked:
continue
default:
let verifiedRenewalInfo = try storeManager.checkVerified(status.renewalInfo)
//Find the first subscription in the store that matches id on the `status.renewalInfo`
guard let newSubscription = storeManager.renewables.first(where: {$0.id == verifiedRenewalInfo.autoRenewPreference}) else { continue }
guard let currentProduct = highestProduct else {
highestProduct = newSubscription
highestStatus = status
// next status
continue
}
let currentProductTier = storeManager.tierDuration(for: currentProduct.id)
let newTier = storeManager.tierDuration(for: newSubscription.id)
if newTier > currentProductTier {
//updated product and status
highestProduct = newSubscription
highestStatus = status
}
}
}
currentSubscription = highestProduct // currentSubscription is an @State
status = highestStatus // status is an @State
if let mySubcriptionStatus = status,
case .verified(let renewalInfo) = highestStatus?.renewalInfo {
print(mySubcriptionStatus.state) // StoreKit.Product.SubscriptionInfo.RenewalState(rawValue: 3) -- inBillingRetry
print(renewalInfo.expirationReason) // nil
print(renewalInfo.gracePeriodExpirationDate) // nil
}
} catch {
print(error)
}
}
Hi. I have spent some time on the Apple Music API docs on how to list songs by genre but can't find it. How can I use the API to list songs that belong to a genre e.g rock? The search endpoint is close but I can't limit it to a genre. Thanks in advance.