Team-scoped keys introduce the ability to restrict your token authentication keys to either development or production environments. Topic-specific keys in addition to environment isolation allow you to associate each key with a specific Bundle ID streamlining key management.
For detailed instructions on accessing these features, read our updated documentation on establishing a token-based connection to APNs.
Delve into the world of built-in app and system services available to developers. Discuss leveraging these services to enhance your app's functionality and user experience.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I just saw another post regarding bookmarks on iOS where an Apple engineer made the following statement:
[quote='855165022, DTS Engineer, /thread/797469?answerId=855165022#855165022'] macOS is better at enforcing the "right" behavior, so code that works there will generally work on iOS. [/quote]
So I went back to my macOS code to double-check. Sure enough, the following statement:
let bookmark = try url.bookmarkData(options: .withSecurityScope)
fails 100% of the time.
I had seen earlier statements from other DTS Engineers recommending that any use of a URL be bracketed by start/stopAccessingSecurityScopedResource. And that makes a lot of sense. If "start" returns true, then call stop. But if start returns false, then it isn't needed, so don't call stop. No harm, no foul.
But what's confusing is this other, directly-related API where a security-scoped bookmark cannot be created under any circumstances because of the URL itself, some specific way the URL was initially created, and/or manipulated?
So, what I'm asking is if someone could elaborate on what would cause a failure to create a security-scoped bookmark? What kinds of URLs are valid for creation of security-scoped bookmarks? Are there operations on a URL that will then cause a failure to create a security-scoped bookmark? Is it allowed to pass the URL and/or bookmark back and forth between Objective-C and Swift?
I'm developing a new macOS app for release in the Mac App Store. I'm initially getting my URL from an NSOpenPanel. Then I store it in a SQLite database. I may access the URL again, after a restart, or after a year. I have a login item that also needs to read the database and access the URL.
I have additional complications as well, but they don't really matter. Before I get to any of that, I get a whole volume URL from an NSOpen panel in Swift, then, almost immediately, attempt to create a security-scoped bookmark. I cannot. I've tried many different combinations of options and flows of operation, but obviously not all.
I think this started happening with macOS 26, but that doesn't really matter. If this is new behaviour in macOS 26, then I must live with it.
My particular use requires a URL to a whole volume. Because of this, I don't actually seem to need a security-scoped bookmark at all. So I think I might simply get lucky for now.
But this still bothers me. I don't really like being lucky. I'd rather be right. I have other apps in development where this could be a bigger problem. It seems like I will need completely separate URL handling logic based on the type of URL the user selects.
And what of document-scoped URLs? This experience seems to strongly indicate that security-scoped URLs should only ever be document-scoped. I think in some of my debugging efforts I tried document-scoped URLs. They didn't fix the problem, but they seemed to make the entire process more straightforward and transparent. Can a single metadata-hosting file host multiple security-scoped bookmarks? Or should I have a separate one for each bookmark?
But the essence of my question is that this is supposed to be simple operation that, in certain cases, is a guaranteed failure. There are a mind-bogglingly large number of potential options and logic flows. Does there exist a set of options and logic flows for which the user can select a URL, any URL, with the explicit intent to persist it, and that my app can save, share with helper apps, and have it all work normally after restart?
I have an iOS app that allows user to select a folder (from Files). I want to bookmark that folder and later on (perhaps on a different launch of the app) access the contents of it. Is that scenario supported or not? Can't make it work for some reason (e.g. I'm getting no error from the call to create a bookmark, from a call to resolve the bookmark, the folder URL is not stale, but... startAccessingSecurityScopedResource() is returning false.
Hi, I'm trying to mount my FSKit volume with a client app (SwiftUI).
I already successfully did it with the "mount" command and I can instantiate my file-system with FSPathURLResource.
Also, I managed to mount the file-system with DiskArbitration in a SwiftUI app, but I only managed to get it working with FSBlockDeviceResource.
Is there a way to programmatically do it in a client app? Or is "mount" command currently the only option?
Observed few times that providerDidBegin(_:) delegate never called for the complete app session after app init(as part of this CXProvider registered) which was built with SDK 26 and running on iOS 26.
This issue observed multiple times with our testing. Since there is no providerDidBegin:, client is marking CallKit as not ready and never report any calls for VoIP APNS and ended up in app crash due to "[PKPushRegistry _terminateAppIfThereAreUnhandledVoIPPushes]"
Please refer for sysdiagnose logs : FB19778306
Hello,
I'm trying to adopt the new BGContinuedProcessingTask API, but I'm having a little trouble imagining how the API authors intended it be used. I saw the WWDC talk, but it lacked higher-level details about how to integrate this API, and I can't find a sample project.
I notice that we can list wildcard background task identifiers in our Info.plist files now, and it appears this is to be used with continued tasks - a user might start one video encoding, then while it is ongoing, enqueue another one from the same app, and these tasks would have identifiers such as "MyApp.VideoEncoding.ABCD" and "MyApp.VideoEncoding.EFGH" to distinguish them.
When it comes to implementing this, is the expectation that we:
a) Register a single handler for the wildcard pattern, which then figures out how to fulfil each request from the identifier of the passed-in task instance?
Or
b) Register a unique handler for each instance of the wildcard pattern? Since you can't unregister handlers, any resources captured by the handler would be leaked, so you'd need to make sure you only register immediately before submission - in other words register + submit should always be called as a pair.
Of course, I'd like to design my application to use this API as the authors intended it be used, but I'm just not entirely sure what that is. When I try to register a single handler for a wildcard pattern, the system rejects it at runtime (while allowing registrations for each instance of the pattern, indicating that at least my Info.plist is configured correctly). That points towards option B.
If it is option B, it's potentially worth calling that out in documentation - or even better, perhaps introduce a new call just for BGContinuedProcessingTask instead of the separate register + submit calls?
Thanks for your insight.
K
Aside: Also, it would be really nice if the handler closure would be async. Currently if you need to await on something, you need to launch an unstructured Task, but that causes issues since BGContinuedProcessingTask is not Sendable, so you can't pass it in to that Task to do things like update the title or mark the BGTask as complete.
For years I've been using Receigen for receipt verification for the Mac App Store build of my application. However, with the deprecation of exit code 173, I am moving to StoreKit-based verification and have a couple of questions.
I have followed the instructions from https://developer.apple.com/documentation/storekit/apptransaction/shared and have something like this (simplified):
Swift:
@objc class ValidateReceipt: NSObject {
@objc func validate() async -> Bool {
do {
let verificationResult = try await AppTransaction.shared
switch verificationResult {
case .verified(_ /*let appTransaction*/):
// StoreKit verified that the user purchased this app and
// the properties in the AppTransaction instance
return true;
default:
// The app transaction didn't pass StoreKit's verification
return false;
}
}
catch {
// Handle errors
return false;
}
}
}
Objective-C:
ValidateReceipt *validateReceipt = [[ValidateReceipt alloc] init];
[validateReceipt validateWithCompletionHandler:^(BOOL result) {
if (result)
{
// Successful app purchase validation
}
else
{
// App purchase validation failure
}
}];
Thing is, I always get a valid result, i.e., in ValidReceipt.validate(), the case .verified block always runs. Even when exporting a new release build of my app and running it (without any _MASReceipt).
When using exit code 173, an .app without a _MASReceipt would prompt for app store login. Nothing of the sort happens now.
Am I misunderstanding the documentation / doing something wrong / missing something obvious?
Testing Environment:
iOS Version: 26.0 Beta 7
Xcode Version: 17.0 Beta 6
Device: iPhone 16 Pro
Description:
We are implementing the new BGContinuedProcessingTask API and are using the wildcard identifier notation as described in the official documentation. Our Info.plist is correctly configured with a permitted identifier pattern, such as com.our-bundle.export.*.
We then register a single launch handler for this exact wildcard pattern. We are performing this registration within a UIViewController, which is a supported pattern as BGContinuedProcessingTask is explicitly exempt from the "register before applicationDidFinishLaunching" requirement, according to the BGTaskScheduler.h header file. The register method correctly returns true, indicating the registration was successful.
However, when we then try to submit a task with a unique identifier that matches this pattern (e.g., com.our-bundle.export.UUID), the BGTaskScheduler.shared.submit() call throws an NSInternalInconsistencyException and terminates the app. The error reason is: 'No launch handler registered for task with identifier com.our-bundle.export.UUID'.
This indicates that the system is not correctly matching the specific, unique identifier from the submit call to the registered wildcard pattern handler. This behavior contradicts the official documentation.
Steps to Reproduce:
Create a new Xcode project.
In Signing & Capabilities, add "Background Modes" (with "Background processing" checked) and "Background GPU Access".
Add a permitted identifier (e.g., "com.company.test.*") to BGTaskSchedulerPermittedIdentifiers in Info.plist.
In a UIViewController's viewDidLoad, register a handler for the wildcard pattern. Check that the register method returns true.
Immediately after, try to submit a BGContinuedProcessingTaskRequest with a unique identifier that matches the pattern.
Expected Results:
The submit call should succeed without crashing, and the task should be scheduled.
Actual Results:
The app crashes immediately upon calling submit(). The console shows an uncaught NSInternalInconsistencyException with the reason: 'No launch handler registered for task with identifier com.company.test.UUID'.
Workaround:
The issue can be bypassed if we register a new handler for each unique identifier immediately before submitting a request with that same unique identifier. This strongly suggests the bug is in the system's wildcard pattern-matching logic.
I’m seeing what looks like a regression on iOS 26 beta where a presented view controller dismisses when a user long‑presses a button inside a table view cell and drags downward.
Steps to reproduce
Present a UIViewController modally.
The controller contains a UITableView; each cell has a UIButton.
Long‑press and hold the UIButton in any cell.
While still holding, drag downward.
Expected
The button and/or table view handle the gesture; no interactive dismissal starts.
Actual
The system recognizes a pull‑to‑dismiss gesture and begins dismissing the presented controller.
Notes
Reproducible only on iOS 26 beta.
Not observed on earlier iOS versions in my testing.
Happens on both simulator and device (beta).
Environment
iOS: 26 beta (please see exact build)
When trying to login with sandbox account in my simulator, nothing happens, it just become inactive for few seconds and then it become active again prompting that I can login, again and again.
Topic:
App & System Services
SubTopic:
General
I'm developing an app that uses CloudKit synchronization with SwiftData and on visionOS I added an App Settings bundle. I have noticed that sometimes, when the app is open and the user changes a setting from the App Settings bundle, the following fatal error occurs:
SwiftData/BackingData.swift:831: Fatal error: This model instance was destroyed by calling ModelContext.reset and is no longer usable.
The setting is read within the App struct in the visionOS app target using @AppStorage and this value is in turn used to set the passthrough video dimming via the .preferredSurroundingsEffect modifier. The setting allows the user to specify the dimming level as dark, semi dark, or ultra dark.
The fatal error appears to occur intermittently although the first time it was observed was after adding the settings bundle. As such, I suspect there is some connection between those code changes and this fatal error even though they do not directly relate to SwiftData.
We have an application which is written in Swift, which activates Transparent Proxy network extension.
Our Transparent Proxy module is a system extension, which is exposing an app proxy provider interface (We are using NETransparentProxyProvider class and in extension’s Info.plist we use com.apple.networkextension.app-proxy key.)
We are using JAMF MDM profile for installing our transparent proxy in customer environment. We are using VPN payload(https://developer.apple.com/documentation/devicemanagement/vpn) for this network system extension.
This payload does not have any field for order.
As per https://developer.apple.com/documentation/devicemanagement/vpn/transparentproxy-data.dictionary documentation there is another payload for TransparentProxy and we could create a Transparent Proxy profile using iMazingProfile Editor.
Noticed that, if we add the Order attribute to the VPN/TransparentProxy payload, while installing the extension, the save to preferences fails with "Error in saving TP configuration in updateOnDemandRule permission denied" error.
Can we use this Order field to ordering the installed Transparent Proxy extension in a machine?
Customer devices will likely have other Transparent Proxy network extensions as well. We want to allow the Customer to control the order in which each Transparent Proxy network extension receives the network traffic.
How can we set the order of the Transparent proxy extension that can be deployed using MDM profile with VPN/TransparentProxy payload?
Attached the TransparentProxy payload profile for the reference.
DGWebProxy_TransparentProxy_iMazing
Topic:
App & System Services
SubTopic:
Networking
Tags:
Network Extension
System Extensions
Device Management
Product Timeout, In App purchase is approved in App Store Connect. The Product ID and Bundle ID match.
Environment
macOS App in TestFlight
Bundle ID: com.streamtime.StreamTime
App Version: 1.1 (Build 51)
StoreKit 2
Product ID: com.streamtime.premium
Status: App & Subscription Approved
Issue
StoreKit product request (Product.products(for:)) consistently times out after 60 seconds in TestFlight, despite all connectivity checks passing. The same code works perfectly in Xcode with local StoreKit configuration.
Diagnostic Results
✅ Successful checks:
App Store connectivity (HTTP 200 from buy.itunes.apple.com)
Backend API connectivity (HTTP 200)
StoreKit 2 API available
AppStore.canMakePayments: true
Valid receipt exists
Bundle ID matches
Product ID matches approved subscription
❌ Failing:
Product request times out after 60 seconds
No products returned
Code Implementation
// Direct product request (fails in TestFlight)
let products = try await Product.products(for: ["com.streamtime.premium"])
Logs
🔍 App Bundle ID: com.streamtime.StreamTime
🔍 Product ID: com.streamtime.premium
🔍 AppStore.canMakePayments: true
🔍 Apple Store connectivity: HTTP 200
🔵 Direct request for product ID: 'com.streamtime.premium'
⏱️ Direct request start time: 2025-08-30 10:21:32 +0000
❌ TIMEOUT: Product request took longer than 60 seconds
What I've Tried
Removed manual in-app-purchase entitlement (per Apple's guidance)
Using automatic signing
Verified subscription is approved in App Store Connect
Using Sandbox Apple ID in TestFlight
Verified all network connectivity
Questions
Why does StoreKit timeout only in TestFlight when all other connectivity works?
Are there additional configuration steps needed for macOS apps vs iOS?
Could this be related to the automatic in-app purchase entitlement?
Any guidance would be greatly appreciated as this is blocking our TestFlight validation.
Topic:
App & System Services
SubTopic:
StoreKit
I just find out there no option of removing duplicate photo on iOS 26 beta I was wondering if there is any other way to remove duplicate photo on my Photo gallery
Topic:
App & System Services
SubTopic:
General
I’m implementing subscriptions and running tests, and I noticed a behavior I’d like to confirm.
Plans in the app
Basic — Monthly
Basic — Annual
Premium — Monthly
Premium — Annual
Test environment
Sandbox (where ~1 day ≈ under 1 minute of real time)
steps
Start Basic (Monthly) using an introductory offer (free trial).
Create a crossgrade to Basic (Annual) (scheduled/queued).
After receiving a RENEWAL App Store Server Notification indicating the plan will move from trial to paid Basic (Annual), but before the trial actually expires, upgrade the user to Premium (Monthly).
Observed behavior (Sandbox) & questions
Even though there is still up to ~1 day of trial remaining (≈ under 1 minute in Sandbox), upgrading to Premium (Monthly) immediately ends the trial and activates the paid Premium plan right away.
Will this same behavior occur in Production?
If yes, is this the expected/acceptable behavior when upgrading during an active trial after a pending crossgrade?
Note: If we upgrade to Premium before the RENEWAL notification arrives, the remaining trial time is carried over in our tests.
In this flow, we see a RENEWAL notification for Basic (Annual) (moving from trial → paid), but then the user immediately upgrades to Premium (Monthly) and the trial ends at that moment.
In Production, would the charge for Basic (Annual) be refunded automatically since the user effectively switches to Premium immediately (and Basic Annual does not remain active)?
In Sandbox there’s no real charge, but I want to ensure we won’t see a situation in Production where Basic (Annual) is billed and not refunded, even though the subscription effectively moved to Premium right away.
Thanks in advance!
I’m implementing subscriptions and running tests, and I noticed a behavior I’d like to confirm.
Plans in the app
Basic — Monthly
Basic — Annual
Premium — Monthly
Premium — Annual
Test environment
Sandbox (where ~1 day ≈ under 1 minute of real time)
steps
Start Basic (Monthly) using an introductory offer (free trial).
Create a crossgrade to Basic (Annual) (scheduled/queued).
3.After receiving a RENEWAL App Store Server Notification indicating the plan will move from trial to paid Basic (Annual), but before the trial actually expires, upgrade the user to Premium (Monthly).
Observed behavior (Sandbox) & questions
Even though there is still up to ~1 day of trial remaining (≈ under 1 minute in Sandbox), upgrading to Premium (Monthly) immediately ends the trial and activates the paid Premium plan right away.
Will this same behavior occur in Production?
If yes, is this the expected/acceptable behavior when upgrading during an active trial after a pending crossgrade?
Note: If we upgrade to Premium before the RENEWAL notification arrives, the remaining trial time is carried over in our tests.
In this flow, we see a RENEWAL notification for Basic (Annual) (moving from trial → paid), but then the user immediately upgrades to Premium (Monthly) and the trial ends at that moment.
In Production, would the charge for Basic (Annual) be refunded automatically since the user effectively switches to Premium immediately (and Basic Annual does not remain active)?
In Sandbox there’s no real charge, but I want to ensure we won’t see a situation in Production where Basic (Annual) is billed and not refunded, even though the subscription effectively moved to Premium right away.
Thanks in advance!
when we use raise in GCD, the signal handler is executed asynchronously, whereas in pthread, it is executed synchronously as expected.
example:
#include <Foundation/Foundation.h>
#include <pthread/pthread.h>
static void HandleSignal(int sigNum, siginfo_t* signalInfo, void* userContext) {
printf("handle signal %d\n", sigNum);
printf("begin sleep\n");
sleep(3);
printf("end sleep\n");
}
void InstallSignal(void) {
static const int g_fatalSignals[] =
{
SIGABRT,
SIGBUS,
SIGFPE,
SIGILL,
SIGPIPE,
SIGSEGV,
SIGSYS,
SIGTRAP,
};
int fatalSignalsCount = sizeof(g_fatalSignals) / sizeof(int);
struct sigaction action = {{0}};
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
#if defined(__LP64__)
action.sa_flags |= SA_64REGSET;
#endif
sigemptyset(&action.sa_mask);
action.sa_sigaction = &HandleSignal;
struct sigaction pre_sa;
for(int i = 0; i < fatalSignalsCount; i++) {
int sigResult = sigaction(g_fatalSignals[i], &action, &pre_sa);
}
}
void* RaiseAbort(void *userdata) {
raise(SIGABRT);
printf("signal handler has finished\n");
return NULL;
}
int main(int argc, const char * argv[]) {
InstallSignal();
dispatch_async(dispatch_get_global_queue(0, 0), ^{
raise(SIGABRT);
// abort(); // abort() is ok
RaiseAbort(nullptr);
});
// pthread is ok
// pthread_t tid;
// int ret = pthread_create(&tid, NULL, RaiseAbort, NULL);
// if (ret != 0) {
// fprintf(stderr, "create thread failed\n");
// return EXIT_FAILURE;
// }
[[NSRunLoop mainRunLoop] run];
return 0;
}
console log:
signal handler has finished
handle signal 6
begin sleep
end sleep
As per : TN3120: Expected use cases for Network Extension packet tunnel providers | Apple Developer Documentation
It is clear that Packets that are read from NEPacketTunnelFlow are meant to be sent over a tunnel connection to a remote server for injection into a remote network. They are not meant to be dropped or re-injected back into the system.
In my usecase:
NEPacketTunnelProvider is separate process. which reads the packet using packetFlow.readPacketObjects
Send it over to other process i.e privileged helper(Non-bundle/command line tool/non sandboxed) via UDS IPC.
Helpers send to to remote tunnel and return back the packet to NEPacketTunnelFlow via same IPC.
NEPacketTunnelProvider uses packetFlow.writePacketObjects to inject packets.
Things works fine. We don't distribute it via Appstore.
We are now attempting to implement a on device bypass mechanism from helper tool side. Could you please suggest if there is any approach I could try, even if it involves proceeding at my own risk?
ICEcard app is "Emergency as a Service" platform. One of the key feature is to know about primary info, health info, or in case missing child , elderly using Face scan of registered user of app via another registered user of ICEcard app. App was working fine but last 2-3 week back got issue reported of app getting closed as soon Face scan option is selected.
to simulate issue > register > open face scan icon at bottom home screen> select any of option accident or health issue or information >> app closes immediately.
Android app is working fine.
link of app store.
https://apps.apple.com/in/app/ice-card-app/id6736453602
android link for reference
https://play.google.com/store/apps/details?id=com.rannlab.ice_card.ice_card&pcampaignid=web_share
Hey,
We also opened a feedback assistant request,
and also opened a ticket with Apple Developer Technical Support a while ago that notice the unmount problem also but it was before we pin point the problem to the Network Extension.
After a further investigation, we've found out that the root cause of this problem is cause by having a network filter from the NetworkExtension provider on (Specifically we have tested with the NEFilterDataProvider) while having a Xsan volume.
The NEFilterDataProvider causing problems for the Xsan, and is stalling the shutdown until we get a panic from watchdog timeout, and only then the mac is fully shutdown.
The problem from what we investigated and also talked with you, is that the Xsan process can't unmount the volume and stuck.
We have also noticed that if we install a network extension and allow the popup of the network filters, i.e enabled the NEFilterDataProvider the computer is stuck, and the finder is in a non responsive state until a reboot (Also probably due to the fact the Xsan is now in a problematic state).
This tests was done on latest versions of MacOs 13 & 14.
We have taken a sysdiagnose from the computer while we have tested.
Do you familiar with the problem (We got no answer on the feedback assistant)?
Thank you,
Idan
Hey, we also opened a bug regarding this behavior on April, back when you introduce the new event on MacOs 15.4
The bug ticket is: FB17139326
Starting macOs 15.4 you added a new event for the system extension framework named: tcc_modify
The event should be triggered every-time there is a change regarding the tcc db (granted / revoked using various ways).
One of the ways you can grant / revoke tcc db permission is by changing the user sqlite with root permissions.
You can change various permissions regarding the user for example the apps that allowed to use microphone permissions.
It is expected that when granted / revoked permissions using sqlite for microphone we will get notify from the system extension for tcc modify event.
but the actual result is that the permission is added without any tcc modify event.
We wanted to know if this is intentional that changing the user tcc db with root permissions, using sqlite and not conventional methods (user popup / settings), suppose to not initiate an event, and we should monitor them using other methods.
Thank you,
Idan