Posts under App & System Services topic

Post

Replies

Boosts

Views

Activity

App Store Server API: originalTransactionId stability across expiration and resubscription
DTS recommended that we post this question in the Developer Forums. We would like clarification on the supported production behavior of originalTransactionId in the App Store Server API, particularly after a subscription expires and the customer resubscribes. Our main backend design question is: Can we continue using a stored originalTransactionId to identify and retrieve subsequent subscription activity within the same subscription group, or must we support discovering and associating new identifiers? Integration context Our backend uses: GET /inApps/v1/subscriptions/{transactionId} GET /inApps/v2/history/{transactionId} App and subscription details: Bundle ID: com.lgeha.nuts Subscription group identifier: 22350255 Product A: thinq_g_unlimitedpro Product B: thinq_g_single We use originalTransactionId as a key for subscription records and associate those records with user accounts in our service. We do not use it as an identifier for the Apple Account itself. Please assume the same Apple Account and app, with both products in the same subscription group, using ordinary auto-renewable subscriptions without a special subscription migration. This question concerns the identifiers and lookup behavior exposed to our backend by the App Store Server API. Sandbox observation and scope During sandbox testing, purchase history was cleared, and a new originalTransactionId was subsequently observed. We understand that this observation involved a sandbox history reset and does not establish production behavior. Our questions below concern production behavior without any purchase-history reset. Preservation across subscription lifecycle events For each scenario below, is originalTransactionId guaranteed to remain unchanged for subsequent transactions, or can Apple assign a different value? Automatic renewal of the same product. An upgrade, downgrade, or crossgrade between products A and B while the subscription is active. Turning off automatic renewal, then re-enabling it before expiration. Turning off automatic renewal, allowing the subscription to expire, and later resubscribing to the same product. Turning off automatic renewal for product A, allowing it to expire, and later subscribing to product B within the same subscription group. Scenarios 4 and 5 are our primary concern. We would like to distinguish commonly observed behavior from supported guarantees that a backend can rely on. Conditions for a new identifier after expiration For scenarios 4 and 5, can a new purchase legitimately receive a different originalTransactionId in production despite the Apple Account, app, and subscription group remaining unchanged? If so, what conditions determine this? Does it depend on: Time elapsed since expiration. Billing retry or billing grace-period status or history. Whether the purchase uses StoreKit 1 or StoreKit 2. Whether the customer resubscribes inside the app or through App Store subscription management. Our concern is whether these factors affect the identifiers subsequently returned by the App Store Server API. Stability of an existing transaction Separately from a new purchase receiving a new identifier, if the same transactionId is retrieved at two different times, is its associated originalTransactionId guaranteed to remain unchanged? Can an Apple-supported correction process change that association, or should such a result be treated as an inconsistency and reported through Feedback Assistant? This question concerns the same returned transactionId, rather than a different latest transaction returned by a subsequent status query. We have not confirmed such a change in production. Lookup behavior using a previously stored identifier If resubscription can create a new originalTransactionId, how does that affect each endpoint? For GET /inApps/v1/subscriptions/{transactionId}: Can a request using the previous originalTransactionId return the current status of a later resubscription with a different originalTransactionId, assuming the same Apple Account, app, and subscription group? Or must the backend obtain the new identifier separately? For GET /inApps/v2/history/{transactionId}: Can a request using the previous originalTransactionId return transactions from that later resubscription, assuming all applicable pages are retrieved and no filters exclude those transactions? Please clarify any endpoint-specific guarantees or limitations on using an older identifier to discover subsequent subscription activity. Backend account association If resubscription can create a new identifier, should our backend support multiple originalTransactionId values for one service user within the same subscription group? Is there a documented server-side relationship that links subscriptions with different originalTransactionId values? Alternatively, should that association rely on an application-managed identifier such as appAccountToken, where available? Please clarify any limitations, especially for resubscriptions initiated outside the app. Related discussions We reviewed these discussions as background: Transaction ID Misassociation in IAP Subscription API (https://developer.apple.com/forums/thread/777433) original_transaction_id associated to web_order_line_item_id of auto-renewable subscription changed (https://developer.apple.com/forums/thread/778301) We do not assume that these reports establish supported behavior or share the cause of our sandbox observation. Could Apple clarify the supported preservation or replacement rules, particularly after expiration and resubscription, and point us to documentation describing the behavior a backend can rely on? If investigating a specific inconsistency requires a separate Feedback Assistant report, please indicate which server-side request and response details should be included. Thank you.
1
0
417
2d
How can a macOS application establish that an open APFS file has no extended ACL?
On macOS 26.5.2 (build 25F84), which documented API and return conditions, if any, establish that a regular file on APFS has no extended access control list (ACL), using an already-open file descriptor? We tested three disposable regular files on an APFS volume reporting ACL support. For each file, we opened a read-only file descriptor and called: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) fgetattrlist() requesting ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY Before and after inspection, fstat() confirmed stable device, inode, mode, and change timestamp. Observed results: 1. Newly created file, no ACL explicitly assigned acl_get_fd_np() returned NULL with errno == ENOENT. fgetattrlist() succeeded but omitted ATTR_CMN_EXTENDED_SECURITY from the returned attribute mask. FSOPT_PACK_INVAL_ATTRS also left that bit clear. 2. File with an explicitly assigned empty ACL acl_get_fd_np() returned NULL with errno == ENOENT. fgetattrlist() returned the extended-security attribute with an ACL entry count of zero. 3. File with one explicit ACL entry acl_get_fd_np() returned a non-null ACL. fgetattrlist() returned the extended-security attribute with an ACL entry count of one. Apple's published XNU attribute-packing implementation appears to use the same omission branch when ACL metadata is unsupported or when the ACL pointer is null. My question: Is there a supported descriptor-based API sequence that reliably distinguishes: Genuine absence of an extended ACL Unavailable or unsupported per-file ACL metadata An ACL retrieval failure If so, which API, capability checks, return values, attribute bits, or error conditions should a caller rely on? Are there relevant APFS or macOS version limitations? If the public API cannot establish ACL absence unambiguously in this situation, confirmation of that limitation would also be helpful. Thank you for your guidance.
2
0
52
2d
macOS: How to reliably verify the absence of an extended ACL using a file descriptor?
We are implementing a fail-closed security check for a directory opened through a file descriptor on macOS. We need to reliably distinguish between: No extended ACL is present. An extended ACL is present but contains zero entries. ACL retrieval failed or is unsupported. Observed behavior For an existing directory with mode 0700: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) returns NULL with errno == ENOENT. acl_get_file(path, ACL_TYPE_EXTENDED) returns NULL with errno == ENOENT. fstat() and lstat() agree on the device and inode. The directory exists and can be opened successfully. ls -ldeO@ displays no extended ACL entries. We reviewed Apple's open-source implementations of acl_get_fd_np() and filesec_get_property(). We understand that ENOENT can result from an unavailable FILESEC_ACL property, rather than a missing filesystem object. We also understand that XNU distinguishes an empty ACL from KAUTH_FILESEC_NOACL. Question Is there a publicly supported, file-descriptor-based API with documented postconditions that can reliably prove the absence of an extended ACL, while distinguishing it from an empty ACL and an ACL retrieval failure? Specifically: Can fstatx_np() and filesec_get_property() provide this distinction? Can fgetattrlist() with ATTR_CMN_EXTENDED_SECURITY and ATTR_CMN_RETURNED_ATTRS reliably establish ACL absence? What additional filesystem capability checks or return-value checks are required? If no public API provides this guarantee, is that a documented limitation? For security reasons, our implementation rejects the object whenever ACL absence cannot be established reliably. We would appreciate clarification of the supported API contract and its limitations. Thank you.
1
0
53
2d
How precisely is a predicate evaluated for an HMEventTrigger?
Perhaps I am just stupid, but I can't quite grok that. What object is the predicate evaluated over, how, and at what moment? Originally I've thought when some event causes the trigger to fire, the predicate would just be evaluated over that event; but that can't be that simple, see please details below. I've set (in a 3rd party application; Home, far as I can say, does not allow that) a predicate “only when both of a pair of lights are off”. The predicate works perfectly, and the event really performs its action set only when both of the lights are off, so far so good. Nevertheless, I've dumped the predicate, and it looks like this (the first line is my own dump which is a bit more concise; the 2nd one is the standard description just to make sure that my own dump works properly): (((self.characteristic == 'Power State' of 'Lustr O') && (self.characteristicValue == 0)) && ((self.characteristic == 'Power State' of 'Knihovna') && (self.characteristicValue == 0))) (characteristic == <HMCharacteristic, Unique ID: 2E046807-9127-565F-B9CB-10BC0F2EE6D2, Type: 00000025, Instance ID: 9> AND characteristicValue == 0) AND (characteristic == <HMCharacteristic, Unique ID: 7444CCCE-1C1B-5234-8CAE-01DA4D811B8B, Type: 00000025, Instance ID: 9> AND characteristicValue == 0)I can't understand that at all :( I must be missing something of great importance, but it seems to me that a predicate which can be just as well[1] written as self.characteristic==A && self.characteristic==B && (some other conditions) can't ever evaluate to YES when A and B differ (which they self-evidently do in this case). The “to evaluate before executing the scene” of the documentation does not really help. What do I miss, can anybody explain that? Thanks! [1] Correct me please if I am wrong, but I do believe the logical AND is both an associative and an commutative operator, which makes this re-write fully equivalent to the original.
5
0
101
2d
iOS 27.2 beta: "Couldn't Sync iCloud Data" – Resume Data Sync only offers Delete (FB25408294)
Filed as FB25408294 with sysdiagnose attached. After an Apple battery repair (Aug 28, 2026), my iPhone 15 Pro Max was reset and set up as new. Since then, Settings shows "Some iCloud Data Isn't Syncing." Resume Data Sync asks for my iPhone passcode, loads, then shows "Couldn't Sync iCloud Data" with only Cancel or Delete iCloud Data. iOS 27.2 developer beta Advanced Data Protection: OFF Messages in iCloud: 188 GB stored, but "0 messages" / "Not synced" Same error on my Mac; Apple Watch Ultra can't finish setup because of it Tried current and previous device passcode No Recovery Key or Recovery Contact I have NOT deleted any iCloud data and want to recover it rather than reset it. Is anyone from the iCloud / CloudKit / Keychain team able to look at the FB? Has anyone found a way to get a device back into the iCloud Keychain circle without resetting end-to-end encrypted data?
1
0
35
2d
Is a `flowClosed` report guaranteed when the owning process exits or crashes?
Our macOS NEFilterDataProvider sets shouldReport = true on flow verdicts and receives NEFilterReport.Event.flowClosed in handle(_:). In testing, we have observed close reports after the owning process exits or crashes, sometimes with a short delay. Is a flowClosed report guaranteed for every TCP and UDP flow in these cases? Does the behavior differ by protocol, and is there a documented upper bound on delivery time? We also set statisticsReportFrequency = .low. Does that setting affect only periodic .statistics reports, with no effect on flowClosed delivery?
2
0
89
2d
APNs Delivery Metrics: What Exactly Triggers “Discarded - Disabled”?
Hello, I'm trying to understand the exact meaning of the APNs delivery status Discarded - Disabled shown in Apple's Push Notification Console. According to the status tooltip: Push notifications which were discarded by APNs, because the push feature was disabled for the application on the target device. None of these were saved to APNs storage. However, I'm unable to reproduce this behavior by disabling notifications through iOS Settings. My test scenario I performed the following test on a physical iOS device: Installed our application. Enabled notifications for the application in iOS Settings. Sent a regular visible push notification (alert) from CloudKit console. Checked the individual APNs Delivery Log. The status was Delivered to Device. Disabled notifications for our application through Settings → Notifications → [Our App] → Allow Notifications. Sent another regular visible push notification using the same device token. Checked the individual APNs Delivery Log again. Unexpected result: Despite notifications being disabled in iOS Settings, APNs reported Delivered to Device, not Discarded - Disabled. I'm checking individual notification delivery records, not aggregated metrics. Questions I'd appreciate clarification on the following: What exactly does Apple mean by "the push feature was disabled for the application on the target device"? Does Discarded - Disabled refer to the notification authorization status (UNAuthorizationStatus.denied) or a different device-side state? If disabling notifications through iOS Settings does not trigger this status, what specific user action or device configuration does? Is there a distinction between disabling notification presentation and disabling remote push delivery at the APNs level? Under what exact circumstances does APNs report Discarded - Disabled instead of Delivered to Device? Additional information Push type: alert Notification type: Regular visible notification Device: iPhone 14 iOS version: 27.2 APNs environment: Sandbox My goal is to understand the exact technical conditions that produce Discarded - Disabled, rather than just the general meaning of the status. Has anyone encountered this behavior or received clarification from Apple about this particular APNs delivery status? Thanks!
0
0
45
2d
Import resulting certificate to associate with private key
On macOS I am creating a public/private key pair (ECDSA 256), will be secure enclave in the long run, just trying to baseline some functionality right now using file store (currently running in a system daemon). I can sign data using the private key with no problem, and export the public key. However, after generating a cert chain via CSR externally, I’m trying to figure out the proper incantation to import that cert/chain and have it recognized as matching the existing private key, but so far I can’t figure out the correct attributes to get it to pair up. Do you have any sample code that might have the right SecAddItem (or such) calls that would make this work as expected?
9
0
2.1k
2d
Installing a macOS guest onto an external USB disk with Virtualization.framework (sandboxed app)
Hello, We develop a sandboxed Mac App Store app that runs virtual machines with Virtualization.framework on Apple silicon (macOS 27). Users want to install a macOS guest onto an external USB disk and start the VM from it, so they can keep a VM on portable storage or on a disk larger than the Mac's internal drive. What we tried USB passthrough: we attach the disk before the VM starts, with VZUSBPassthroughDeviceConfiguration (from an AAUSBAccessory) on a VZXHCIControllerConfiguration. Linux guests install onto the disk and boot from it without problems. For a macOS guest, VZMacOSInstaller fails to start when the USB disk is the only storage: As we understand it, a macOS VM can only start from its own storage devices, never from a USB device, so even a successful install would not boot. VZDiskBlockDeviceStorageDeviceAttachment: this needs an open file handle to /dev/diskN. That requires admin rights, which a sandboxed app can't obtain, so we can't use it in our App Store app. Questions Is there a supported way to install a macOS guest onto an external USB disk and start the VM from it? Is there a sandbox-compatible way to get a VZDiskBlockDeviceStorageDeviceAttachment for an external disk, for example after user consent, similar to how AccessoryAccess grants USB devices? If neither is possible today, is support for this planned, or is there a recommended alternative? Thank you for any guidance.
5
0
94
2d
iOS – Custom voice keyword detection when iPhone is locked
Hello, I am currently working on an iOS app and studying the feasibility of a custom voice detection feature. The user might set up a secret voice keyword (a custom word or phrase). When this keyword is spoken, even when the iPhone is locked and stored in a pocket, the application would automatically trigger an action. My questions are: Can an iOS app continuously detect a custom voice keyword when running in the background and iPhone is locked? Is there an officially supported and App Store compatible method to perform this detection locally, without recording or transmitting audio? Can an application automatically trigger an action following this detection? Would using AVAudioSession and the audio mode in the background be an acceptable solution for this use case? Are there any Apple frameworks suitable for this type of feature? I would be particularly interested in feedback from Apple engineers or developers who have experimented with similar features. Thank you in advance for your help.
0
0
42
2d
ExitTimeOut appears to be capped at 60 seconds, and ExitTimeOut 0 kills immediately
On macOS 27.x (Apple silicon) I've been measuring how launchd stops a job, and two behaviors don't match the documentation. Method: a throwaway job whose script traps SIGTERM and logs it, bootstrapped with different ExitTimeOut values, then stopped with launchctl bootout while timing when the process dies. Observed (LaunchAgent in the gui domain; the same results in the system domain with a LaunchDaemon): ExitTimeOut 45 -> `launchctl print` reports 45; SIGTERM, then SIGKILL at 45 s ExitTimeOut 61 -> reports 60; SIGTERM, then SIGKILL at 60 s ExitTimeOut 90 -> reports 60; SIGTERM, then SIGKILL at 60 s ExitTimeOut 120 -> reports 60; SIGTERM, then SIGKILL at 60 s ExitTimeOut 0 -> reports 0; SIGKILL after ~0.1 s, SIGTERM never deliveredman launchd.plist says of ExitTimeOut: "The amount of time launchd waits between sending the SIGTERM signal and before sending a SIGKILL signal when the job is to be stopped. The default value is system-defined. The value zero is interpreted as infinity and should not be used, as it can stall system shutdown forever." So: is there a 60-second ceiling on ExitTimeOut? It isn't documented that I can find, and it applies in both domains. And is zero meant to be "infinity" as documented, or an immediate SIGKILL as observed? Finally, is there a supported way for a service to be given more than 60 seconds to exit when launchd stops it — or is 60 seconds simply the maximum? Happy to file a Feedback with a minimal repro if that's useful.
7
0
256
2d
HMPresenceEvent-based predicate woes
I can't find a way to create an event trigger with a presence-based predicate ideally for a particular user at home; or at least, for all users at home. Just for the record, the rationale: I need to keep the heating on in the user's private room when he is at home, off when he is not. The idea is to have a trigger based on a low temperature event (I can do that and works all right), which would then check whether the user is at home through the predicate; if so, it would open the radiator valve (the action also tested and also working all right); if not, it would do nothing. How to? Since I could find no API to create an HMPresenceEvent for a particular user, I've set it up in the Home application, and tried to use it this way (I happen to have only one such at the moment in Home, so there's no need to check the attributes): HMPresenceEvent *pevent; for (HMEventTrigger *t in home.triggers) if ([t isKindOfClass:HMEventTrigger.class]) for (HMPresenceEvent *e in t.events) if ([e isKindOfClass:HMPresenceEvent.class]) { pevent=[e copy]; break; } NSPredicate *p=[HMEventTrigger predicateForEvaluatingTriggerWithPresence:pevent]; HMEventTrigger *et=[[HMEventTrigger alloc] initWithName:@"TEST PRESENCE" events:... endEvents:nil recurrences:nil predicate:p];alas, this raises the “NSInvalidArgumentException: Invalid parameter; (user info absent)” exception. Looks like copy loses this information somehow?!? Without appropriate public APIs one can't say :( (Since I can set up these events in the Home application freely with any kinds of action, it seems to be patently absurd not to open these APIs for privacy reasons, but that's another question, not for this ticket.) Anyway, I've tried to resort to checking for “all users at home” through pevent=[[HMPresenceEvent alloc] initWithPresenceEventType:HMPresenceEventTypeAtHome presenceUserType:HMPresenceEventUserTypeHomeUsers];where HMPresenceEventUserTypeHomeUsers is documented as “Presence of all home users”. Nevertheless, when I log out the result, I get just “any user“: [Presence-Event: type: HMPresenceTypeAnyUserAtHome, mode: HMPresenceEventActivationGranularityHome]That's unusable for me. I need to check for presence of all users (if checking for a particular one is really forbidden for some inexplicable reason). Please help. How to properly set up a trigger predicate for (ideally) a given specific HMUser, or at the very least, for a presence of all registered home users. Thanks!
2
0
115
2d
File Provider extension can't reach local network hosts on macOS 27, containing app can
On macOS 27 the File Provider extension of our app (Secure ShellFish, an SSH client) can't connect to any host on the local network, while the containing app connects to the same host on the same Mac without problems. Local Network is enabled for the app in System Settings, but every connection from the extension fails with "Local network prohibited". It did not happen on macOS 26 and still happens on macOS 27.2 (26B123). This is hitting end users of Secure ShellFish, not just my test setup, and it has been my number one support issue since macOS 27 was released. I filed this as FB24999927 with a sysdiagnose. I'm posting here to find out whether others with File Provider (or other) extensions see the same, and whether there is anything on our side that should make it work. Steps Install the app on a clean macOS 27 system and launch it. Choose Allow at the Local Network prompt. Add an SSH server on the local network (another Mac in my test) and open a terminal to it. This works. Open the same server in Finder (the File Provider domain under ~/Library/CloudStorage). The directory listing fails. What happens TN3179 says "In general, app extensions share the Local Network privilege state of their container app", so I expected the listing to load. Instead every connection from the extension to the LAN host is blocked, and the error depends on the networking API: CFStream: ENETDOWN (50) "Network is down" BSD socket connect(): EHOSTUNREACH (65) "No route to host" Network.framework (NWConnection, multipath TCP): waits with path unsatisfied (Local network prohibited) until our connect timeout, ETIMEDOUT (60) No Local Network prompt appears. Toggling the permission, rebooting, killing the extension process and reinstalling the app don't help. What I ruled out A stale extension process: freshly launched extension processes are blocked on their very first connection. A missing UUID cache: after installing a new build, nehelper populates the cache for the app with 14 UUIDs, including both slices of the extension's executable. The extension was blocked 23 seconds later. Shared executable UUIDs: the app and the extension have distinct Mach-O UUIDs. The sandbox: the extension has com.apple.security.network.client. A missing usage string: adding NSLocalNetworkUsageDescription to the extension's Info.plist changed nothing, with no prompt and no separate entry in System Settings. Networking in general: the extension reaches internet hosts and the Mac itself by its local name. Only other hosts on the local network are blocked. Log The blocked notification arrives with bundle_id: (null). UserEventAgent then maps the extension to the app by its UUID, nehelper answers that local network is allowed by preference, and the handler is called with the newly allowed state. Later connections from the same process are still blocked, so that state never takes effect for the extension. 09:19:37.575 UserEventAgent Got local network blocked notification: pid: 4297, uuid: 183484C2-8052-36AD-A81E-B02F15F875B3, bundle_id: (null) 09:19:37.575 UserEventAgent LocalNetwork: found bundle id com.appliedphasor.secure-shellfish.mac-provider by PID 09:19:37.575 ShellFish-Finder [C1.1.1 IPv6#dace0833.22 failed path (unsatisfied (Local network prohibited), interface: en0[802.11], ipv4, ipv6, uses wifi)] 09:19:37.576 UserEventAgent LocalNetwork: found bundle id com.appliedphasor.secure-shellfish by UUID 183484C2-8052-36AD-A81E-B02F15F875B3 09:19:37.597 nehelper UUID cache hit for com.appliedphasor.secure-shellfish 09:19:37.597 nehelper Local network allowed by preference for ShellFish (com.appliedphasor.secure-shellfish) 09:19:37.597 UserEventAgent App got response: 1 09:19:37.597 UserEventAgent Calling handler with newly allowed state: 1 09:19:44.795 fileproviderd populate-directory error: FP -1004 "Unable to list p5.local: Unable To Connect To P5.Local: Network Is Down."Questions Is this a known change in macOS 27? FB24035385 (helper and child processes no longer inherit Local Network access on macOS 27) sounds related, and other File Provider apps report the same, for example nextcloud/desktop#10885: https://github.com/nextcloud/desktop/issues/10885 Does an extension need anything on macOS 27 to share its container's Local Network privilege, such as an entitlement, an Info.plist key, or something the app must do first? If not, is there a supported workaround? The only one we see is to relay the extension's traffic through the main app over loopback, which only works while the app is running. For these users Finder integration is completely broken, because servers on the local network (Raspberry Pi, NAS, home servers) are the most common setup among them. Any pointers are much appreciated.
2
8
225
2d
StoreKit 2 returns USA/USD in TestFlight but DEU/EUR in local Release build on the same device
Hi everyone, We are currently preparing the release of our Flutter-based iOS application and are experiencing an unusual StoreKit 2 storefront issue that only occurs when the app is installed through TestFlight. The problem When our application is installed through TestFlight, StoreKit 2 consistently returns the United States storefront (USA), and all six auto-renewable subscription products are displayed with USD prices. However, both the regular Apple Account and the Sandbox Apple Account are configured for Germany. We have verified the following: All six subscription products are correctly configured in App Store Connect with EUR prices for Germany. The subscriptions are available in Germany, Austria, and Switzerland. We created a completely new Sandbox tester with Germany selected during account creation, using an email address that had never previously been used for sandbox testing. The issue occurs on two different physical devices (iPhone and iPad). No local StoreKit configuration file is used. Our application does not override the storefront, modify localized prices, or contain any hardcoded USD fallback. Controlled comparison We performed additional tests using the same application code on the same iPhone. The results were: Installation method Storefront Currency Local Debug build via Xcode/Flutter DEU EUR Local development-signed Release build via Flutter DEU EUR TestFlight Release build USA USD The locally installed Release build successfully retrieves all six subscription products with their correct German prices. For example, StoreKit returns the following values for one of our subscriptions: Local Release build: Storefront.current.countryCode = DEU Product currencyCode = EUR Product.displayPrice = 6,99 € TestFlight build: Storefront.current.countryCode = USA Product currencyCode = USD Both builds use the same StoreKit 2 integration and product identifiers. Technical environment Framework: Flutter StoreKit integration: StoreKit 2 Flutter plugin: in_app_purchase_storekit 0.4.11+2 Devices: Physical iPhone and iPad iOS/iPadOS: 26.6.2 Subscription products: Six auto-renewable subscriptions Expected storefront: Germany (DEU) Actual TestFlight storefront: United States (USA) We have traced the storefront country code directly to StoreKit 2’s Storefront.current.countryCode and the localized prices to the product information returned by Product.products(for:). There is no application-level storefront override or price conversion. Questions Why would StoreKit 2 return a different storefront in TestFlight compared with a locally installed development-signed Release build on the same physical device? Could TestFlight use a different sandbox storefront or Apple Account context than a locally installed build? Is there a recommended way to diagnose or reset the storefront association used by TestFlight? Has anyone experienced similar behavior where TestFlight consistently returns USA despite using a German Apple Account and newly created German sandbox testers? We have already contacted Apple Developer Support and followed their recommendation to create a completely new German sandbox tester, but the issue persists. Any guidance from Apple engineers or developers who have encountered similar behavior would be greatly appreciated. Thank you!
0
0
51
2d
StoreKit 2 returns USA/USD in TestFlight but DEU/EUR in local Release build on the same device
Hi everyone, We are currently preparing the release of our Flutter-based iOS application and are experiencing an unusual StoreKit 2 storefront issue that only occurs when the app is installed through TestFlight. The problem When our application is installed through TestFlight, StoreKit 2 consistently returns the United States storefront (USA), and all six auto-renewable subscription products are displayed with USD prices. However, both the regular Apple Account and the Sandbox Apple Account are configured for Germany. We have verified the following: All six subscription products are correctly configured in App Store Connect with EUR prices for Germany. The subscriptions are available in Germany, Austria, and Switzerland. We created a completely new Sandbox tester with Germany selected during account creation, using an email address that had never previously been used for sandbox testing. The issue occurs on two different physical devices (iPhone and iPad). No local StoreKit configuration file is used. Our application does not override the storefront, modify localized prices, or contain any hardcoded USD fallback. Controlled comparison We performed additional tests using the same application code on the same iPhone. The results were: Installation method Storefront Currency Local Debug build via Xcode/Flutter DEU EUR Local development-signed Release build via Flutter DEU EUR TestFlight Release build USA USD The locally installed Release build successfully retrieves all six subscription products with their correct German prices. For example, StoreKit returns the following values for one of our subscriptions: Local Release build: Storefront.current.countryCode = DEU Product currencyCode = EUR Product.displayPrice = 6,99 € TestFlight build: Storefront.current.countryCode = USA Product currencyCode = USD Both builds use the same StoreKit 2 integration and product identifiers. Technical environment Framework: Flutter StoreKit integration: StoreKit 2 Flutter plugin: in_app_purchase_storekit 0.4.11+2 Devices: Physical iPhone and iPad iOS/iPadOS: 26.6.2 Subscription products: Six auto-renewable subscriptions Expected storefront: Germany (DEU) Actual TestFlight storefront: United States (USA) We have traced the storefront country code directly to StoreKit 2’s Storefront.current.countryCode and the localized prices to the product information returned by Product.products(for:). There is no application-level storefront override or price conversion. Questions Why would StoreKit 2 return a different storefront in TestFlight compared with a locally installed development-signed Release build on the same physical device? Could TestFlight use a different sandbox storefront or Apple Account context than a locally installed build? Is there a recommended way to diagnose or reset the storefront association used by TestFlight? Has anyone experienced similar behavior where TestFlight consistently returns USA despite using a German Apple Account and newly created German sandbox testers? We have already contacted Apple Developer Support and followed their recommendation to create a completely new German sandbox tester, but the issue persists. Any guidance from Apple engineers or developers who have encountered similar behavior would be greatly appreciated. Thank you!
0
0
26
2d
Restricting apps based on work place/school discipline
We're building an app for colleges and employers in India. On a person's own iPhone, with their explicit consent, it would use Family Controls and ManagedSettings during class or work hours to block apps except those on an organisation's approved list. The person approves it on their device and can withdraw at any time. The organisation sees only whether the block is active, not which apps are used. Section 3.3.3 of the licence says the framework may not be used in organizational settings or to manage another adult's device. Is our use permitted? If not, is there an approved way to do this without supervising the device? We'd also like to confirm whether Network Extension or URL Filter is allowed for this use.
0
0
9
2d
Using tcsetattr on stdin in sandboxed CLI app does not work due ioctl restriction
Our (sandboxed, distributed through the Mac App Store) app can optionally run as a CLI tool, to allow users to use it in scripts and other automation contexts. One of the usecases involves being a wrapper for the ssh command, but the ssh binary is not able to enable raw mode for stdin due to a sandbox violation (bug report). As a reduced example, I've created https://github.com/mihaip/sandboxed-cli-test, which has a minimal C program that uses tcsetattr to set attributes on stdin. That fails, and sandboxd logs to the console Sandbox: SandboxedCLI(30110) deny(1) file-ioctl /dev/ttys012. If I disable sandboxing on the binary then it works as expected. Looking through the sandbox profiles on /System/Library/Sandbox/Profiles, I'm not seeing cases where file-ioctl is enabled on /dev/tty. Are we out of luck, or is there a workaround?
1
5
1.5k
2d
Title: Supported macOS PID reservation for an exited but unreaped direct child
Title: Supported macOS PID reservation for an exited but unreaped direct child I'm designing a process-lifecycle experiment on Apple silicon, initially targeting macOS 26.7.2 (build 25G332). A trusted parent directly launches a foreground child using posix_spawn(). The parent remains alive, exclusively owns reaping, preserves child exit status, and never sets SIGCHLD to SIG_IGN or enables SA_NOCLDWAIT. The parent may send kill(child_pid, SIGKILL) before obtaining the child's terminal status through waitpid(). POSIX.1-2008 §3.295 describes the PID as the last resource released when a process's lifetime ends. Section 4.13 prohibits PID reuse before that lifetime ends. Could Apple DTS clarify the supported macOS contract for this sequence? If the child exits immediately before the kill() call but remains unreaped, is its PID guaranteed not to be reassigned to another process while the original parent retains exclusive reaping authority? Does this guarantee apply to a child created through posix_spawn() on current Apple silicon macOS releases? Are there documented exceptions beyond automatic status disposal, competing reapers and parent termination? What result should the parent expect when kill() targets an already-exited but unreaped child? The design serialises signaling and reaping, and never signals the numeric PID after status consumption. This question concerns identity-safe signal targeting, not whether successful kill() establishes termination. The latter is separately verified using waitpid(). I'm seeking a supported API contract rather than empirical observations or private kernel implementation details. Thank you.
1
0
52
2d
macOS/APFS: interpreting acl_get_fd_np ENOENT and omitted extended-security attributes
Apple Support directed me to the Developer Forums for this API-contract question. I am implementing conservative, read-only ACL classification for existing files and directories. I need to distinguish an absent ACL from unavailable or incomplete ACL information. Ambiguous results are currently rejected. The measurements below were taken on macOS 26.5, build 25F71, Apple Silicon (arm64), on APFS. Method I tested eight newly created objects: a regular file and a directory in each of four preparation states: Fresh: no ACL setter, deletion or normalization was performed. Explicit-empty ACL preparation. One DENY entry. One ALLOW entry. “Fresh” describes preparation only; I am not assuming it independently proves ACL absence. Each object remained open through preparation and two observations using the same file descriptor. Each observation performed: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) fgetattrlist() requesting ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY, with FSOPT_REPORT_FULLSIZE and without FSOPT_PACK_INVAL_ATTRS. Errno was cleared immediately before each query and captured immediately afterward. Descriptor/path identity and metadata stability were checked. Returned lengths, attribute bitmaps and applicable reference/payload bounds were validated. Observations Results matched between the two observations and between regular files and directories: Preparationacl_get_fd_np resultfgetattrlist returnEXTENDED_SECURITY returnedReturned filesec ACE countAttribute-buffer lengthFreshNULL, errno ENOENT0NoN/A32 bytesExplicit-emptyNULL, errno ENOENT0Yes076 bytesOne DENY entryNon-NULL, errno 00Yes1100 bytesOne ALLOW entryNon-NULL, errno 00Yes1100 bytesWhen the getter returned NULL, ACL validation and enumeration were not performed; their results are N/A, not measured zeros or an empty entry list. When EXTENDED_SECURITY was omitted, its payload fields were unavailable. I did not interpret default buffer values as returned ACL information. An actually returned zero-entry record is distinct from omission. No NOACL sentinel was observed in this experiment. Question For a valid descriptor referring to an existing APFS object, what is the supported interpretation of: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) returning NULL with ENOENT; and fgetattrlist() succeeding while omitting ATTR_CMN_EXTENDED_SECURITY from the returned attribute bitmap? In particular: Can this combination establish ACL absence under documented conditions, or must it remain classified as unavailable/ambiguous information? How should the observed NULL/ENOENT with an actually returned zero-entry ACL record be interpreted? If these results cannot establish absence, which supported read-only, descriptor-based API or verification sequence should be used? What guarantees and limitations apply regarding macOS versions, filesystem support and genuine retrieval failures? I reviewed the acl_get(3) documentation but could not find a clear explanation of this valid-descriptor ENOENT case: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/acl_get.3.html I am seeking the supported API contract, not asserting an OS defect or vulnerability. I do not want to set, delete or normalize ACLs on the objects being inspected, or treat an ambiguous result as success.
1
0
52
2d
App Store Server API: originalTransactionId stability across expiration and resubscription
DTS recommended that we post this question in the Developer Forums. We would like clarification on the supported production behavior of originalTransactionId in the App Store Server API, particularly after a subscription expires and the customer resubscribes. Our main backend design question is: Can we continue using a stored originalTransactionId to identify and retrieve subsequent subscription activity within the same subscription group, or must we support discovering and associating new identifiers? Integration context Our backend uses: GET /inApps/v1/subscriptions/{transactionId} GET /inApps/v2/history/{transactionId} App and subscription details: Bundle ID: com.lgeha.nuts Subscription group identifier: 22350255 Product A: thinq_g_unlimitedpro Product B: thinq_g_single We use originalTransactionId as a key for subscription records and associate those records with user accounts in our service. We do not use it as an identifier for the Apple Account itself. Please assume the same Apple Account and app, with both products in the same subscription group, using ordinary auto-renewable subscriptions without a special subscription migration. This question concerns the identifiers and lookup behavior exposed to our backend by the App Store Server API. Sandbox observation and scope During sandbox testing, purchase history was cleared, and a new originalTransactionId was subsequently observed. We understand that this observation involved a sandbox history reset and does not establish production behavior. Our questions below concern production behavior without any purchase-history reset. Preservation across subscription lifecycle events For each scenario below, is originalTransactionId guaranteed to remain unchanged for subsequent transactions, or can Apple assign a different value? Automatic renewal of the same product. An upgrade, downgrade, or crossgrade between products A and B while the subscription is active. Turning off automatic renewal, then re-enabling it before expiration. Turning off automatic renewal, allowing the subscription to expire, and later resubscribing to the same product. Turning off automatic renewal for product A, allowing it to expire, and later subscribing to product B within the same subscription group. Scenarios 4 and 5 are our primary concern. We would like to distinguish commonly observed behavior from supported guarantees that a backend can rely on. Conditions for a new identifier after expiration For scenarios 4 and 5, can a new purchase legitimately receive a different originalTransactionId in production despite the Apple Account, app, and subscription group remaining unchanged? If so, what conditions determine this? Does it depend on: Time elapsed since expiration. Billing retry or billing grace-period status or history. Whether the purchase uses StoreKit 1 or StoreKit 2. Whether the customer resubscribes inside the app or through App Store subscription management. Our concern is whether these factors affect the identifiers subsequently returned by the App Store Server API. Stability of an existing transaction Separately from a new purchase receiving a new identifier, if the same transactionId is retrieved at two different times, is its associated originalTransactionId guaranteed to remain unchanged? Can an Apple-supported correction process change that association, or should such a result be treated as an inconsistency and reported through Feedback Assistant? This question concerns the same returned transactionId, rather than a different latest transaction returned by a subsequent status query. We have not confirmed such a change in production. Lookup behavior using a previously stored identifier If resubscription can create a new originalTransactionId, how does that affect each endpoint? For GET /inApps/v1/subscriptions/{transactionId}: Can a request using the previous originalTransactionId return the current status of a later resubscription with a different originalTransactionId, assuming the same Apple Account, app, and subscription group? Or must the backend obtain the new identifier separately? For GET /inApps/v2/history/{transactionId}: Can a request using the previous originalTransactionId return transactions from that later resubscription, assuming all applicable pages are retrieved and no filters exclude those transactions? Please clarify any endpoint-specific guarantees or limitations on using an older identifier to discover subsequent subscription activity. Backend account association If resubscription can create a new identifier, should our backend support multiple originalTransactionId values for one service user within the same subscription group? Is there a documented server-side relationship that links subscriptions with different originalTransactionId values? Alternatively, should that association rely on an application-managed identifier such as appAccountToken, where available? Please clarify any limitations, especially for resubscriptions initiated outside the app. Related discussions We reviewed these discussions as background: Transaction ID Misassociation in IAP Subscription API (https://developer.apple.com/forums/thread/777433) original_transaction_id associated to web_order_line_item_id of auto-renewable subscription changed (https://developer.apple.com/forums/thread/778301) We do not assume that these reports establish supported behavior or share the cause of our sandbox observation. Could Apple clarify the supported preservation or replacement rules, particularly after expiration and resubscription, and point us to documentation describing the behavior a backend can rely on? If investigating a specific inconsistency requires a separate Feedback Assistant report, please indicate which server-side request and response details should be included. Thank you.
Replies
1
Boosts
0
Views
417
Activity
2d
How can a macOS application establish that an open APFS file has no extended ACL?
On macOS 26.5.2 (build 25F84), which documented API and return conditions, if any, establish that a regular file on APFS has no extended access control list (ACL), using an already-open file descriptor? We tested three disposable regular files on an APFS volume reporting ACL support. For each file, we opened a read-only file descriptor and called: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) fgetattrlist() requesting ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY Before and after inspection, fstat() confirmed stable device, inode, mode, and change timestamp. Observed results: 1. Newly created file, no ACL explicitly assigned acl_get_fd_np() returned NULL with errno == ENOENT. fgetattrlist() succeeded but omitted ATTR_CMN_EXTENDED_SECURITY from the returned attribute mask. FSOPT_PACK_INVAL_ATTRS also left that bit clear. 2. File with an explicitly assigned empty ACL acl_get_fd_np() returned NULL with errno == ENOENT. fgetattrlist() returned the extended-security attribute with an ACL entry count of zero. 3. File with one explicit ACL entry acl_get_fd_np() returned a non-null ACL. fgetattrlist() returned the extended-security attribute with an ACL entry count of one. Apple's published XNU attribute-packing implementation appears to use the same omission branch when ACL metadata is unsupported or when the ACL pointer is null. My question: Is there a supported descriptor-based API sequence that reliably distinguishes: Genuine absence of an extended ACL Unavailable or unsupported per-file ACL metadata An ACL retrieval failure If so, which API, capability checks, return values, attribute bits, or error conditions should a caller rely on? Are there relevant APFS or macOS version limitations? If the public API cannot establish ACL absence unambiguously in this situation, confirmation of that limitation would also be helpful. Thank you for your guidance.
Replies
2
Boosts
0
Views
52
Activity
2d
macOS: How to reliably verify the absence of an extended ACL using a file descriptor?
We are implementing a fail-closed security check for a directory opened through a file descriptor on macOS. We need to reliably distinguish between: No extended ACL is present. An extended ACL is present but contains zero entries. ACL retrieval failed or is unsupported. Observed behavior For an existing directory with mode 0700: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) returns NULL with errno == ENOENT. acl_get_file(path, ACL_TYPE_EXTENDED) returns NULL with errno == ENOENT. fstat() and lstat() agree on the device and inode. The directory exists and can be opened successfully. ls -ldeO@ displays no extended ACL entries. We reviewed Apple's open-source implementations of acl_get_fd_np() and filesec_get_property(). We understand that ENOENT can result from an unavailable FILESEC_ACL property, rather than a missing filesystem object. We also understand that XNU distinguishes an empty ACL from KAUTH_FILESEC_NOACL. Question Is there a publicly supported, file-descriptor-based API with documented postconditions that can reliably prove the absence of an extended ACL, while distinguishing it from an empty ACL and an ACL retrieval failure? Specifically: Can fstatx_np() and filesec_get_property() provide this distinction? Can fgetattrlist() with ATTR_CMN_EXTENDED_SECURITY and ATTR_CMN_RETURNED_ATTRS reliably establish ACL absence? What additional filesystem capability checks or return-value checks are required? If no public API provides this guarantee, is that a documented limitation? For security reasons, our implementation rejects the object whenever ACL absence cannot be established reliably. We would appreciate clarification of the supported API contract and its limitations. Thank you.
Replies
1
Boosts
0
Views
53
Activity
2d
How precisely is a predicate evaluated for an HMEventTrigger?
Perhaps I am just stupid, but I can't quite grok that. What object is the predicate evaluated over, how, and at what moment? Originally I've thought when some event causes the trigger to fire, the predicate would just be evaluated over that event; but that can't be that simple, see please details below. I've set (in a 3rd party application; Home, far as I can say, does not allow that) a predicate “only when both of a pair of lights are off”. The predicate works perfectly, and the event really performs its action set only when both of the lights are off, so far so good. Nevertheless, I've dumped the predicate, and it looks like this (the first line is my own dump which is a bit more concise; the 2nd one is the standard description just to make sure that my own dump works properly): (((self.characteristic == 'Power State' of 'Lustr O') && (self.characteristicValue == 0)) && ((self.characteristic == 'Power State' of 'Knihovna') && (self.characteristicValue == 0))) (characteristic == <HMCharacteristic, Unique ID: 2E046807-9127-565F-B9CB-10BC0F2EE6D2, Type: 00000025, Instance ID: 9> AND characteristicValue == 0) AND (characteristic == <HMCharacteristic, Unique ID: 7444CCCE-1C1B-5234-8CAE-01DA4D811B8B, Type: 00000025, Instance ID: 9> AND characteristicValue == 0)I can't understand that at all :( I must be missing something of great importance, but it seems to me that a predicate which can be just as well[1] written as self.characteristic==A && self.characteristic==B && (some other conditions) can't ever evaluate to YES when A and B differ (which they self-evidently do in this case). The “to evaluate before executing the scene” of the documentation does not really help. What do I miss, can anybody explain that? Thanks! [1] Correct me please if I am wrong, but I do believe the logical AND is both an associative and an commutative operator, which makes this re-write fully equivalent to the original.
Replies
5
Boosts
0
Views
101
Activity
2d
iOS 27.2 beta: "Couldn't Sync iCloud Data" – Resume Data Sync only offers Delete (FB25408294)
Filed as FB25408294 with sysdiagnose attached. After an Apple battery repair (Aug 28, 2026), my iPhone 15 Pro Max was reset and set up as new. Since then, Settings shows "Some iCloud Data Isn't Syncing." Resume Data Sync asks for my iPhone passcode, loads, then shows "Couldn't Sync iCloud Data" with only Cancel or Delete iCloud Data. iOS 27.2 developer beta Advanced Data Protection: OFF Messages in iCloud: 188 GB stored, but "0 messages" / "Not synced" Same error on my Mac; Apple Watch Ultra can't finish setup because of it Tried current and previous device passcode No Recovery Key or Recovery Contact I have NOT deleted any iCloud data and want to recover it rather than reset it. Is anyone from the iCloud / CloudKit / Keychain team able to look at the FB? Has anyone found a way to get a device back into the iCloud Keychain circle without resetting end-to-end encrypted data?
Replies
1
Boosts
0
Views
35
Activity
2d
Is a `flowClosed` report guaranteed when the owning process exits or crashes?
Our macOS NEFilterDataProvider sets shouldReport = true on flow verdicts and receives NEFilterReport.Event.flowClosed in handle(_:). In testing, we have observed close reports after the owning process exits or crashes, sometimes with a short delay. Is a flowClosed report guaranteed for every TCP and UDP flow in these cases? Does the behavior differ by protocol, and is there a documented upper bound on delivery time? We also set statisticsReportFrequency = .low. Does that setting affect only periodic .statistics reports, with no effect on flowClosed delivery?
Replies
2
Boosts
0
Views
89
Activity
2d
APNs Delivery Metrics: What Exactly Triggers “Discarded - Disabled”?
Hello, I'm trying to understand the exact meaning of the APNs delivery status Discarded - Disabled shown in Apple's Push Notification Console. According to the status tooltip: Push notifications which were discarded by APNs, because the push feature was disabled for the application on the target device. None of these were saved to APNs storage. However, I'm unable to reproduce this behavior by disabling notifications through iOS Settings. My test scenario I performed the following test on a physical iOS device: Installed our application. Enabled notifications for the application in iOS Settings. Sent a regular visible push notification (alert) from CloudKit console. Checked the individual APNs Delivery Log. The status was Delivered to Device. Disabled notifications for our application through Settings → Notifications → [Our App] → Allow Notifications. Sent another regular visible push notification using the same device token. Checked the individual APNs Delivery Log again. Unexpected result: Despite notifications being disabled in iOS Settings, APNs reported Delivered to Device, not Discarded - Disabled. I'm checking individual notification delivery records, not aggregated metrics. Questions I'd appreciate clarification on the following: What exactly does Apple mean by "the push feature was disabled for the application on the target device"? Does Discarded - Disabled refer to the notification authorization status (UNAuthorizationStatus.denied) or a different device-side state? If disabling notifications through iOS Settings does not trigger this status, what specific user action or device configuration does? Is there a distinction between disabling notification presentation and disabling remote push delivery at the APNs level? Under what exact circumstances does APNs report Discarded - Disabled instead of Delivered to Device? Additional information Push type: alert Notification type: Regular visible notification Device: iPhone 14 iOS version: 27.2 APNs environment: Sandbox My goal is to understand the exact technical conditions that produce Discarded - Disabled, rather than just the general meaning of the status. Has anyone encountered this behavior or received clarification from Apple about this particular APNs delivery status? Thanks!
Replies
0
Boosts
0
Views
45
Activity
2d
Import resulting certificate to associate with private key
On macOS I am creating a public/private key pair (ECDSA 256), will be secure enclave in the long run, just trying to baseline some functionality right now using file store (currently running in a system daemon). I can sign data using the private key with no problem, and export the public key. However, after generating a cert chain via CSR externally, I’m trying to figure out the proper incantation to import that cert/chain and have it recognized as matching the existing private key, but so far I can’t figure out the correct attributes to get it to pair up. Do you have any sample code that might have the right SecAddItem (or such) calls that would make this work as expected?
Replies
9
Boosts
0
Views
2.1k
Activity
2d
Installing a macOS guest onto an external USB disk with Virtualization.framework (sandboxed app)
Hello, We develop a sandboxed Mac App Store app that runs virtual machines with Virtualization.framework on Apple silicon (macOS 27). Users want to install a macOS guest onto an external USB disk and start the VM from it, so they can keep a VM on portable storage or on a disk larger than the Mac's internal drive. What we tried USB passthrough: we attach the disk before the VM starts, with VZUSBPassthroughDeviceConfiguration (from an AAUSBAccessory) on a VZXHCIControllerConfiguration. Linux guests install onto the disk and boot from it without problems. For a macOS guest, VZMacOSInstaller fails to start when the USB disk is the only storage: As we understand it, a macOS VM can only start from its own storage devices, never from a USB device, so even a successful install would not boot. VZDiskBlockDeviceStorageDeviceAttachment: this needs an open file handle to /dev/diskN. That requires admin rights, which a sandboxed app can't obtain, so we can't use it in our App Store app. Questions Is there a supported way to install a macOS guest onto an external USB disk and start the VM from it? Is there a sandbox-compatible way to get a VZDiskBlockDeviceStorageDeviceAttachment for an external disk, for example after user consent, similar to how AccessoryAccess grants USB devices? If neither is possible today, is support for this planned, or is there a recommended alternative? Thank you for any guidance.
Replies
5
Boosts
0
Views
94
Activity
2d
iOS – Custom voice keyword detection when iPhone is locked
Hello, I am currently working on an iOS app and studying the feasibility of a custom voice detection feature. The user might set up a secret voice keyword (a custom word or phrase). When this keyword is spoken, even when the iPhone is locked and stored in a pocket, the application would automatically trigger an action. My questions are: Can an iOS app continuously detect a custom voice keyword when running in the background and iPhone is locked? Is there an officially supported and App Store compatible method to perform this detection locally, without recording or transmitting audio? Can an application automatically trigger an action following this detection? Would using AVAudioSession and the audio mode in the background be an acceptable solution for this use case? Are there any Apple frameworks suitable for this type of feature? I would be particularly interested in feedback from Apple engineers or developers who have experimented with similar features. Thank you in advance for your help.
Replies
0
Boosts
0
Views
42
Activity
2d
ExitTimeOut appears to be capped at 60 seconds, and ExitTimeOut 0 kills immediately
On macOS 27.x (Apple silicon) I've been measuring how launchd stops a job, and two behaviors don't match the documentation. Method: a throwaway job whose script traps SIGTERM and logs it, bootstrapped with different ExitTimeOut values, then stopped with launchctl bootout while timing when the process dies. Observed (LaunchAgent in the gui domain; the same results in the system domain with a LaunchDaemon): ExitTimeOut 45 -> `launchctl print` reports 45; SIGTERM, then SIGKILL at 45 s ExitTimeOut 61 -> reports 60; SIGTERM, then SIGKILL at 60 s ExitTimeOut 90 -> reports 60; SIGTERM, then SIGKILL at 60 s ExitTimeOut 120 -> reports 60; SIGTERM, then SIGKILL at 60 s ExitTimeOut 0 -> reports 0; SIGKILL after ~0.1 s, SIGTERM never deliveredman launchd.plist says of ExitTimeOut: "The amount of time launchd waits between sending the SIGTERM signal and before sending a SIGKILL signal when the job is to be stopped. The default value is system-defined. The value zero is interpreted as infinity and should not be used, as it can stall system shutdown forever." So: is there a 60-second ceiling on ExitTimeOut? It isn't documented that I can find, and it applies in both domains. And is zero meant to be "infinity" as documented, or an immediate SIGKILL as observed? Finally, is there a supported way for a service to be given more than 60 seconds to exit when launchd stops it — or is 60 seconds simply the maximum? Happy to file a Feedback with a minimal repro if that's useful.
Replies
7
Boosts
0
Views
256
Activity
2d
HMPresenceEvent-based predicate woes
I can't find a way to create an event trigger with a presence-based predicate ideally for a particular user at home; or at least, for all users at home. Just for the record, the rationale: I need to keep the heating on in the user's private room when he is at home, off when he is not. The idea is to have a trigger based on a low temperature event (I can do that and works all right), which would then check whether the user is at home through the predicate; if so, it would open the radiator valve (the action also tested and also working all right); if not, it would do nothing. How to? Since I could find no API to create an HMPresenceEvent for a particular user, I've set it up in the Home application, and tried to use it this way (I happen to have only one such at the moment in Home, so there's no need to check the attributes): HMPresenceEvent *pevent; for (HMEventTrigger *t in home.triggers) if ([t isKindOfClass:HMEventTrigger.class]) for (HMPresenceEvent *e in t.events) if ([e isKindOfClass:HMPresenceEvent.class]) { pevent=[e copy]; break; } NSPredicate *p=[HMEventTrigger predicateForEvaluatingTriggerWithPresence:pevent]; HMEventTrigger *et=[[HMEventTrigger alloc] initWithName:@"TEST PRESENCE" events:... endEvents:nil recurrences:nil predicate:p];alas, this raises the “NSInvalidArgumentException: Invalid parameter; (user info absent)” exception. Looks like copy loses this information somehow?!? Without appropriate public APIs one can't say :( (Since I can set up these events in the Home application freely with any kinds of action, it seems to be patently absurd not to open these APIs for privacy reasons, but that's another question, not for this ticket.) Anyway, I've tried to resort to checking for “all users at home” through pevent=[[HMPresenceEvent alloc] initWithPresenceEventType:HMPresenceEventTypeAtHome presenceUserType:HMPresenceEventUserTypeHomeUsers];where HMPresenceEventUserTypeHomeUsers is documented as “Presence of all home users”. Nevertheless, when I log out the result, I get just “any user“: [Presence-Event: type: HMPresenceTypeAnyUserAtHome, mode: HMPresenceEventActivationGranularityHome]That's unusable for me. I need to check for presence of all users (if checking for a particular one is really forbidden for some inexplicable reason). Please help. How to properly set up a trigger predicate for (ideally) a given specific HMUser, or at the very least, for a presence of all registered home users. Thanks!
Replies
2
Boosts
0
Views
115
Activity
2d
File Provider extension can't reach local network hosts on macOS 27, containing app can
On macOS 27 the File Provider extension of our app (Secure ShellFish, an SSH client) can't connect to any host on the local network, while the containing app connects to the same host on the same Mac without problems. Local Network is enabled for the app in System Settings, but every connection from the extension fails with "Local network prohibited". It did not happen on macOS 26 and still happens on macOS 27.2 (26B123). This is hitting end users of Secure ShellFish, not just my test setup, and it has been my number one support issue since macOS 27 was released. I filed this as FB24999927 with a sysdiagnose. I'm posting here to find out whether others with File Provider (or other) extensions see the same, and whether there is anything on our side that should make it work. Steps Install the app on a clean macOS 27 system and launch it. Choose Allow at the Local Network prompt. Add an SSH server on the local network (another Mac in my test) and open a terminal to it. This works. Open the same server in Finder (the File Provider domain under ~/Library/CloudStorage). The directory listing fails. What happens TN3179 says "In general, app extensions share the Local Network privilege state of their container app", so I expected the listing to load. Instead every connection from the extension to the LAN host is blocked, and the error depends on the networking API: CFStream: ENETDOWN (50) "Network is down" BSD socket connect(): EHOSTUNREACH (65) "No route to host" Network.framework (NWConnection, multipath TCP): waits with path unsatisfied (Local network prohibited) until our connect timeout, ETIMEDOUT (60) No Local Network prompt appears. Toggling the permission, rebooting, killing the extension process and reinstalling the app don't help. What I ruled out A stale extension process: freshly launched extension processes are blocked on their very first connection. A missing UUID cache: after installing a new build, nehelper populates the cache for the app with 14 UUIDs, including both slices of the extension's executable. The extension was blocked 23 seconds later. Shared executable UUIDs: the app and the extension have distinct Mach-O UUIDs. The sandbox: the extension has com.apple.security.network.client. A missing usage string: adding NSLocalNetworkUsageDescription to the extension's Info.plist changed nothing, with no prompt and no separate entry in System Settings. Networking in general: the extension reaches internet hosts and the Mac itself by its local name. Only other hosts on the local network are blocked. Log The blocked notification arrives with bundle_id: (null). UserEventAgent then maps the extension to the app by its UUID, nehelper answers that local network is allowed by preference, and the handler is called with the newly allowed state. Later connections from the same process are still blocked, so that state never takes effect for the extension. 09:19:37.575 UserEventAgent Got local network blocked notification: pid: 4297, uuid: 183484C2-8052-36AD-A81E-B02F15F875B3, bundle_id: (null) 09:19:37.575 UserEventAgent LocalNetwork: found bundle id com.appliedphasor.secure-shellfish.mac-provider by PID 09:19:37.575 ShellFish-Finder [C1.1.1 IPv6#dace0833.22 failed path (unsatisfied (Local network prohibited), interface: en0[802.11], ipv4, ipv6, uses wifi)] 09:19:37.576 UserEventAgent LocalNetwork: found bundle id com.appliedphasor.secure-shellfish by UUID 183484C2-8052-36AD-A81E-B02F15F875B3 09:19:37.597 nehelper UUID cache hit for com.appliedphasor.secure-shellfish 09:19:37.597 nehelper Local network allowed by preference for ShellFish (com.appliedphasor.secure-shellfish) 09:19:37.597 UserEventAgent App got response: 1 09:19:37.597 UserEventAgent Calling handler with newly allowed state: 1 09:19:44.795 fileproviderd populate-directory error: FP -1004 "Unable to list p5.local: Unable To Connect To P5.Local: Network Is Down."Questions Is this a known change in macOS 27? FB24035385 (helper and child processes no longer inherit Local Network access on macOS 27) sounds related, and other File Provider apps report the same, for example nextcloud/desktop#10885: https://github.com/nextcloud/desktop/issues/10885 Does an extension need anything on macOS 27 to share its container's Local Network privilege, such as an entitlement, an Info.plist key, or something the app must do first? If not, is there a supported workaround? The only one we see is to relay the extension's traffic through the main app over loopback, which only works while the app is running. For these users Finder integration is completely broken, because servers on the local network (Raspberry Pi, NAS, home servers) are the most common setup among them. Any pointers are much appreciated.
Replies
2
Boosts
8
Views
225
Activity
2d
StoreKit 2 returns USA/USD in TestFlight but DEU/EUR in local Release build on the same device
Hi everyone, We are currently preparing the release of our Flutter-based iOS application and are experiencing an unusual StoreKit 2 storefront issue that only occurs when the app is installed through TestFlight. The problem When our application is installed through TestFlight, StoreKit 2 consistently returns the United States storefront (USA), and all six auto-renewable subscription products are displayed with USD prices. However, both the regular Apple Account and the Sandbox Apple Account are configured for Germany. We have verified the following: All six subscription products are correctly configured in App Store Connect with EUR prices for Germany. The subscriptions are available in Germany, Austria, and Switzerland. We created a completely new Sandbox tester with Germany selected during account creation, using an email address that had never previously been used for sandbox testing. The issue occurs on two different physical devices (iPhone and iPad). No local StoreKit configuration file is used. Our application does not override the storefront, modify localized prices, or contain any hardcoded USD fallback. Controlled comparison We performed additional tests using the same application code on the same iPhone. The results were: Installation method Storefront Currency Local Debug build via Xcode/Flutter DEU EUR Local development-signed Release build via Flutter DEU EUR TestFlight Release build USA USD The locally installed Release build successfully retrieves all six subscription products with their correct German prices. For example, StoreKit returns the following values for one of our subscriptions: Local Release build: Storefront.current.countryCode = DEU Product currencyCode = EUR Product.displayPrice = 6,99 € TestFlight build: Storefront.current.countryCode = USA Product currencyCode = USD Both builds use the same StoreKit 2 integration and product identifiers. Technical environment Framework: Flutter StoreKit integration: StoreKit 2 Flutter plugin: in_app_purchase_storekit 0.4.11+2 Devices: Physical iPhone and iPad iOS/iPadOS: 26.6.2 Subscription products: Six auto-renewable subscriptions Expected storefront: Germany (DEU) Actual TestFlight storefront: United States (USA) We have traced the storefront country code directly to StoreKit 2’s Storefront.current.countryCode and the localized prices to the product information returned by Product.products(for:). There is no application-level storefront override or price conversion. Questions Why would StoreKit 2 return a different storefront in TestFlight compared with a locally installed development-signed Release build on the same physical device? Could TestFlight use a different sandbox storefront or Apple Account context than a locally installed build? Is there a recommended way to diagnose or reset the storefront association used by TestFlight? Has anyone experienced similar behavior where TestFlight consistently returns USA despite using a German Apple Account and newly created German sandbox testers? We have already contacted Apple Developer Support and followed their recommendation to create a completely new German sandbox tester, but the issue persists. Any guidance from Apple engineers or developers who have encountered similar behavior would be greatly appreciated. Thank you!
Replies
0
Boosts
0
Views
51
Activity
2d
StoreKit 2 returns USA/USD in TestFlight but DEU/EUR in local Release build on the same device
Hi everyone, We are currently preparing the release of our Flutter-based iOS application and are experiencing an unusual StoreKit 2 storefront issue that only occurs when the app is installed through TestFlight. The problem When our application is installed through TestFlight, StoreKit 2 consistently returns the United States storefront (USA), and all six auto-renewable subscription products are displayed with USD prices. However, both the regular Apple Account and the Sandbox Apple Account are configured for Germany. We have verified the following: All six subscription products are correctly configured in App Store Connect with EUR prices for Germany. The subscriptions are available in Germany, Austria, and Switzerland. We created a completely new Sandbox tester with Germany selected during account creation, using an email address that had never previously been used for sandbox testing. The issue occurs on two different physical devices (iPhone and iPad). No local StoreKit configuration file is used. Our application does not override the storefront, modify localized prices, or contain any hardcoded USD fallback. Controlled comparison We performed additional tests using the same application code on the same iPhone. The results were: Installation method Storefront Currency Local Debug build via Xcode/Flutter DEU EUR Local development-signed Release build via Flutter DEU EUR TestFlight Release build USA USD The locally installed Release build successfully retrieves all six subscription products with their correct German prices. For example, StoreKit returns the following values for one of our subscriptions: Local Release build: Storefront.current.countryCode = DEU Product currencyCode = EUR Product.displayPrice = 6,99 € TestFlight build: Storefront.current.countryCode = USA Product currencyCode = USD Both builds use the same StoreKit 2 integration and product identifiers. Technical environment Framework: Flutter StoreKit integration: StoreKit 2 Flutter plugin: in_app_purchase_storekit 0.4.11+2 Devices: Physical iPhone and iPad iOS/iPadOS: 26.6.2 Subscription products: Six auto-renewable subscriptions Expected storefront: Germany (DEU) Actual TestFlight storefront: United States (USA) We have traced the storefront country code directly to StoreKit 2’s Storefront.current.countryCode and the localized prices to the product information returned by Product.products(for:). There is no application-level storefront override or price conversion. Questions Why would StoreKit 2 return a different storefront in TestFlight compared with a locally installed development-signed Release build on the same physical device? Could TestFlight use a different sandbox storefront or Apple Account context than a locally installed build? Is there a recommended way to diagnose or reset the storefront association used by TestFlight? Has anyone experienced similar behavior where TestFlight consistently returns USA despite using a German Apple Account and newly created German sandbox testers? We have already contacted Apple Developer Support and followed their recommendation to create a completely new German sandbox tester, but the issue persists. Any guidance from Apple engineers or developers who have encountered similar behavior would be greatly appreciated. Thank you!
Replies
0
Boosts
0
Views
26
Activity
2d
Restricting apps based on work place/school discipline
We're building an app for colleges and employers in India. On a person's own iPhone, with their explicit consent, it would use Family Controls and ManagedSettings during class or work hours to block apps except those on an organisation's approved list. The person approves it on their device and can withdraw at any time. The organisation sees only whether the block is active, not which apps are used. Section 3.3.3 of the licence says the framework may not be used in organizational settings or to manage another adult's device. Is our use permitted? If not, is there an approved way to do this without supervising the device? We'd also like to confirm whether Network Extension or URL Filter is allowed for this use.
Replies
0
Boosts
0
Views
9
Activity
2d
Using tcsetattr on stdin in sandboxed CLI app does not work due ioctl restriction
Our (sandboxed, distributed through the Mac App Store) app can optionally run as a CLI tool, to allow users to use it in scripts and other automation contexts. One of the usecases involves being a wrapper for the ssh command, but the ssh binary is not able to enable raw mode for stdin due to a sandbox violation (bug report). As a reduced example, I've created https://github.com/mihaip/sandboxed-cli-test, which has a minimal C program that uses tcsetattr to set attributes on stdin. That fails, and sandboxd logs to the console Sandbox: SandboxedCLI(30110) deny(1) file-ioctl /dev/ttys012. If I disable sandboxing on the binary then it works as expected. Looking through the sandbox profiles on /System/Library/Sandbox/Profiles, I'm not seeing cases where file-ioctl is enabled on /dev/tty. Are we out of luck, or is there a workaround?
Replies
1
Boosts
5
Views
1.5k
Activity
2d
Title: Supported macOS PID reservation for an exited but unreaped direct child
Title: Supported macOS PID reservation for an exited but unreaped direct child I'm designing a process-lifecycle experiment on Apple silicon, initially targeting macOS 26.7.2 (build 25G332). A trusted parent directly launches a foreground child using posix_spawn(). The parent remains alive, exclusively owns reaping, preserves child exit status, and never sets SIGCHLD to SIG_IGN or enables SA_NOCLDWAIT. The parent may send kill(child_pid, SIGKILL) before obtaining the child's terminal status through waitpid(). POSIX.1-2008 §3.295 describes the PID as the last resource released when a process's lifetime ends. Section 4.13 prohibits PID reuse before that lifetime ends. Could Apple DTS clarify the supported macOS contract for this sequence? If the child exits immediately before the kill() call but remains unreaped, is its PID guaranteed not to be reassigned to another process while the original parent retains exclusive reaping authority? Does this guarantee apply to a child created through posix_spawn() on current Apple silicon macOS releases? Are there documented exceptions beyond automatic status disposal, competing reapers and parent termination? What result should the parent expect when kill() targets an already-exited but unreaped child? The design serialises signaling and reaping, and never signals the numeric PID after status consumption. This question concerns identity-safe signal targeting, not whether successful kill() establishes termination. The latter is separately verified using waitpid(). I'm seeking a supported API contract rather than empirical observations or private kernel implementation details. Thank you.
Replies
1
Boosts
0
Views
52
Activity
2d
macOS/APFS: interpreting acl_get_fd_np ENOENT and omitted extended-security attributes
Apple Support directed me to the Developer Forums for this API-contract question. I am implementing conservative, read-only ACL classification for existing files and directories. I need to distinguish an absent ACL from unavailable or incomplete ACL information. Ambiguous results are currently rejected. The measurements below were taken on macOS 26.5, build 25F71, Apple Silicon (arm64), on APFS. Method I tested eight newly created objects: a regular file and a directory in each of four preparation states: Fresh: no ACL setter, deletion or normalization was performed. Explicit-empty ACL preparation. One DENY entry. One ALLOW entry. “Fresh” describes preparation only; I am not assuming it independently proves ACL absence. Each object remained open through preparation and two observations using the same file descriptor. Each observation performed: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) fgetattrlist() requesting ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY, with FSOPT_REPORT_FULLSIZE and without FSOPT_PACK_INVAL_ATTRS. Errno was cleared immediately before each query and captured immediately afterward. Descriptor/path identity and metadata stability were checked. Returned lengths, attribute bitmaps and applicable reference/payload bounds were validated. Observations Results matched between the two observations and between regular files and directories: Preparationacl_get_fd_np resultfgetattrlist returnEXTENDED_SECURITY returnedReturned filesec ACE countAttribute-buffer lengthFreshNULL, errno ENOENT0NoN/A32 bytesExplicit-emptyNULL, errno ENOENT0Yes076 bytesOne DENY entryNon-NULL, errno 00Yes1100 bytesOne ALLOW entryNon-NULL, errno 00Yes1100 bytesWhen the getter returned NULL, ACL validation and enumeration were not performed; their results are N/A, not measured zeros or an empty entry list. When EXTENDED_SECURITY was omitted, its payload fields were unavailable. I did not interpret default buffer values as returned ACL information. An actually returned zero-entry record is distinct from omission. No NOACL sentinel was observed in this experiment. Question For a valid descriptor referring to an existing APFS object, what is the supported interpretation of: acl_get_fd_np(fd, ACL_TYPE_EXTENDED) returning NULL with ENOENT; and fgetattrlist() succeeding while omitting ATTR_CMN_EXTENDED_SECURITY from the returned attribute bitmap? In particular: Can this combination establish ACL absence under documented conditions, or must it remain classified as unavailable/ambiguous information? How should the observed NULL/ENOENT with an actually returned zero-entry ACL record be interpreted? If these results cannot establish absence, which supported read-only, descriptor-based API or verification sequence should be used? What guarantees and limitations apply regarding macOS versions, filesystem support and genuine retrieval failures? I reviewed the acl_get(3) documentation but could not find a clear explanation of this valid-descriptor ENOENT case: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/acl_get.3.html I am seeking the supported API contract, not asserting an OS defect or vulnerability. I do not want to set, delete or normalize ACLs on the objects being inspected, or treat an ambiguous result as success.
Replies
1
Boosts
0
Views
52
Activity
2d