Post

Replies

Boosts

Views

Activity

How does listSectionSpacing works in SwiftUI?
Hello, I want to understand how listSectionSpacing with a custom CGFloat value works in SwiftUI. According to the documentation, we can use different spacing between sections and If adjacent sections have different spacing value, the smaller value on the shared edge is used. For example, if I have a: Section A with a listSectionSpacing of 10 Section B with a listSectionSpacing of 200 Section C with a listSectionSpacing of 20 Section D with a listSectionSpacing of 0 I notice the spacing between the sections A+B and B+C is none of 10, 200 or 20. If the documentation is correct, shouldn't it be 10? If I now have a: Section A with a listSectionSpacing of 200 Section B with a listSectionSpacing of 200 Section C with a listSectionSpacing of 200 Section D with a listSectionSpacing of 0 I notice the spacing is never 200. Is the spacing capped? Also, if I specify a header and footer, the spacing doesn't seem to be used at all. Thus the spacing is the same for all sections. Is my understanding wrong and this API working as expected? Or is that a bug in how the spacing is used? I filed #FB13699952 few weeks ago. Axel struct ListSections: View { @State private var header: Bool = false @State private var footer: Bool = false private let sections: [ListSection] = [ ListSection(position: "A", spacing: 200), ListSection(position: "B", spacing: 200), ListSection(position: "C", spacing: 200), ListSection(position: "D", spacing: 0) ] var body: some View { VStack { Toggle("Header", isOn: $header) Toggle("Footer", isOn: $footer) } .padding(.horizontal) List { ForEach(sections) { section in Section { LabeledContent("Section \(section.position)", value: section.spacing.formatted()) } header: { if header { Text("Header \(section.position)") .background(.red.opacity(0.3)) } } footer: { if footer { Text("Footer \(section.position)") .background(.green.opacity(0.3)) } } .listSectionSpacing(section.spacing) } } } } #Preview { ListSections() }
Topic: UI Frameworks SubTopic: SwiftUI
7
0
1.6k
Jun ’24
What are possible failures when using CLLocationUpdate.Updates AsyncSequence
Hello, I'm currently migrating my app location service to use the new CLLocationUpdate.Updates. I'm trying to understand what can fail in this AsyncSequence. Based on the previous CLError, I thought authorisation was one of them for example but it turns out that this is handled by the CLLocationUpdate where we can check different properties. So, is there a list of errors available somewhere? Thanks Axel, @alpennec
2
0
444
Dec ’24
Are subscriptions Product ID unique per app or per developer account?
Hello, I'm trying to create a subscription for one of my apps. When I specify the Product ID yearly_3, I get the following error message: The Product ID you entered is already being used by another subscription. This app does not have any other subscriptions with this Product ID. But I have another app with a yearly_3 Product ID. According to the official documentation, the Product ID is A unique ID specific to your app. So I thought it was possible to have the same Product ID between apps, but not for the same app. What's the rule here? Thanks, Axel
0
0
443
Dec ’24
App Store Connect API: Modify an Auto-Renewable Subscription to change prices for all territories
Hello, I want to update the prices in all territories of an auto-renewable subscription at once (in a single request). I know it's possible to do it territory by territory using the Create a Subscription Price Change API endpoint, but this means I need to call this API for every territory. And I have a lot of subscriptions I need to update. There is an another API endpoint that seems to allow to Modify an Auto-Renewable Subscription. For the countries where I want to change the price, I fetch the subscription price points using the List All Price Points for a Subscription API endpoint. When I call this API endpoint with the following body (that is the expected body content for this endpoint): { "data": { "type": "subscriptions", "relationships": { "prices": { "data": [ { "id": "eyJzIjoiNjc0MDAyMTQ5NiIsInQiOiJDQU4iLCJwIjoiMTAwMDEifQ", "type": "subscriptionPrices" }, { "type": "subscriptionPrices", "id": "eyJzIjoiNjc0MDAyMTQ5NiIsInQiOiJVU0EiLCJwIjoiMTAwMDEifQ" } ] } }, "id": "6740021496" }, "included": [ { "relationships": { "subscriptionPricePoint": { "data": { "id": "eyJzIjoiNjc0MDAyMTQ5NiIsInQiOiJDQU4iLCJwIjoiMTAwMDEifQ", "type": "subscriptionPricePoints" } }, "territory": { "data": { "type": "territories", "id": "CAN" } }, "subscription": { "data": { "id": "6740021496", "type": "subscriptions" } } }, "id": "eyJzIjoiNjc0MDAyMTQ5NiIsInQiOiJDQU4iLCJwIjoiMTAwMDEifQ", "attributes": { "preserveCurrentPrice": true }, "type": "subscriptionPrices" }, { "attributes": { "preserveCurrentPrice": true }, "id": "eyJzIjoiNjc0MDAyMTQ5NiIsInQiOiJVU0EiLCJwIjoiMTAwMDEifQ", "type": "subscriptionPrices", "relationships": { "subscription": { "data": { "type": "subscriptions", "id": "6740021496" } }, "subscriptionPricePoint": { "data": { "type": "subscriptionPricePoints", "id": "eyJzIjoiNjc0MDAyMTQ5NiIsInQiOiJVU0EiLCJwIjoiMTAwMDEifQ" } }, "territory": { "data": { "type": "territories", "id": "USA" } } } } ] } I receive a 409 error: { "errors" : [ { "id" : "5b6a4b62-686c-4a65-87ba-e16131db517b", "status" : "409", "code" : "ENTITY_ERROR", "title" : "There is a problem with the request entity", "detail" : "User is not allowed to edit.", "source" : { "pointer" : "subscriptionPrices" } } ] } I made sure my bearer authorisation token is correct and still valid (not expired). the p8 key has Admin rights Can this PATCH endpoint be used for what I want to do? If yes, is there anything special to do to use this PATCH endpoint? Thanks, Axel
2
0
600
Jan ’25
Bug in Screen Time API: familyActivityPicker dismisses a presenting sheet on iOS 18.4 and above
Hello, I’m presenting the familyActivityPicker from a presented sheet in my application. When I select some apps, categories or websites and tap “Done”, the familyActivityPicker is dismissed but the presenting sheet is also dismissed on iOS 18.4, iOS 18.5, iOS 26 beta 1 and 2. If I tap on “Cancel” from the familyActivityPicker, the sheet is also dismissed on iOS 18.4, iOS 18.5, iOS 26 beta 1 and 2. The same code works perfectly fine on iOS 18.0, iOS 18.1, iOS 18.2 and iOS 18.3. Is this a known-issue? If opened the feedback FB18369821 for this. Regards, Axel
3
0
140
Aug ’25
Working with visits and significant location changes following Core Location updates in iOS 17 and iOS 18
Hello, I'm working on an application that requires the use of significant location changes and visits, in addition to region monitoring and standard continuous location delivery (foreground and background). iOS 17 and iOS 18 introduced changes to how we can monitor distinct regions of interest (with CLMonitor) as well as receive location updates (with CLLocationUpdate). But I couldn't find any information regarding how to work with Significant location changes. Do we still need to create a location manager and call startMonitoringSignificantLocationChanges()? Where are the updates received in this case, in the locationManager(_:didUpdateLocations:) or in the liveUpdates async sequence? Visits. Same question here, for visit monitoring to work, do we still have to create a location manager then call startMonitoringVisits()? Where are the visits being notified? Still in locationManager(_:didVisit:) or in the liveUpdates asynchronous sequence? I just want to be sure I understand correctly how to use the updates, and if some features of Core Location still need to use a location manager and the delegate to receive the events. Maybe additional CLCondition will be added to cover both of these technologies as it seems highly related to monitoring conditions (significant location change, and visit). Thank you, Axel
0
0
127
Jul ’25
Product.SubscriptionInfo subscriptionPeriod does not provide the same result between the Sandbox/App Store environment and the StoreKit Testing in Xcode for a "1 week" subscription. "1 week" vs "7 days"
Hello, I noticed the Product.SubscriptionInfo subscriptionPeriod (of type Product.SubscriptionPeriod) is different for the same product between StoreKit Testing in Xcode and the sandbox/App Store (production) environment. For a “1 week” auto-renewable subscription, we get the following: StoreKit Testing in Xcode: 1 week gives a subscriptionPeriod with value of 1 and a unit of Product.SubscriptionPeriod.Unit.week Sandbox/App Store: 1 week gives a subscriptionPeriod with value of 7 and a unit of Product.SubscriptionPeriod.Unit.day This created issues in my app because I used the localizedDescription of a Product.SubscriptionPeriod to display a text similar to “$4.99 per week”. This is what I obtain with the StoreKit Testing in Xcode, but in the Sandbox/App Store environment, it displays “$4.99 per day” (because the subscriptionPeriod is “7 Days” and the unit is then .day). Obviously, this is not what I wanted to display. Other periods like “1 month”, “2 months”, “3 months”, “6 months, and “1 year”, the period provided by both StoreKit Testing and Sandbox/App Store correspond to the period unit specified in App Store Connect. In addition, I want to report that for a weekly subscription/offer or a 2 weeks offer, Product.SubscriptionInfo.subscriptionPeriod or Product.SubscriptionOffer.period == .weekly or .everyTwoWeeks is always false. We observe the following: With Sandbox or App Store live production: 1 week, Product.SubscriptionInfo.subscriptionPeriod == .weekly is false (because it’s “7 days”) 1 week, Product.SubscriptionOffer.period == .weekly is false (because it’s “7 days”) 2 weeks (offer), Product.SubscriptionInfo.subscriptionPeriod == .everyTwoWeeks is false (because it’s “14 days”) 2 weeks (offer), Product.SubscriptionOffer.period == .everyTwoWeeks is false (because it’s “14 days”) But with an Xcode StoreKit configuration file: 1 week, Product.SubscriptionInfo.subscriptionPeriod == .weekly is true (because it’s “1 week”) 1 week, Product.SubscriptionOffer.period == .weekly is true (because it’s “1 week”) 2 weeks, Product.SubscriptionInfo.subscriptionPeriod == . everyTwoWeeks is true (because it’s “2 weeks”) 2 weeks, Product.SubscriptionOffer.period == . everyTwoWeeks is true (because it’s “2 weeks”) So in sandbox and production, .weekly and .everyTwoWeeks is never possible. If someone from Apple could check the feedback FB19605865 🙂 Thank you Regards, Axel, @alpennec Code: do { let productIDs: [String] = ["revenueSocks_weekly_trial"] let products: [StoreKit.Product] = try await Product.products (for: productIDs) let weeklySubscription: StoreKit.Product = products.first! let displayPrice: String = weeklySubscription.displayPrice // For a weekly subscription in App Store Connect // With an Xcode StoreKit configuration file: subscriptionPeriod unit is Week (week), value is 1 → "1 Week" // With the Sandbox + App Store: subscriptionPeriod unit is Day (.day), value is 7 → "7 Days" let unitString: String = weeklySubscription.subscription!.subscriptionPeriod.unit.localizedDescription print("\(displayPrice) per \(unitString.localizedLowercase)") // StoreKit configuration file → "$4.99 per week" // Sandbox + App Store → "$4.99 per day" } catch { print(error) }
0
0
58
3w
StoreKit 2: does Transaction.currentEntitlements also provide transactions for subscriptions shared with me?
Let's imagine an app with two plans, one for individual (level of service 2) and one for family (level of service 1). If a user is subscribed as an individual, but if someone in his family shares a family plan with him, will Transaction.currentEntitlements show both subscriptions? Or only the transaction where the user is the owner (in this case the individual subscription)?
1
0
1.1k
Dec ’21
SwiftUI: Fatal error: No ObservableObject of type * found. A View.environmentObject(_:) for * may be missing as an ancestor of this view.
Hello, The app displays a list of posts (Post), and for each post, a list of tags (Tag). The Post detail view shows a list of tags for a given post. The Tag detail view shows the post name and the tag name. Both Post and Tag are ObservableObject, and both are passed to the environment when a NavigationLink is tapped. On the master List with all the posts, you tap on a post. The post is passed in the environment. It's working because the detail view for the selected post is correctly displayed, and you can choose to display a tag from the tags in the displayed post. But when you tap on a tag to view the details, the app crashes: the post object is not in the environment. No ObservableObject of type Post found. A View.environmentObject(_:) for Post may be missing as an ancestor of this view. Why? The post object in the PostView, so it should be also available in the TagView because the TagView can only be displayed from the PostView. Thanks Axel import SwiftUI class Store: ObservableObject {     @Published var posts: [Post] = [         Post(name: "Post 1", tags: [.init(name: "Tag 1"), .init(name: "Tag 2")]),         Post(name: "Post 2", tags: [.init(name: "Tag 1"), .init(name: "Tag 2")])     ] } class Post: ObservableObject, Identifiable, Hashable {     @Published var name: String = ""     @Published var tags: [Tag] = []     var id: String { name }     init(name: String, tags: [Tag]) {         self.name = name         self.tags = tags     }     static func == (lhs: Post, rhs: Post) -> Bool {         return lhs.id == rhs.id     }     func hash(into hasher: inout Hasher) {         hasher.combine(id)     } } class Tag: ObservableObject, Identifiable, Hashable {     @Published var name: String = ""     var id: String { name }     init(name: String) {         self.name = name     }     static func == (lhs: Tag, rhs: Tag) -> Bool {         return lhs.id == rhs.id     }     func hash(into hasher: inout Hasher) {         hasher.combine(id)     } } struct PassEnvironmentObject: View {     @StateObject private var store: Store = .init()     var body: some View {       NavigationStack {             List {                 ForEach(store.posts) { post in                     NavigationLink(post.name, value: post)                 }             }             .navigationDestination(for: Post.self) { post in                 PostView()                     .environmentObject(post)           }             .navigationDestination(for: Tag.self) { tag in                 TagView()                     .environmentObject(tag)             }         }     } } struct PostView: View {     @EnvironmentObject private var post: Post     var body: some View {         List {             ForEach(post.tags) { tag in                 NavigationLink(tag.name, value: tag)             }         }     } } struct TagView: View {     @EnvironmentObject private var post: Post     @EnvironmentObject private var tag: Tag     var body: some View {         VStack {             Text(post.name)             Text(tag.name)         }     } } struct PassEnvironmentObject_Previews: PreviewProvider {     static var previews: some View {         PassEnvironmentObject()     } }
2
0
2.0k
Jun ’22
Xcode Export Localizations for an iOS app using Swift Package Manager packages fails: No such module UIKit
I'm building an iOS app (the supported destinations in the app target are iOS, iPad and Mac - Designed for iPad). I've many SPM frameworks in order to split my codebase in different features. I want to export the localisations for the different packages and the app using Xcode but it fails. I followed the Apple guide regarding SPM localization: the packages contains a Resources folder with a folder for each language supported. I specified the platforms .iOS(.v16) in the packages. But it seems that exporting the localisations using the Product > Export Localizations feature in Xcode compiles also the packages and app for macOS. Here is the error message: Showing Recent Messages /Users/axel/Developer/AppName/Packages/Helpers/Sources/Helpers/UIKit/UIImage+Extension.swift:7:14: No such module 'UIKit' /Users/axel/Developer/AppName/Packages/Helpers/Sources/Helpers/UIKit/UIImage+Extension.swift:7:14: UIKit is not available when building for macOS. Consider using `#if canImport(UIKit)` to conditionally import this framework. Is there a way to have the export feature work when building an iOS app with packages specified for iOS?
2
0
2.2k
Feb ’23
How do subscription promotional offers work for currently subscribed customers?
Hello, I'm trying to understand what happens when a subscribed customer of a subscription A purchases a promotional offer for the same subscription A. Let's say the product is a yearly subscription priced at $100. When the month 7 starts (6 months remaining in the regular subscription period), I send the user a promotional offer for the same product but priced at $25 for the first year (100$ afterwards) and he accepts the offer. Is the promotional offer started only at the end of the current year (after the 6 remaining months) or is it started immediately and he gets a pro-rata refund for the 6 remaining months? Thanks.
5
0
946
Sep ’25
Automatic Grammar Agreement with formatted number: use integer value to switch categories
Hello, I want to use Automatic Grammar Agreement to localise a string in my app, let say "three remaining activities". The string "three" is obtained by using a NumberFormatter with a numberStyle set to .spellOut (so I'm not using an Integer) var formatter: NumberFormatter = NumberFormatter() formatter.numberStyle = .spellOut let formattedCount: String = numberFormatter.string(from: count as NSNumber)! Text("key_with_string_\(formattedCount)") In my string catalog, I have translated the key key_with_string_%@ like this ^[%@ remaining activity](inflect: true), but it does not work. I've tried to add the integer value used by the number formatter in the key key_with_string_%@_%lld but it does not work. Should Automatic Grammar Agreement work normally just by using the formatted string provided by the NumberFormatter? If not, is there a way to specify to use a secondary variable (my count integer) to switch between different categories like one and other automatically? Thanks ! Axel
1
0
887
Jun ’24
Why first View on my NavigationStack appears again when I switch branch?
Hello, In my app, I have an onboarding made of multiple steps in a NavigationStack. I also have a state variable that controls an if else root branch to show either the onboarding NavigationStack or the app content if the onboarding is finished. I noticed that when I end the onboarding (i.e. I switch to the other part of the if else root branch), the onAppear of the first View in the NavigationStack of the onboarding is called again. I don’t understand why. Is this a bug? Thanks, Axel enum Step { case one case two case three case four } struct ContentView: View { @State private var isFinished: Bool = false @State private var steps: [Step] = [] var body: some View { if isFinished { Button("Restart") { steps = [] isFinished = false } } else { NavigationStack(path: $steps) { VStack { Text("Start") .onAppear { print("onAppear: start") } Button("Go to step 1") { steps.append(.one) } } .navigationDestination(for: Step.self) { step in switch step { case .one: Button("Go to step 2") { steps.append(.two) } .onAppear { print("onAppear: step 1") } case .two: Button("Go to step 3") { steps.append(.three) } .onAppear { print("onAppear: step 2") } case .three: Button("Go to step 4") { steps.append(.four) } .onAppear { print("onAppear: step 3") } case .four: Button("End") { isFinished = true } .onAppear { print("onAppear: end") } } } } .onAppear { print("onAppear: NavigationStack") } } } }
6
0
779
Dec ’24
Are data in an iCloud NSUbiquitousKeyValueStore directly available at app launch on another device?
Hello, I'm planning to had an onboarding to one of my apps. I am thinking about a way for a user to not see the onboarding again if he installs the app on another device. So for example, the user completes the onboarding on its iPhone, then downloads the app on its iPad and launch it, he doesn't see the onboarding a second time. I thought about using iCloud NSUbiquitousKeyValueStored to store the onboarding completion state. But I'm not sure when the data is synced to the other device logged into the same Apple account: Immediately even if the app is not installed on the other device (independent from the app, only iCloud thing)? At the same time as the app install on the other device? After the app is first launched on the other device? Of course synchronisation will depend on the Internet connection, speed, etc. so the app should handle the case where the data is not here but what would be the best case scenario? Thank you, Axel
1
0
76
Aug ’25