Posts under App & System Services topic

Post

Replies

Boosts

Views

Created

External purchase region
Hi everyone, I have a question regarding App Store subscriptions and tax country / storefront changes. If a customer originally purchased a subscription while their App Store country was France (so we reported France as the tax country), and later updates or renews that same subscription while located in Hungary, which country should we report going forward? Should we continue using the original country (France)? Or should we start sending the new country (Hungary) once it changes? Also, what happens if the customer changes their App Store region entirely, for example from France to the US? How is Apple’s commission calculated after the region change? If anyone has experience with this scenario or knows the official Apple behavior, I’d really appreciate your help. Thanks!
2
0
187
2w
State of Mind and the free text: Can it be fetched?
Has anyone actually managed to read the free-text note/context from Apple Health State of Mind entries? I’m building an iOS app that reads HKStateOfMind data from HealthKit. I can get the expected stuff fine: valence labels associations But in the Health app, users can also add extra context text to a mood entry, like: Tasks, Weather - Great work-life balance From my app, I can read Tasks and Weather, but I can’t find the Great work-life balance part anywhere. I already checked: public HKStateOfMind properties metadata debug description / object description attachment-ish routes Nothing so far. So before I spend more time chasing this: is that text just not exposed to third-party apps? Or is there some weird HealthKit path I’m missing? If anyone has actually pulled this off, I’d love to know how.
0
0
127
2w
how to store secret key in/for system extension
Hi. I have a private cryptographic key that I want to generate and store for use by the system extension only (a network extension NETransparentProxyProvider). The ideal properties I want is: only accessible by extension never leave extension not be accessible by root user or other apps Here is what I have tried so far (by/within the system extension): app data container / local storage: this works, but is accessible by root user app data shared container (storage): this works, but also acccessible by root user system keyring: works, but also accesible by root user System extension by itself does not seem to be able to store/load secrets in app protected keyring. The host application however can store in app protected keyring.... So I though, let's use an app group (as access group) and have it like this shared between host and (system) extension... but nop... (system) extension cannot access the secret... Ok... so than I thought: manual low-level XPC calls.... Also that doesn't work, got something almost to work but seemed to require an entire 3rd (launchd/daemon) service.... way to complex for what I want... also seems that as a root user I can use debug tools to also access it There is however the SendMessage/HandleMessage thing available for TransparentProxy.... that does work... but (1) also doesn't seem the most secure (2) the docs clearly state cannot rely on that for this state as the system extension can be started while the host app is not active.... (e.g. at startup) So that is not a solution either.... I went in so many different directions and rabbit holes in the last days.... this feels like a lot harder than it should be? How do other VPN/Proxy like solutions store secrets that are unique to an extension???? I am hoping there is something available here that I am simply missing despite all my effort... any guidance greatly appreciated...
5
0
231
2w
Family Controls Entitlement for Extension Identifiers
I've already submitted multiple cases about this issue. My Family Controls Distribution request was apparently approved (or I was told via Developer Support) for my Shield Action & Shield Configuration extensions, but the Distribution option still does not appear in the identifiers. This is blocking my ability to distribute via TestFlight. I need someone who can update the identifier capabilities or explain why the approved capability is not showing.
1
0
142
2w
Reclaiming cached data from an `enumerateDirectory` call
If I'm in an enumerateDirectory call, I can very quickly fill in the fileID, parentID, and (maybe) the type attributes based on the directory entry I have loaded. That is, I can quickly fill in anything that is contained in the dirent structure in dirent.h, plus the parentID. However, if any other attributes are requested (say, flags), or if the file system doesn't store the filetype in the directory entry, then I need to do additional I/O and load an inode. If I have to load an inode, I might keep a reference to it and assume that I can clean it up later whenever there is a matching call to reclaimItem. But in the enumerateDirectory call, I never provide an FSItem to the system! By observation, I see that normally, a call to enumerateDirectory of this nature is followed up by a lookupItem call for every single fetched item, and then assumedly the system can later reclaim it if need be. At least, I tried various ways of listing directories, and each way I tried showed this behavior. If that's the case, then I can rely on a later reclaimItem call telling me when to clean up this cached data from memory. Is this guaranteed, however? I don't see a mention of this in the documentation, so I'm not sure if I can rely on this. Or, do I need to handle a case where, if I do additional I/O after enumerateDirectory, I might need to figure out when cached data should be cleaned up to avoid a "leak?" (Using the term "leak" loosely here, since in theory looking up the file later would make it reclaimable, but perhaps that might not happen.)
6
0
378
2w
Can't enter sandbox environment for IAP testing on any of my apps - always getting -100 error with no [Environment: Sandbox] indicator
Body: I'm experiencing a persistent issue that has affected multiple apps I've developed, and I'm hoping to get some guidance from the community or Apple engineers. The Problem: When testing In-App Purchases, my app never enters the sandbox environment. The payment prompt does NOT show the "[Environment: Sandbox]" indicator, and I always receive error code -100 (Invalid Product Identifier). This issue has occurred across multiple apps I've built, including a previous app that I ultimately had to release as a paid download (rather than freemium with IAP) because I couldn't resolve this same problem. Now I'm facing the identical issue with my new app, "AI Job Assistant". What I've Checked (all correct): ✅ Paid App Agreement status is "Active" in App Store Connect ✅ Bundle ID matches exactly between Xcode/HBuilderX and App Store Connect ✅ Product IDs in code match those created in App Store Connect (case-sensitive, no spaces) ✅ All IAP products have complete metadata (name, description, pricing, 640x920 screenshot) ✅ Product status is "Ready to Submit" (not "Waiting for Review") ✅ I have both iOS Development certificate and iOS Distribution certificate — I am using the Development certificate for testing ✅ My provisioning profile is explicitly for Development (named "aijobDevprofile", shows "iOS Development" type) ✅ The Development profile contains my test device UDID ✅ I have fully signed out of my real Apple ID in Settings → Media & Purchases ✅ I only log into my Sandbox Tester account through the purchase prompt (not in Settings) ✅ I test on a real device (not simulator) ✅ I have tried creating multiple new Sandbox Tester accounts ✅ I have tried toggling "Cleared for Sale" off and on for all products ✅ I have waited over 24 hours after making configuration changes What I See: When I initiate a purchase, the payment prompt comes up but there is NO "[Environment: Sandbox]" text anywhere After entering my Sandbox Tester credentials, the request fails with error code -100 (Invalid Product Identifier) My Setup: Development framework: uni-app / HBuilderX (custom debug base with Development certificate and Development provisioning profile) Backend: Cloudflare Workers (handles receipt verification) Testing device: iPhone (latest iOS version) The same issue occurred with my previous app, which I never resolved and eventually gave up on IAP entirely Question: Why does my app never enter the sandbox environment despite using the correct Development certificate and Development provisioning profile? Is it possible there is an issue at the Apple developer account level that is preventing sandbox environment activation? How can I force my debug builds to connect to sandbox instead of production? I am willing to provide any additional logs or information needed. Please help. Thank you.
0
0
167
2w
Applinks for any subdomain not opening the app
My Entitlements file contains the following (removed some non related entries): <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.associated-domains</key> <array> <string>webcredentials:app.mydomain.org</string> <string>applinks:*.mydomain.org</string> </array> </dict> </plist> Now when I tap on a link such as abc.mydomain.org, the app is not opened. If I change the generic applinks key from *.mydomain.org to a specific domain, this works correctly and it opens the app as expected. (This makes me think the website part of the AASA file is correct). Since I need to support a lot of subdomains (think about hundreds in the near future), I really need the wildcard to work. Do you have any tips on how to make this work?
0
0
70
3w
EAAccessoryManager Crash when selecting accessory from picker while multiple accessories are present
The app crashes when using EAAccessoryManager.showBluetoothAccessoryPicker(withNameFilter:) to connect to a Bluetooth accessory in a multi-accessory scenario. The crash occurs immediately after selecting an accessory from the picker UI. Steps to Reproduce: Ensure a Bluetooth accessory (Accessory A) is already connected to the iPhone/iPad and is visible in Bluetooth settings. Launch the app. Initiate a connection flow that presents the Bluetooth accessory picker using EAAccessoryManager.showBluetoothAccessoryPicker(withNameFilter:). Ensure another compatible accessory (Accessory B) is available and visible in the picker. Select Accessory B from the picker to connect. After connection, simulate a disconnect of Accessory B (e.g., power cycle or remove battery). Attempt to reconnect Accessory B by triggering the same picker flow again. Select Accessory B from the picker. Result: The accessory connects successfully at the system level. The app crashes immediately after selecting the accessory from the picker (during dismissal). Reproducibility: Occurs consistently under the described multi-accessory scenario. Not observed when only a single accessory is present.
5
0
267
3w
macOS Preview appears to hold MTP devices open indefinitely
I am developing a USB MTP device for use with macOS. When the device is connected while Preview is running, I observe the host send OpenSession, then GetDeviceInfo, and then no further MTP commands. I do not see a later CloseSession. Problem is that once this happens, exclusive access to the USB interface is retained, so another application cannot connect to the device. From the device side, there is no obvious way to recover except forcing a USB disconnect/reset or shutting down the USB interface. My questions are: Is this expected behavior for Preview, or for a Preview-related macOS helper? Is it expected on macOS that a client may open an MTP session and then leave it idle without sending CloseSession? I am mainly trying to understand whether this is expected macOS behavior, or whether this should be considered a bug.
3
0
184
3w
AppTransaction.originalAppVersion returns "1.0" in App Review environment — not the actual build number
Hi, I'm using AppTransaction.originalAppVersion to detect whether a user originally purchased the app under the old paid model, so I can automatically unlock the app for them as a courtesy when migrating to freemium. Background On iOS, originalAppVersion returns CFBundleVersion (the build number). When I transitioned the app from paid (v1.x) to freemium (v2.0), I defined a numeric threshold for CFBundleVersion to distinguish legacy purchasers from new users: Build number below the threshold → v1.x purchase → auto-unlock Build number at or above the threshold → v2.0+ install → requires IAP In Production, originalAppVersion correctly returns the actual build number, and the comparison works as intended. Detection logic (simplified) // Determine environment via receipt URL func detectStoreEnvironment() -> String { if let url = Bundle.main.appStoreReceiptURL, url.lastPathComponent == "sandboxReceipt" { return "Sandbox" } return "Production" } // Legacy check using numeric comparison static func isLegacyPaidUser(version: String, threshold: String) -> Bool { guard !version.isEmpty else { return false } return version.compare(threshold, options: .numeric) == .orderedAscending } // In checkLegacyPurchase(): let version = appTransaction.originalAppVersion let isLegacy = isLegacyPaidUser(version: version, threshold: legacyBuildNumberThreshold) let env = detectStoreEnvironment() let shouldAutoUnlock = isLegacy && env != "Sandbox" The problem I know that in the Sandbox environment, originalAppVersion always returns "1.0" — this is mentioned in the AppTransaction documentation. My code already suppresses the auto-unlock for Sandbox (env != "Sandbox"). However, it appears that the App Review environment also returns "1.0" for originalAppVersion. Because the receipt URL path component is "receipt" (not "sandboxReceipt"), my environment detection classifies it as "Production" — so the Sandbox suppression doesn't apply. The reviewer is incorrectly identified as a legacy paid user and the app is unlocked without a purchase. This caused our v2.0 submission to be rejected under Guideline 2.1a. Questions Is it documented that the App Review environment returns "1.0" for AppTransaction.originalAppVersion, similar to Sandbox? Is there a reliable way to detect the App Review environment specifically — separate from both Sandbox and Production? For example, does the receipt URL differ, or is there another API? Is using originalAppVersion for legacy paid-user detection a supported pattern? If so, what is the recommended approach to handle the App Review case? Any guidance would be greatly appreciated. Thank you.
0
0
92
3w
WeatherKit JWT token generation fails with WDSJWTAuthenticator Code=2 despite correct entitlement
I enabled the WeatherKit capability on my App ID (com.saimcan.darkweather, Team 6SWSD6V4ZC) about 12 hours ago. The entitlement is embedded in the binary and the provisioning profile authorizes it, but every request fails at the JWT generation step. Error from the logs: Error Domain=WeatherDaemon.WDSJWTAuthenticatorServiceListener.Errors Code=2 "(null)" Relevant log excerpt (iOS 26.4 Simulator, same result on a physical device): [AuthService] Calling process is 3rd party process and has the correct entitlement ... accepting the connection [AuthService] Received proxy request for generating a jwt token. url=https://weatherkit.apple.com [WeatherDataService] Starting to generate JWT token request. bundleIdentifier=com.saimcan.darkweather [AuthService] Signed successfully [WeatherDataService] Make new JWT token request. requestIdentifier=... [AuthService] Failed to generate jwt token ... Code=2 What I have verified: Active Apple Developer Program membership (renewed through April 2027) All agreements accepted WeatherKit capability enabled on the App ID codesign -d --entitlements confirms com.apple.developer.weatherkit in the built binary embedded.mobileprovision also includes com.apple.developer.weatherkit App Group (group.com.saimcan.darkweather.shared) correctly bound to both the app and widget App IDs Since "Signed successfully" is logged, the device-side auth plumbing is working. The rejection appears to be server-side. Could someone from the WeatherKit team check whether JWT minting is enabled for this Team ID / Bundle ID? Team ID: 6SWSD6V4ZC Bundle ID: com.saimcan.darkweather
2
1
156
3w
DeviceActivityReport extension not discovered at runtime (ClientError Code=2)
Hi I am trying to implement a minimal DeviceActivityReport extension. Setup: iOS app with FamilyControls authorization (status = approved) DeviceActivityReport displayed in SwiftUI Report extension embedded in PlugIns Correct NSExtensionPointIdentifier: com.apple.deviceactivityui.report-extension No NSExtensionPrincipalClass or storyboard Entitlements: com.apple.developer.family-controls com.apple.developer.family-controls.app-and-website-usage The app installs and runs correctly. Authorization is granted. However, the extension is never loaded: No logs from the extension (init/body/makeConfiguration never called) Console shows: "Failed to discover the client's extension: DeviceActivityReportService... ClientError Code=2" Environment: Xcode 16.2 iOS device running iOS 18.x (latest available) The .appex is correctly embedded and signed. Question: Is there a known issue with DeviceActivityReport extensions not being discovered at runtime with this setup? Is additional configuration required beyond NSExtensionPointIdentifier? Thanks
2
0
215
3w
Tap to Pay on iPhone – Provisioning profile missing entitlement when uploading to TestFlight
Hi everyone, I’m currently implementing Tap to Pay on iPhone following Apple’s official documentation. I’ve completed all the required configurations (entitlements, capabilities, merchant setup, etc.) on the Apple Developer portal. However, when I archive the app and attempt to upload it to TestFlight, I receive the following error: "Profile doesn't support Tap to Pay on iPhone. Profile doesn't include the com.apple.developer.proximity-reader.payment.acceptance entitlement." From what I understand, this seems related to the provisioning profile not including the required entitlement, even though I believe everything has been configured correctly. I have already tried: Regenerating provisioning profiles Verifying App ID capabilities Ensuring the correct entitlements are added in the project But the issue still persists. Has anyone encountered this issue before? Is there any additional approval step required from Apple to enable the Tap to Pay entitlement? I’d really appreciate any advice or experience you can share. Thanks in advance!
1
0
214
3w
TLS Inspection with MITM Proxy setup for System Extension app in macOS
Hi All, I am working on a macOS System Extension using Apple’s Network Extension Framework, designed to observe and log network activity at multiple layers. The system extension is currently stable and working as expected for HTTP and DNS traffic with 3 providers, getting Socket, HTTP, and DNS logs. Current Architecture Overview The project consists of two Xcode targets: 1. Main App Process Responsible for: Managing system extension lifecycle (activation, configuration) Establishing IPC (XPC) communication with extensions Receiving structured logs from extensions Writing logs efficiently to disk using a persistent file handle Uses: OSSystemExtensionManager NEFilterManager, NETransparentProxyManager, NEDNSProxyManager NWPathMonitor for network availability handling Persistent logging mechanism (FileHandle) 2. System Extension Process Contains three providers, all running within a single system extension process: a) Content Filter (NEFilterDataProvider) Captures socket-level metadata Extracts: PID via audit token Local/remote endpoints Protocol (TCP/UDP, IPv4/IPv6) Direction (inbound/outbound) Sends structured JSON logs via shared IPC b) Transparent Proxy (NETransparentProxyProvider) Intercepts TCP flows Creates a corresponding NWConnection to the destination Captures both HTTP and HTTPS traffic, sends it to HTTPFlowLogger file which bypasses if it's not HTTP traffic. Uses a custom HTTPFlowLogger: Built using SwiftNIO library (NIO HTTP1) Parses up to HTTP/1.1 traffic Handles streaming, headers, and partial body capture (with size limits) Maintains per-flow state and lifecycle management Logs structured HTTP data via shared IPC c) DNS Proxy (NEDNSProxyProvider) Intercepts UDP DNS traffic Forwards queries to upstream resolver (system DNS or fallback) Maintains shared UDP connection Tracks pending requests using DNS IDs Parses DNS packets (queries + responses) using a custom parser Logs structured DNS metadata via shared IPC Shared Component: IPCConnection Single bidirectional XPC channel used by all providers Handles: App → Extension registration Extension → App logging Uses Mach service defined in system extension entitlements Project Structure NetworkExtension (Project) │ ├── NetworkExtension (Target 1: Main App) │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Info.plist │ ├── NetworkExtension.entitlements │ ├── Main.storyboard │ └──ViewController.swift │ ├── SystemExtensions (Target 2: Extension Process) │ ├── common/ │ │ ├── IPCConnection.swift │ │ └── main.swift │ │ │ ├── DNSProxyProvider/ │ │ ├──DNSDataParser.swift │ │ └──DNSProxyProvider.swift (DNS Proxy) │ │ │ ├── FilterDataProvider/ │ │ └── FilterDataProvider.swift │ │ │ ├── TransparentProxyProvider/ │ │ ├── HTTPLogParser.swift │ │ ├── LogDataModel.swift │ │ └──TransparentProxyProvider.swift │ │ │ ├── Info.plist │ └── SystemExtensions.entitlements │ Current Capabilities Unified logging pipeline across: Socket-level metadata HTTP traffic (HTTP/1.1) DNS queries/responses Efficient log handling using persistent file descriptors Stable IPC communication between app and extensions Flow-level tracking and lifecycle management Selective filtering (e.g., bypass rules for specific IPs) What's the best approach to add TLS Inspection with MITM proxy setup? Some context and constraints: Existing implementation handles HTTP parsing and should remain unchanged (Swift-based). I’m okay with bypassing apps/sites that use certificate pinning (e.g., banking apps) and legitimate sites. Performance is important — I want to avoid high CPU utilization. I’m relatively new to TLS inspection and MITM proxy design. Questions Is it a good idea to implement TLS inspection within a system extension, or does that typically introduce significant complexity and performance overhead? As NETransparentProxyProvider already intercepting HTTPS traffic, can we redirect it to a separate processing pipeline (e.g., another file/module), while keeping the existing HTTP parser(HTTPFlowLogger - HTTP only parser) intact? What are the recommended architectural approaches for adding HTTPS parsing via MITM in a performant way? Are there best practices for selectively bypassing pinned or sensitive domains while still inspecting other traffic? Any guidance on avoiding common pitfalls (e.g., certificate handling, connection reuse, latency issues)? I’m looking for a clean, maintainable approach to integrate HTTPS inspection into my existing system without unnecessary complexity or performance degradation. Please let me know if any additional details from my side would help in suggesting the most appropriate approach. Thanks in advance for your time and insights—I really appreciate it.
5
0
273
3w
Clarification on HealthKit Observer Delivery Frequency and BGTaskScheduler Behavior
Hi Team, We are implementing HealthKit data sync using HKObserverQuery along with enableBackgroundDelivery and BGTaskScheduler for fallback processing. However, we are observing inconsistent behavior and would like clarification on expected system behavior: For HKObserverQuery: When using enableBackgroundDelivery with frequency .immediate, we sometimes receive updates promptly, but other times we do not receive any trigger at all. Similarly, when using .hourly, our expectation was that updates would be delivered approximately once per hour, but in practice, triggers are delayed, batched, or skipped. For BGTaskScheduler: We are scheduling BGAppRefreshTask with earliestBeginDate set (e.g., 1 hour), but tasks are sometimes delayed by several hours or not triggered predictably. In some cases, tasks are not executed even after extended periods. We would like to understand: Are HKObserverQuery delivery frequencies (.immediate, .hourly, .daily) strictly best-effort hints rather than guaranteed intervals? Under what conditions can observer updates be skipped or significantly delayed? Is there any recommended approach to ensure more reliable periodic syncing of HealthKit data? For BGTaskScheduler, what factors most strongly influence scheduling delays or missed executions? Our goal is to design a reliable sync mechanism, but the lack of deterministic behavior is making it difficult to define expected system behavior. Any clarification or recommended best practices would be greatly appreciated. Thanks in advance!
1
0
171
3w
HKAnchoredObjectQuery ignores "no correlation" predicate in updateHandler
Hello, I'm seeing an inconsistency in how HKAnchoredObjectQuery applies predicates between its initial results handler and its update handler. Specifically, predicates that filter quantity samples by correlation membership - using either HKQuery.predicateForObjectsWithNoCorrelation() or NSPredicate(format: "%K == nil", HKPredicateKeyPathCorrelation) - are respected in the resultsHandler but silently ignored in the updateHandler. Setup I have three long-running HKAnchoredObjectQuery instances: One for HKCorrelationType(.bloodPressure) - no predicate One for HKQuantityType(.bloodPressureSystolic) - predicate: HKQuery.predicateForObjectsWithNoCorrelation() One for HKQuantityType(.bloodPressureDiastolic) - predicate: HKQuery.predicateForObjectsWithNoCorrelation() The intent of the predicate on the systolic/diastolic queries is to capture only standalone quantity samples written directly by third-party apps - not the constituent sub-samples of an HKCorrelation. The correlation query handles correlated samples. Expected behavior When a BloodPressure correlation is saved to the store, only the correlation query's updateHandler should fire, with 1 new sample. The systolic and diastolic updateHandlers should not fire, since those samples have correlation != nil which is excluded by the predicate. Actual behavior After saving one BloodPressure correlation, all three updateHandlers fire with 1 new object each. The systolic and diastolic update handlers receive the correlated sub-samples despite the predicateForObjectsWithNoCorrelation() predicate. The same predicate correctly filters those kinds of samples out of the initial resultsHandler. Additionally, the same predicate applied in a one-shot HKSampleQuery for the systolic or diastolic type correctly returns 0 results when only correlated readings exist. The problem is only experienced in updateHandler of a long-running HKAnchoredObjectQuery. Tested iOS versions iOS 26.3 iOS 18.7.6 Workaround When an HKAnchoredObjectQuery updateHandler fires with systolic or diastolic samples, I fire a one-shot HKSampleQuery with a compound predicate using the sample UUIDs and predicateForObjectsWithNoCorrelation. Any samples that are part of a correlation are not returned in the HKSampleQuery resultsHandler.
1
0
170
3w
adding CarPlay extension to iOS app
hello last year at the WWDC Apple announced a app extension for audio playback in CarPlay for iOS apps is there a guide to add this feature because whenever I open my custom music I can hear the music playing trough the car's speakers and I see the album art, but I have no controls on the display of the car the person I white this app for is a indie producer who wants his huge collection to be available for people to enjoy there is no subscription of login
1
0
41
3w
Korea subscription consent: Timing mismatch between push notifications and Settings consent option
Hi all, I've been observing what appears to be a timing mismatch in how Apple handles Korea trial-to-paid consent, and I wanted to see if other developers are seeing the same thing. Per Korean regulations effective Feb 14, 2025, Apple must obtain explicit user consent before converting a free trial to a paid subscription. Apple handles this via email, push notifications, and an in-app consent option accessible from Settings > Subscriptions. For a 7-day trial in the Republic of Korea storefront, I'm observing: Consent push notifications (Agree to continue your subscription without interruption) start arriving ~1 day after trial redemption, at roughly hourly frequency. However, when the user taps the push and navigates to Settings > Subscriptions, there is no consent option available. The only visible action is "Cancel Free Trial". The consent option only becomes available around day 4 of the trial (i.e., 3 days before renewal, matching Apple's documented messaging cadence [1]). For the first ~3 days, users receive hourly push notifications they cannot act on. The only way to stop them is to cancel the subscription entirely. This is happening across multiple apps in the Korean App Store, so it appears to be a platform-level behavior rather than an app-specific issue. Is anyone else observing this behavior? Any insight from Apple engineers or other developers would be greatly appreciated. [1] https://developer.apple.com/help/app-store-connect/reference/in-app-purchases-and-subscriptions/consent-for-subscription-offer-conversions
1
0
208
3w
External purchase region
Hi everyone, I have a question regarding App Store subscriptions and tax country / storefront changes. If a customer originally purchased a subscription while their App Store country was France (so we reported France as the tax country), and later updates or renews that same subscription while located in Hungary, which country should we report going forward? Should we continue using the original country (France)? Or should we start sending the new country (Hungary) once it changes? Also, what happens if the customer changes their App Store region entirely, for example from France to the US? How is Apple’s commission calculated after the region change? If anyone has experience with this scenario or knows the official Apple behavior, I’d really appreciate your help. Thanks!
Replies
2
Boosts
0
Views
187
Activity
2w
Family Controls (Distribution)
It has been five days since we applied for Family Controls (Distribution) permission, but the status still shows as Submitted. Is there any way to expedite the review process?
Replies
2
Boosts
1
Views
165
Activity
2w
State of Mind and the free text: Can it be fetched?
Has anyone actually managed to read the free-text note/context from Apple Health State of Mind entries? I’m building an iOS app that reads HKStateOfMind data from HealthKit. I can get the expected stuff fine: valence labels associations But in the Health app, users can also add extra context text to a mood entry, like: Tasks, Weather - Great work-life balance From my app, I can read Tasks and Weather, but I can’t find the Great work-life balance part anywhere. I already checked: public HKStateOfMind properties metadata debug description / object description attachment-ish routes Nothing so far. So before I spend more time chasing this: is that text just not exposed to third-party apps? Or is there some weird HealthKit path I’m missing? If anyone has actually pulled this off, I’d love to know how.
Replies
0
Boosts
0
Views
127
Activity
2w
how to store secret key in/for system extension
Hi. I have a private cryptographic key that I want to generate and store for use by the system extension only (a network extension NETransparentProxyProvider). The ideal properties I want is: only accessible by extension never leave extension not be accessible by root user or other apps Here is what I have tried so far (by/within the system extension): app data container / local storage: this works, but is accessible by root user app data shared container (storage): this works, but also acccessible by root user system keyring: works, but also accesible by root user System extension by itself does not seem to be able to store/load secrets in app protected keyring. The host application however can store in app protected keyring.... So I though, let's use an app group (as access group) and have it like this shared between host and (system) extension... but nop... (system) extension cannot access the secret... Ok... so than I thought: manual low-level XPC calls.... Also that doesn't work, got something almost to work but seemed to require an entire 3rd (launchd/daemon) service.... way to complex for what I want... also seems that as a root user I can use debug tools to also access it There is however the SendMessage/HandleMessage thing available for TransparentProxy.... that does work... but (1) also doesn't seem the most secure (2) the docs clearly state cannot rely on that for this state as the system extension can be started while the host app is not active.... (e.g. at startup) So that is not a solution either.... I went in so many different directions and rabbit holes in the last days.... this feels like a lot harder than it should be? How do other VPN/Proxy like solutions store secrets that are unique to an extension???? I am hoping there is something available here that I am simply missing despite all my effort... any guidance greatly appreciated...
Replies
5
Boosts
0
Views
231
Activity
2w
Family Controls Entitlement for Extension Identifiers
I've already submitted multiple cases about this issue. My Family Controls Distribution request was apparently approved (or I was told via Developer Support) for my Shield Action & Shield Configuration extensions, but the Distribution option still does not appear in the identifiers. This is blocking my ability to distribute via TestFlight. I need someone who can update the identifier capabilities or explain why the approved capability is not showing.
Replies
1
Boosts
0
Views
142
Activity
2w
Reclaiming cached data from an `enumerateDirectory` call
If I'm in an enumerateDirectory call, I can very quickly fill in the fileID, parentID, and (maybe) the type attributes based on the directory entry I have loaded. That is, I can quickly fill in anything that is contained in the dirent structure in dirent.h, plus the parentID. However, if any other attributes are requested (say, flags), or if the file system doesn't store the filetype in the directory entry, then I need to do additional I/O and load an inode. If I have to load an inode, I might keep a reference to it and assume that I can clean it up later whenever there is a matching call to reclaimItem. But in the enumerateDirectory call, I never provide an FSItem to the system! By observation, I see that normally, a call to enumerateDirectory of this nature is followed up by a lookupItem call for every single fetched item, and then assumedly the system can later reclaim it if need be. At least, I tried various ways of listing directories, and each way I tried showed this behavior. If that's the case, then I can rely on a later reclaimItem call telling me when to clean up this cached data from memory. Is this guaranteed, however? I don't see a mention of this in the documentation, so I'm not sure if I can rely on this. Or, do I need to handle a case where, if I do additional I/O after enumerateDirectory, I might need to figure out when cached data should be cleaned up to avoid a "leak?" (Using the term "leak" loosely here, since in theory looking up the file later would make it reclaimable, but perhaps that might not happen.)
Replies
6
Boosts
0
Views
378
Activity
2w
Can't enter sandbox environment for IAP testing on any of my apps - always getting -100 error with no [Environment: Sandbox] indicator
Body: I'm experiencing a persistent issue that has affected multiple apps I've developed, and I'm hoping to get some guidance from the community or Apple engineers. The Problem: When testing In-App Purchases, my app never enters the sandbox environment. The payment prompt does NOT show the "[Environment: Sandbox]" indicator, and I always receive error code -100 (Invalid Product Identifier). This issue has occurred across multiple apps I've built, including a previous app that I ultimately had to release as a paid download (rather than freemium with IAP) because I couldn't resolve this same problem. Now I'm facing the identical issue with my new app, "AI Job Assistant". What I've Checked (all correct): ✅ Paid App Agreement status is "Active" in App Store Connect ✅ Bundle ID matches exactly between Xcode/HBuilderX and App Store Connect ✅ Product IDs in code match those created in App Store Connect (case-sensitive, no spaces) ✅ All IAP products have complete metadata (name, description, pricing, 640x920 screenshot) ✅ Product status is "Ready to Submit" (not "Waiting for Review") ✅ I have both iOS Development certificate and iOS Distribution certificate — I am using the Development certificate for testing ✅ My provisioning profile is explicitly for Development (named "aijobDevprofile", shows "iOS Development" type) ✅ The Development profile contains my test device UDID ✅ I have fully signed out of my real Apple ID in Settings → Media & Purchases ✅ I only log into my Sandbox Tester account through the purchase prompt (not in Settings) ✅ I test on a real device (not simulator) ✅ I have tried creating multiple new Sandbox Tester accounts ✅ I have tried toggling "Cleared for Sale" off and on for all products ✅ I have waited over 24 hours after making configuration changes What I See: When I initiate a purchase, the payment prompt comes up but there is NO "[Environment: Sandbox]" text anywhere After entering my Sandbox Tester credentials, the request fails with error code -100 (Invalid Product Identifier) My Setup: Development framework: uni-app / HBuilderX (custom debug base with Development certificate and Development provisioning profile) Backend: Cloudflare Workers (handles receipt verification) Testing device: iPhone (latest iOS version) The same issue occurred with my previous app, which I never resolved and eventually gave up on IAP entirely Question: Why does my app never enter the sandbox environment despite using the correct Development certificate and Development provisioning profile? Is it possible there is an issue at the Apple developer account level that is preventing sandbox environment activation? How can I force my debug builds to connect to sandbox instead of production? I am willing to provide any additional logs or information needed. Please help. Thank you.
Replies
0
Boosts
0
Views
167
Activity
2w
Applinks for any subdomain not opening the app
My Entitlements file contains the following (removed some non related entries): <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.associated-domains</key> <array> <string>webcredentials:app.mydomain.org</string> <string>applinks:*.mydomain.org</string> </array> </dict> </plist> Now when I tap on a link such as abc.mydomain.org, the app is not opened. If I change the generic applinks key from *.mydomain.org to a specific domain, this works correctly and it opens the app as expected. (This makes me think the website part of the AASA file is correct). Since I need to support a lot of subdomains (think about hundreds in the near future), I really need the wildcard to work. Do you have any tips on how to make this work?
Replies
0
Boosts
0
Views
70
Activity
3w
EAAccessoryManager Crash when selecting accessory from picker while multiple accessories are present
The app crashes when using EAAccessoryManager.showBluetoothAccessoryPicker(withNameFilter:) to connect to a Bluetooth accessory in a multi-accessory scenario. The crash occurs immediately after selecting an accessory from the picker UI. Steps to Reproduce: Ensure a Bluetooth accessory (Accessory A) is already connected to the iPhone/iPad and is visible in Bluetooth settings. Launch the app. Initiate a connection flow that presents the Bluetooth accessory picker using EAAccessoryManager.showBluetoothAccessoryPicker(withNameFilter:). Ensure another compatible accessory (Accessory B) is available and visible in the picker. Select Accessory B from the picker to connect. After connection, simulate a disconnect of Accessory B (e.g., power cycle or remove battery). Attempt to reconnect Accessory B by triggering the same picker flow again. Select Accessory B from the picker. Result: The accessory connects successfully at the system level. The app crashes immediately after selecting the accessory from the picker (during dismissal). Reproducibility: Occurs consistently under the described multi-accessory scenario. Not observed when only a single accessory is present.
Replies
5
Boosts
0
Views
267
Activity
3w
macOS Preview appears to hold MTP devices open indefinitely
I am developing a USB MTP device for use with macOS. When the device is connected while Preview is running, I observe the host send OpenSession, then GetDeviceInfo, and then no further MTP commands. I do not see a later CloseSession. Problem is that once this happens, exclusive access to the USB interface is retained, so another application cannot connect to the device. From the device side, there is no obvious way to recover except forcing a USB disconnect/reset or shutting down the USB interface. My questions are: Is this expected behavior for Preview, or for a Preview-related macOS helper? Is it expected on macOS that a client may open an MTP session and then leave it idle without sending CloseSession? I am mainly trying to understand whether this is expected macOS behavior, or whether this should be considered a bug.
Replies
3
Boosts
0
Views
184
Activity
3w
AppTransaction.originalAppVersion returns "1.0" in App Review environment — not the actual build number
Hi, I'm using AppTransaction.originalAppVersion to detect whether a user originally purchased the app under the old paid model, so I can automatically unlock the app for them as a courtesy when migrating to freemium. Background On iOS, originalAppVersion returns CFBundleVersion (the build number). When I transitioned the app from paid (v1.x) to freemium (v2.0), I defined a numeric threshold for CFBundleVersion to distinguish legacy purchasers from new users: Build number below the threshold → v1.x purchase → auto-unlock Build number at or above the threshold → v2.0+ install → requires IAP In Production, originalAppVersion correctly returns the actual build number, and the comparison works as intended. Detection logic (simplified) // Determine environment via receipt URL func detectStoreEnvironment() -> String { if let url = Bundle.main.appStoreReceiptURL, url.lastPathComponent == "sandboxReceipt" { return "Sandbox" } return "Production" } // Legacy check using numeric comparison static func isLegacyPaidUser(version: String, threshold: String) -> Bool { guard !version.isEmpty else { return false } return version.compare(threshold, options: .numeric) == .orderedAscending } // In checkLegacyPurchase(): let version = appTransaction.originalAppVersion let isLegacy = isLegacyPaidUser(version: version, threshold: legacyBuildNumberThreshold) let env = detectStoreEnvironment() let shouldAutoUnlock = isLegacy && env != "Sandbox" The problem I know that in the Sandbox environment, originalAppVersion always returns "1.0" — this is mentioned in the AppTransaction documentation. My code already suppresses the auto-unlock for Sandbox (env != "Sandbox"). However, it appears that the App Review environment also returns "1.0" for originalAppVersion. Because the receipt URL path component is "receipt" (not "sandboxReceipt"), my environment detection classifies it as "Production" — so the Sandbox suppression doesn't apply. The reviewer is incorrectly identified as a legacy paid user and the app is unlocked without a purchase. This caused our v2.0 submission to be rejected under Guideline 2.1a. Questions Is it documented that the App Review environment returns "1.0" for AppTransaction.originalAppVersion, similar to Sandbox? Is there a reliable way to detect the App Review environment specifically — separate from both Sandbox and Production? For example, does the receipt URL differ, or is there another API? Is using originalAppVersion for legacy paid-user detection a supported pattern? If so, what is the recommended approach to handle the App Review case? Any guidance would be greatly appreciated. Thank you.
Replies
0
Boosts
0
Views
92
Activity
3w
WeatherKit JWT token generation fails with WDSJWTAuthenticator Code=2 despite correct entitlement
I enabled the WeatherKit capability on my App ID (com.saimcan.darkweather, Team 6SWSD6V4ZC) about 12 hours ago. The entitlement is embedded in the binary and the provisioning profile authorizes it, but every request fails at the JWT generation step. Error from the logs: Error Domain=WeatherDaemon.WDSJWTAuthenticatorServiceListener.Errors Code=2 "(null)" Relevant log excerpt (iOS 26.4 Simulator, same result on a physical device): [AuthService] Calling process is 3rd party process and has the correct entitlement ... accepting the connection [AuthService] Received proxy request for generating a jwt token. url=https://weatherkit.apple.com [WeatherDataService] Starting to generate JWT token request. bundleIdentifier=com.saimcan.darkweather [AuthService] Signed successfully [WeatherDataService] Make new JWT token request. requestIdentifier=... [AuthService] Failed to generate jwt token ... Code=2 What I have verified: Active Apple Developer Program membership (renewed through April 2027) All agreements accepted WeatherKit capability enabled on the App ID codesign -d --entitlements confirms com.apple.developer.weatherkit in the built binary embedded.mobileprovision also includes com.apple.developer.weatherkit App Group (group.com.saimcan.darkweather.shared) correctly bound to both the app and widget App IDs Since "Signed successfully" is logged, the device-side auth plumbing is working. The rejection appears to be server-side. Could someone from the WeatherKit team check whether JWT minting is enabled for this Team ID / Bundle ID? Team ID: 6SWSD6V4ZC Bundle ID: com.saimcan.darkweather
Replies
2
Boosts
1
Views
156
Activity
3w
DeviceActivityReport extension not discovered at runtime (ClientError Code=2)
Hi I am trying to implement a minimal DeviceActivityReport extension. Setup: iOS app with FamilyControls authorization (status = approved) DeviceActivityReport displayed in SwiftUI Report extension embedded in PlugIns Correct NSExtensionPointIdentifier: com.apple.deviceactivityui.report-extension No NSExtensionPrincipalClass or storyboard Entitlements: com.apple.developer.family-controls com.apple.developer.family-controls.app-and-website-usage The app installs and runs correctly. Authorization is granted. However, the extension is never loaded: No logs from the extension (init/body/makeConfiguration never called) Console shows: "Failed to discover the client's extension: DeviceActivityReportService... ClientError Code=2" Environment: Xcode 16.2 iOS device running iOS 18.x (latest available) The .appex is correctly embedded and signed. Question: Is there a known issue with DeviceActivityReport extensions not being discovered at runtime with this setup? Is additional configuration required beyond NSExtensionPointIdentifier? Thanks
Replies
2
Boosts
0
Views
215
Activity
3w
Tap to Pay on iPhone – Provisioning profile missing entitlement when uploading to TestFlight
Hi everyone, I’m currently implementing Tap to Pay on iPhone following Apple’s official documentation. I’ve completed all the required configurations (entitlements, capabilities, merchant setup, etc.) on the Apple Developer portal. However, when I archive the app and attempt to upload it to TestFlight, I receive the following error: "Profile doesn't support Tap to Pay on iPhone. Profile doesn't include the com.apple.developer.proximity-reader.payment.acceptance entitlement." From what I understand, this seems related to the provisioning profile not including the required entitlement, even though I believe everything has been configured correctly. I have already tried: Regenerating provisioning profiles Verifying App ID capabilities Ensuring the correct entitlements are added in the project But the issue still persists. Has anyone encountered this issue before? Is there any additional approval step required from Apple to enable the Tap to Pay entitlement? I’d really appreciate any advice or experience you can share. Thanks in advance!
Replies
1
Boosts
0
Views
214
Activity
3w
TLS Inspection with MITM Proxy setup for System Extension app in macOS
Hi All, I am working on a macOS System Extension using Apple’s Network Extension Framework, designed to observe and log network activity at multiple layers. The system extension is currently stable and working as expected for HTTP and DNS traffic with 3 providers, getting Socket, HTTP, and DNS logs. Current Architecture Overview The project consists of two Xcode targets: 1. Main App Process Responsible for: Managing system extension lifecycle (activation, configuration) Establishing IPC (XPC) communication with extensions Receiving structured logs from extensions Writing logs efficiently to disk using a persistent file handle Uses: OSSystemExtensionManager NEFilterManager, NETransparentProxyManager, NEDNSProxyManager NWPathMonitor for network availability handling Persistent logging mechanism (FileHandle) 2. System Extension Process Contains three providers, all running within a single system extension process: a) Content Filter (NEFilterDataProvider) Captures socket-level metadata Extracts: PID via audit token Local/remote endpoints Protocol (TCP/UDP, IPv4/IPv6) Direction (inbound/outbound) Sends structured JSON logs via shared IPC b) Transparent Proxy (NETransparentProxyProvider) Intercepts TCP flows Creates a corresponding NWConnection to the destination Captures both HTTP and HTTPS traffic, sends it to HTTPFlowLogger file which bypasses if it's not HTTP traffic. Uses a custom HTTPFlowLogger: Built using SwiftNIO library (NIO HTTP1) Parses up to HTTP/1.1 traffic Handles streaming, headers, and partial body capture (with size limits) Maintains per-flow state and lifecycle management Logs structured HTTP data via shared IPC c) DNS Proxy (NEDNSProxyProvider) Intercepts UDP DNS traffic Forwards queries to upstream resolver (system DNS or fallback) Maintains shared UDP connection Tracks pending requests using DNS IDs Parses DNS packets (queries + responses) using a custom parser Logs structured DNS metadata via shared IPC Shared Component: IPCConnection Single bidirectional XPC channel used by all providers Handles: App → Extension registration Extension → App logging Uses Mach service defined in system extension entitlements Project Structure NetworkExtension (Project) │ ├── NetworkExtension (Target 1: Main App) │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── Info.plist │ ├── NetworkExtension.entitlements │ ├── Main.storyboard │ └──ViewController.swift │ ├── SystemExtensions (Target 2: Extension Process) │ ├── common/ │ │ ├── IPCConnection.swift │ │ └── main.swift │ │ │ ├── DNSProxyProvider/ │ │ ├──DNSDataParser.swift │ │ └──DNSProxyProvider.swift (DNS Proxy) │ │ │ ├── FilterDataProvider/ │ │ └── FilterDataProvider.swift │ │ │ ├── TransparentProxyProvider/ │ │ ├── HTTPLogParser.swift │ │ ├── LogDataModel.swift │ │ └──TransparentProxyProvider.swift │ │ │ ├── Info.plist │ └── SystemExtensions.entitlements │ Current Capabilities Unified logging pipeline across: Socket-level metadata HTTP traffic (HTTP/1.1) DNS queries/responses Efficient log handling using persistent file descriptors Stable IPC communication between app and extensions Flow-level tracking and lifecycle management Selective filtering (e.g., bypass rules for specific IPs) What's the best approach to add TLS Inspection with MITM proxy setup? Some context and constraints: Existing implementation handles HTTP parsing and should remain unchanged (Swift-based). I’m okay with bypassing apps/sites that use certificate pinning (e.g., banking apps) and legitimate sites. Performance is important — I want to avoid high CPU utilization. I’m relatively new to TLS inspection and MITM proxy design. Questions Is it a good idea to implement TLS inspection within a system extension, or does that typically introduce significant complexity and performance overhead? As NETransparentProxyProvider already intercepting HTTPS traffic, can we redirect it to a separate processing pipeline (e.g., another file/module), while keeping the existing HTTP parser(HTTPFlowLogger - HTTP only parser) intact? What are the recommended architectural approaches for adding HTTPS parsing via MITM in a performant way? Are there best practices for selectively bypassing pinned or sensitive domains while still inspecting other traffic? Any guidance on avoiding common pitfalls (e.g., certificate handling, connection reuse, latency issues)? I’m looking for a clean, maintainable approach to integrate HTTPS inspection into my existing system without unnecessary complexity or performance degradation. Please let me know if any additional details from my side would help in suggesting the most appropriate approach. Thanks in advance for your time and insights—I really appreciate it.
Replies
5
Boosts
0
Views
273
Activity
3w
Clarification on HealthKit Observer Delivery Frequency and BGTaskScheduler Behavior
Hi Team, We are implementing HealthKit data sync using HKObserverQuery along with enableBackgroundDelivery and BGTaskScheduler for fallback processing. However, we are observing inconsistent behavior and would like clarification on expected system behavior: For HKObserverQuery: When using enableBackgroundDelivery with frequency .immediate, we sometimes receive updates promptly, but other times we do not receive any trigger at all. Similarly, when using .hourly, our expectation was that updates would be delivered approximately once per hour, but in practice, triggers are delayed, batched, or skipped. For BGTaskScheduler: We are scheduling BGAppRefreshTask with earliestBeginDate set (e.g., 1 hour), but tasks are sometimes delayed by several hours or not triggered predictably. In some cases, tasks are not executed even after extended periods. We would like to understand: Are HKObserverQuery delivery frequencies (.immediate, .hourly, .daily) strictly best-effort hints rather than guaranteed intervals? Under what conditions can observer updates be skipped or significantly delayed? Is there any recommended approach to ensure more reliable periodic syncing of HealthKit data? For BGTaskScheduler, what factors most strongly influence scheduling delays or missed executions? Our goal is to design a reliable sync mechanism, but the lack of deterministic behavior is making it difficult to define expected system behavior. Any clarification or recommended best practices would be greatly appreciated. Thanks in advance!
Replies
1
Boosts
0
Views
171
Activity
3w
HKAnchoredObjectQuery ignores "no correlation" predicate in updateHandler
Hello, I'm seeing an inconsistency in how HKAnchoredObjectQuery applies predicates between its initial results handler and its update handler. Specifically, predicates that filter quantity samples by correlation membership - using either HKQuery.predicateForObjectsWithNoCorrelation() or NSPredicate(format: "%K == nil", HKPredicateKeyPathCorrelation) - are respected in the resultsHandler but silently ignored in the updateHandler. Setup I have three long-running HKAnchoredObjectQuery instances: One for HKCorrelationType(.bloodPressure) - no predicate One for HKQuantityType(.bloodPressureSystolic) - predicate: HKQuery.predicateForObjectsWithNoCorrelation() One for HKQuantityType(.bloodPressureDiastolic) - predicate: HKQuery.predicateForObjectsWithNoCorrelation() The intent of the predicate on the systolic/diastolic queries is to capture only standalone quantity samples written directly by third-party apps - not the constituent sub-samples of an HKCorrelation. The correlation query handles correlated samples. Expected behavior When a BloodPressure correlation is saved to the store, only the correlation query's updateHandler should fire, with 1 new sample. The systolic and diastolic updateHandlers should not fire, since those samples have correlation != nil which is excluded by the predicate. Actual behavior After saving one BloodPressure correlation, all three updateHandlers fire with 1 new object each. The systolic and diastolic update handlers receive the correlated sub-samples despite the predicateForObjectsWithNoCorrelation() predicate. The same predicate correctly filters those kinds of samples out of the initial resultsHandler. Additionally, the same predicate applied in a one-shot HKSampleQuery for the systolic or diastolic type correctly returns 0 results when only correlated readings exist. The problem is only experienced in updateHandler of a long-running HKAnchoredObjectQuery. Tested iOS versions iOS 26.3 iOS 18.7.6 Workaround When an HKAnchoredObjectQuery updateHandler fires with systolic or diastolic samples, I fire a one-shot HKSampleQuery with a compound predicate using the sample UUIDs and predicateForObjectsWithNoCorrelation. Any samples that are part of a correlation are not returned in the HKSampleQuery resultsHandler.
Replies
1
Boosts
0
Views
170
Activity
3w
Age Verification testing in TestFlight
Hi, We have implemented Age Verification in iOS and wanted to test the workflow before releasing the app. How do we test the app before releasing it in production. We currently use Test Flight for testing. We created users in Sandbox but that shows just Texas in Age Assurance.
Replies
1
Boosts
0
Views
132
Activity
3w
adding CarPlay extension to iOS app
hello last year at the WWDC Apple announced a app extension for audio playback in CarPlay for iOS apps is there a guide to add this feature because whenever I open my custom music I can hear the music playing trough the car's speakers and I see the album art, but I have no controls on the display of the car the person I white this app for is a indie producer who wants his huge collection to be available for people to enjoy there is no subscription of login
Replies
1
Boosts
0
Views
41
Activity
3w
Korea subscription consent: Timing mismatch between push notifications and Settings consent option
Hi all, I've been observing what appears to be a timing mismatch in how Apple handles Korea trial-to-paid consent, and I wanted to see if other developers are seeing the same thing. Per Korean regulations effective Feb 14, 2025, Apple must obtain explicit user consent before converting a free trial to a paid subscription. Apple handles this via email, push notifications, and an in-app consent option accessible from Settings > Subscriptions. For a 7-day trial in the Republic of Korea storefront, I'm observing: Consent push notifications (Agree to continue your subscription without interruption) start arriving ~1 day after trial redemption, at roughly hourly frequency. However, when the user taps the push and navigates to Settings > Subscriptions, there is no consent option available. The only visible action is "Cancel Free Trial". The consent option only becomes available around day 4 of the trial (i.e., 3 days before renewal, matching Apple's documented messaging cadence [1]). For the first ~3 days, users receive hourly push notifications they cannot act on. The only way to stop them is to cancel the subscription entirely. This is happening across multiple apps in the Korean App Store, so it appears to be a platform-level behavior rather than an app-specific issue. Is anyone else observing this behavior? Any insight from Apple engineers or other developers would be greatly appreciated. [1] https://developer.apple.com/help/app-store-connect/reference/in-app-purchases-and-subscriptions/consent-for-subscription-offer-conversions
Replies
1
Boosts
0
Views
208
Activity
3w