Post

Replies

Boosts

Views

Activity

How to inject parameter dependency at runtime in iOS App Intent
I am trying to create an App Intent that lets a user select a day in the itinerary of a trip. The trip has to be chosen before the days available can be displayed. When the PlanActivityIntentDemo intent is ran from the shortcuts app, the trip selected is not injected into the appropriate TripItineraryDayQueryDemo Entity Query. Is there a way to get the selected trip to be injected at run time from shortcuts app. Here's some code for illustration: // Entity Definition: import AppIntents struct ShortcutsItineraryDayEntityDemo: Identifiable, Hashable, AppEntity { typealias DefaultQuery = TripItineraryDayQueryDemo static var typeDisplayRepresentation: TypeDisplayRepresentation = "Trip Itinerary Day" var displayRepresentation: DisplayRepresentation { "Trip Day" } var id: String static var defaultQuery: DefaultQuery { TripItineraryDayQueryDemo() } init() { self.id = UUID().uuidString } } struct TripItineraryDayQueryDemo: EntityQuery { // This only works in shortcut editor but not at runtime. Why? How can I fix this issue? @IntentParameterDependency<PlanActivityIntentDemo>(\.$tripEntity) var tripEntity @IntentParameterDependency<PlanActivityIntentDemo>(\.$title) var intentTitle func entities(for identifiers: [ShortcutsItineraryDayEntityDemo.ID]) async throws -> [ShortcutsItineraryDayEntityDemo] { print("entities being called with identifiers: \(identifiers)") // This method is called when the app needs to fetch entities based on identifiers. let tripsStore = TripsStore() guard let trip = tripEntity?.tripEntity.trip, let itineraryId = trip.firstItineraryId else { print("No trip or itinerary ID can be found for the selected trip.") return [] } return [] // return empty for this demo } func suggestedEntities() async throws -> [ShortcutsItineraryDayEntityDemo] { print("suggested itinerary days being called") let tripsStore = TripsStore() guard let trip = tripEntity?.tripEntity.trip, let itineraryId = trip.firstItineraryId else { print("No trip or itinerary ID found for the selected trip.") return [] } return [] } } struct PlanActivityIntentDemo: AppIntent { static var title: LocalizedStringResource { "Plan New Activity" } // The selected trip fails to get injected when intent is run from shortcut app @Parameter(title: "Trip", description: "The trip to plan an activity for", requestValueDialog: "Which trip would you like to plan an activity for?") 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") var activityDay: ShortcutsItineraryDayEntity func perform() async throws -> some ProvidesDialog { // This is a demo intent, so we won't actually perform any actions. .result(dialog: "Activity '\(title)' planned") } }
0
1
110
Jun ’25
How to transition views in a List View when it appears (SwiftUI)
There are views in a ListView. The views have the transition modifiers on them but no transition occurs. The List is made to appear first before its chid views are rendered. Here's some code to illustrate the problem: The StateObject: class TripsStore: ObservableObject { @Published private(set) var trips: [Trip] = [] @MainActor func getTrips() async throws { ... } } The View struct TripsStore: View { @StateObject private var tripsStore: TripsStore = TripsStore() @State private var progress: RequestStatus = .idle @State private var availableTrips: Set<UUID?> = [] var body: some View { NavigationStack { Group { if progress == .loading { ProgressView() } else { List(tripsStore.trips) { trip in if availableTrips.contains(trip.id) { TripCard(trip: trip) .transition(.asymmetric(insertion: .opacity, removal: .scale).animation(.easeInOut(duration: 3.5))) } } .onAppear { withAnimation { tripsStore.trips.forEach { trip in availableTrips.insert(trip.id) } } } } } .task { progress = .loading do { try await tripsStore.getTrips() } catch { print(error) } progress = .idle } } } } By using a GroupView, trip data is fetched and List is only rendered when that data is available. The appearing of each trip card is animated when the list is about to appear using the .onAppear modifier. Checking if a trip is available, should "insert" the trip's card into the already appeared ListView. During insertion, the transition ought to occur. Unfortunately, it's not happening. Does anyone know why? How can it be fixed?
0
0
330
May ’23
Async task cancelled in Refreshable Modifier on Scrollview on iOS 16
I'm trying to use the refreshable modifier on a Scrollview in an app that targets iOS 16. But the asynchronus task gets cancelled during the pull to refresh gesture. It was tested on a physical device. Here is some code that demonstrates the problem and an image with the error printed: ExploreViewModel.swift class ExploreViewModel: ObservableObject { @Published var randomQuotes: [Quote] = [] init() { Task { await loadQuotes() } } @MainActor func loadQuotes() async { let quotesURL = URL(string: "https://type.fit/api/quotes")! do { let (data, urlResponse) = try await URLSession.shared.data(from: quotesURL) guard let response = urlResponse as? HTTPURLResponse else { print("no response"); return} if response.statusCode == 200 { let quotes = try JSONDecoder().decode([Quote].self, from: data) randomQuotes.append(contentsOf: quotes) } } catch { debugPrint(error) debugPrint(error.localizedDescription) } } func clearQuotes() { randomQuotes.removeAll() } } Content.swift import SwiftUI struct ContentView: View { @StateObject private var exploreVM = ExploreViewModel() var body: some View { NavigationStack { ExploreView() .environmentObject(exploreVM) .refreshable { exploreVM.clearQuotes() await exploreVM.loadQuotes() } } } } ExploreView.swift import SwiftUI struct ExploreView: View { @EnvironmentObject var exploreVM: ExploreViewModel var body: some View { ScrollView { VStack { LazyVGrid(columns: [GridItem(.adaptive(minimum: 140.0), spacing: 24.0)], spacing: 24.0) { ForEach(exploreVM.randomQuotes) { quote in VStack(alignment: .leading) { Text("\(quote.text ?? "No Text")") .font(.headline) Text("\(quote.author ?? "No Author")") .font(.caption) } .frame(minWidth: 0, maxWidth: .infinity) .frame(height: 144.0) .border(Color.red, width: 2.0) } } } .padding() .navigationTitle("Explore") } } } Printed Error
2
3
2.2k
Jan ’23