Hello everyone,
We're implementing Apple Pay on the web and are already live, processing transactions. However, we've noticed that occasionally the onlinePaymentCryptogram returned in the paymentData contains spaces, causing it to be rejected by acquirers.
Has anyone else encountered this issue? Any insights would be greatly appreciated.
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 am currently using the App Store Server API Get All Subscription Statuses in the app I am in charge of.
Please let me confirm the following regarding Get All Subscription Statuses.
■Prerequisites
The language used is Objective-c, and I am using both XCode 15 and 16. I also have an App Store Connect account.
■Questions
Is it possible to set and test each status of the App Store Server API Get All Subscription Statuses with TestFlight?
I cannot test IAP using sandbox account that I logged on from settings, it keeps show my regular Apple ID when I try to test IAP from TestFlight
This issue frustrate me and bunch of my colleagues, we cannot manage our subscription when sandbox account is default choosing Apple ID
I've seen people complaining about this issue a lot
Any help on resolving this issue would be really appreaciated
Hello Apple Developer Community,
I’m working on creating a chart that combines Screen Time Usage data with Workout Time from HealthKit.
I’ve successfully implemented a DeviceActivityReportExtension to fetch Screen Time data and draw a chart. I’m also able to read HealthKit data from the main app.
However, I’m having trouble integrating the HealthKit data into the View generated by the DeviceActivityReportExtension. I’ve attempted to read HealthKit data directly from the extension , but this doesn’t seem to work, likely due to HealthKit access restrictions in extensions.
I also tied using a shared object to pass HealthKit data to the extension, but unfortunately this didn’t seem to work as expected.
I’d greatly appreciate any suggestions on how to successfully integrate HealthKit data into the extension-generated View. Has anyone dealt with a similar challenge or found a workaround for this?
Thanks in advance for your help!
I have implemented the functionality to open my app when double-tapping the side button on an iPhone. However, whenever I double-tap the side button, my app always opens on the login screen. Instead of this default behavior, I want my app to navigate directly to a specific view when launched through the side button action.
I am using SwiftUI and have already integrated HCE (Host Card Emulation) entitlements and also configured with contactless payment. How can I achieve this behaviour so that my app opens a specific screen instead of always showing the login page?
Any guidance on handling this within SwiftUI would be greatly appreciated. Thank you!
Topic:
App & System Services
SubTopic:
Wallet
Hi everyone,
We're experiencing an issue with our Flutter app that uses PushKit, CallKit, and Janus for handling VoIP calls. Everything works fine when the app is in the foreground, but when the app is in the background or completely closed (terminated state), the behavior is inconsistent:
Sometimes, incoming calls are received as expected.
Other times, the app does nothing, and the call is not delivered at all.
Upon checking the console logs, we noticed that our app is being canceled (terminated by the system), which seems to be the reason why calls are not coming through. This happens randomly, making it difficult to reproduce consistently.
Additional Details:
The app is configured to handle VoIP notifications correctly.
We are using PushKit to wake up the app and trigger CallKit for the incoming call UI.
When the app is active, calls are handled correctly via Janus WebRTC signaling.
We have verified that background modes for VoIP are enabled in the Info.plist.
We suspect that iOS may be aggressively killing the app in the background, preventing incoming call notifications from reaching it.
Questions:
Has anyone experienced similar behavior with PushKit + CallKit on recent iOS versions?
Could iOS be terminating the app due to background execution policies?
Are there recommended best practices to ensure reliable delivery of VoIP notifications when the app is closed?
Any insights or suggestions would be greatly appreciated!
Thanks!
Addional Information:
this is the cancellation information at console: Received incoming message on topic hiperme.app at priority 10
por omisión 17:10:18.462084-0300 dasd CANCELED: com.apple.pushLaunch.hiperme.app:E8BACD at priority 10
Hi there, I'm facing an issue when disconnecting CarPlay that the navigation session seems to be in some weird state where it is not properly finished. So when I reconnect CarPlay the "Metadata in instrument cluster or HUD" does not update anymore until I start another navigation session and stop that one.
You can see that the instruction to the left on this screen recording is not updating anymore after a reconnect.
https://www.youtube.com/watch?v=sncxyJULjQk
I have a modified the CostalRoad sample app to add support for the HUD cluster and to auto start a navigation simulation when CarPlay connects.
https://github.com/g4rb4g3/CoastalRoads
Can anyone tell me what I have to do when CarPlay disconnect so I can start a new navigation session on reconnect that has a working HUD cluster?
Fun fact is that Apple Maps handles this quite nice (https://www.youtube.com/watch?v=OpJEIyGcwdo), it somehow manages to finish the navigation session and brings up the HUD cluster just fine on reconnect.
I wonder how I can achieve the same, anyone having an idea on that?
Hi,
We are using Firebase to configure APNs (Apple Push Notification Service) for sending push notifications. During local testing, the push notifications are received properly when the app is in the foreground or background. After TestFlight testing and passing review, we found that when the app is installed using the developer's Apple ID, push notifications are received correctly whether the app is in the foreground or background.
However, when the app is provided to other testers (using non-developer Apple IDs), notifications are only received when the app is in the foreground, and they are not triggered when the app is in the background or inactive state.
Request for Assistance:
Why, after TestFlight testing and passing review, does the app receive push notifications properly in the background when installed using the developer's Apple ID, but on other testers' devices, notifications are not received when the app is in the background?
Are there any differences in Apple ID types or device configurations (developer ID vs. regular tester ID) that could affect the behavior of push notifications in the background mode?
Do we need to apply any additional settings or permissions, particularly for handling background push notifications?
Are there any iOS version or device-specific limitations that could impact the proper delivery of background push notifications?
Additional Information:
The app is properly configured for APNs, and push notifications are being sent via Firebase.
In the developer's Apple ID test environment, the app receives push notifications properly whether it is in the foreground or background.
On other testers' devices, push notifications are only received when the app is in the foreground, and they are not received when the app is in the background.
All test devices have been verified to have notification permissions enabled, and Firebase configuration is correct.
We are developing an iOS app to connect to vehicles and trigger predefined vehicle controls (door lock/unlock) via the Digital Key framework.
We are currently blocked on several aspects and would appreciate your expertise to clarify the following queries.
How can we list down connected vehicle information?
What is the method to retrieve connection status?
How can we perform vehicle control actions (e.g., door lock/unlock)?
STEPS TO REPRODUCE
Starting the CarKeyRemoteControlSession to Fetch Vehicle Reports
Currently, we are using the following API to start a CarKeyRemoteControlSession:
open class func start(
delegate: any CarKeyRemoteControlSessionDelegate,
subscriptionRange subscriptionFunctionIDRange: ClosedRange? = nil,
with delegateCallbackQueue: DispatchQueue? = nil
) async throws -> CarKeyRemoteControlSession
After successfully creating the session, we check for vehicle reports using the vehicleReports property of CarKeyRemoteControlSession:
public var vehicleReports: [VehicleReport] { get throws }
Topic:
App & System Services
SubTopic:
General
I’ve created several shortcuts that tell me the stock price of a given company. The shortcut queries Yahoo Finance using Get Contents of URL, with the URL
https://finance.yahoo.com/quote/TICKER SYMBOL/, for example
https://finance.yahoo.com/quote/PLTR/ for Palantir or
https://finance.yahoo.com/quote/AAPL/ for Apple, etc.
Then it uses RegEx to parse out the numbers which it then formats and displays in a notification. Simple. It works great for several stocks, but for some reason, it does not work correctly for Palantir. It shows an older “previous close” price. Oddly, when I go to the website myself, it shows me the current stock price.
So for today Mar 21 https://finance.yahoo.com/quote/PLTR/ shows me $90.96 (correct) but the shortcut, via Get Contents of URL, shows $87.39 (incorrect). This $87.39 price is listed further down in the page as a "previous close” price. I don’t get it.
Here is a link to my Palantir shortcut:
https://www.icloud.com/shortcuts/edea6ee0261245f49b078efc74d632dd
Here is a link to my Apple shortcut:
https://www.icloud.com/shortcuts/54a416393203432aa356fe76373e3f8b
So the question is, why does Get Contents of URL show an old stock price but when I go to the site myself, it shows the correct stock price … and only for Palantir? I have about six shortcuts running correctly. Palantir is the only one that does not work.
Been banging my head on this one for weeks. Any advice would be much appreciated.
Thank you,
Rob
Hey everyone,
I have an app using the screen time api, I've had quite a few reports from users saying that our monitoring features stop working until they open our app. What happens is that activities and schedules set with the device activity monitor seem to disappear. This is something we check on app re-opens and so we schedule them again and that is why the monitoring starts working again.
Of course our current solution is not optimal since our app is mainly passive. Has anyone experienced these kinds of issue ?
This week I’m handling a DTS incident from a developer who wants to escalate privileges in their app. This is a tricky problem. Over the years I’ve explained aspects of this both here on DevForums and in numerous DTS incidents. Rather than do that again, I figured I’d collect my thoughts into one place and share them here.
If you have questions or comments, please start a new thread with an appropriate tag (Service Management or XPC are the most likely candidates here) in the App & System Services > Core OS topic area.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
BSD Privilege Escalation on macOS
macOS has multiple privilege models. Some of these were inherited from its ancestor platforms. For example, Mach messages has a capability-based privilege model. Others were introduced by Apple to address specific user scenarios. For example, macOS 10.14 and later have mandatory access control (MAC), as discussed in On File System Permissions.
One of the most important privilege models is the one inherited from BSD. This is the classic users and groups model. Many subsystems within macOS, especially those with a BSD heritage, use this model. For example, a packet tracing tool must open a BPF device, /dev/bpf*, and that requires root privileges. Specifically, the process that calls open must have an effective user ID of 0, that is, the root user. That process is said to be running as root, and escalating BSD privileges is the act of getting code to run as root.
IMPORTANT Escalating privileges does not bypass all privilege restrictions. For example, MAC applies to all processes, including those running as root. Indeed, running as root can make things harder because TCC will not display UI when a launchd daemon trips over a MAC restriction.
Escalating privileges on macOS is not straightforward. There are many different ways to do this, each with its own pros and cons. The best approach depends on your specific circumstances.
Note If you find operations where a root privilege restriction doesn’t make sense, feel free to file a bug requesting that it be lifted. This is not without precedent. For example, in macOS 10.2 (yes, back in 2002!) we made it possible to implement ICMP (ping) without root privileges. And in macOS 10.14 we removed the restriction on binding to low-number ports (r. 17427890). Nice!
Decide on One-Shot vs Ongoing Privileges
To start, decide whether you want one-shot or ongoing privileges. For one-shot privileges, the user authorises the operation, you perform it, and that’s that. For example, if you’re creating an un-installer for your product, one-shot privileges make sense because, once it’s done, your code is no longer present on the user’s system.
In contrast, for ongoing privileges the user authorises the installation of a launchd daemon. This code always runs as root and thus can perform privileged operations at any time.
Folks often ask for one-shot privileges but really need ongoing privileges. A classic example of this is a custom installer. In many cases installation isn’t a one-shot operation. Rather, the installer includes a software update mechanism that needs ongoing privileges. If that’s the case, there’s no point dealing with one-shot privileges at all. Just get ongoing privileges and treat your initial operation as a special case within that.
Keep in mind that you can convert one-shot privileges to ongoing privileges by installing a launchd daemon.
Just Because You Can, Doesn’t Mean You Should
Ongoing privileges represent an obvious security risk. Your daemon can perform an operation, but how does it know whether it should perform that operation?
There are two common ways to authorise operations:
Authorise the user
Authorise the client
To authorise the user, use Authorization Services. For a specific example of this, look at the EvenBetterAuthorizationSample sample code.
Note This sample hasn’t been updated in a while (sorry!) and it’s ironic that one of the things it demonstrates, opening a low-number port, no longer requires root privileges. However, the core concepts demonstrated by the sample are still valid.
The packet trace example from above is a situation where authorising the user with Authorization Services makes perfect sense. By default you might want your privileged helper tool to allow any user to run a packet trace. However, your code might be running on a Mac in a managed environment, where the site admin wants to restrict this to just admin users, or just a specific group of users. A custom authorisation right gives the site admin the flexibility to configure authorisation exactly as they want.
Authorising the client is a relatively new idea. It assumes that some process is using XPC to request that the daemon perform a privileged operation. In that case, the daemon can use XPC facilities to ensure that only certain processes can make such a request.
Doing this securely is a challenge. For specific API advice, see this post.
WARNING This authorisation is based on the code signature of the process’s main executable. If the process loads plug-ins [1], the daemon can’t tell the difference between a request coming from the main executable and a request coming from a plug-in.
[1] I’m talking in-process plug-ins here. Plug-ins that run in their own process, such as those managed by ExtensionKit, aren’t a concern.
Choose an Approach
There are (at least) seven different ways to run with root privileges on macOS:
A setuid-root executable
The sudo command-line tool
The authopen command-line tool
AppleScript’s do shell script command, passing true to the administrator privileges parameter
The osascript command-line tool to run an AppleScript
The AuthorizationExecuteWithPrivileges routine, deprecated since macOS 10.7
The SMJobSubmit routine targeting the kSMDomainSystemLaunchd domain, deprecated since macOS 10.10
The SMJobBless routine, deprecated since macOS 13
An installer package (.pkg)
The SMAppService class, a much-needed enhancement to the Service Management framework introduced in macOS 13
Note There’s one additional approach: The privileged file operation feature in NSWorkspace. I’ve not listed it here because it doesn’t let you run arbitrary code with root privileges. It does, however, have one critical benefit: It’s supported in sandboxed apps. See this post for a bunch of hints and tips.
To choose between them:
Do not use a setuid-root executable. Ever. It’s that simple! Doing that is creating a security vulnerability looking for an attacker to exploit it.
If you’re working interactively on the command line, use sudo, authopen, and osascript as you see fit.
IMPORTANT These are not appropriate to use as API. Specifically, while it may be possible to invoke sudo programmatically under some circumstances, by the time you’re done you’ll have code that’s way more complicated than the alternatives.
If you’re building an ad hoc solution to distribute to a limited audience, and you need one-shot privileges, use either AuthorizationExecuteWithPrivileges or AppleScript.
While AuthorizationExecuteWithPrivileges still works, it’s been deprecated for many years. Do not use it in a widely distributed product.
The AppleScript approach works great from AppleScript, but you can also use it from a shell script, using osascript, and from native code, using NSAppleScript. See the code snippet later in this post.
If you need one-shot privileges in a widely distributed product, consider using SMJobSubmit. While this is officially deprecated, it’s used by the very popular Sparkle update framework, and thus it’s unlikely to break without warning.
If you only need escalated privileges to install your product, consider using an installer package. That’s by far the easiest solution to this problem.
Keep in mind that an installer package can install a launchd daemon and thereby gain ongoing privileges.
If you need ongoing privileges but don’t want to ship an installer package, use SMAppService. If you need to deploy to older systems, use SMJobBless.
For instructions on using SMAppService, see Updating helper executables from earlier versions of macOS.
For a comprehensive example of how to use SMJobBless, see the EvenBetterAuthorizationSample sample code. For the simplest possible example, see the SMJobBless sample code. That has a Python script to help you debug your setup. Unfortunately this hasn’t been updated in a while; see this thread for more.
Hints and Tips
I’m sure I’ll think of more of these as time goes by but, for the moment, let’s start with the big one…
Do not run GUI code as root. In some cases you can make this work but it’s not supported. Moreover, it’s not safe. The GUI frameworks are huge, and thus have a huge attack surface. If you run GUI code as root, you are opening yourself up to security vulnerabilities.
Appendix: Running an AppleScript from Native Code
Below is an example of running a shell script with elevated privileges using NSAppleScript.
WARNING This is not meant to be the final word in privilege escalation. Before using this, work through the steps above to see if it’s the right option for you.
Hint It probably isn’t!
let url: URL = … file URL for the script to execute …
let script = NSAppleScript(source: """
on open (filePath)
if class of filePath is not text then
error "Expected a single file path argument."
end if
set shellScript to "exec " & quoted form of filePath
do shell script shellScript with administrator privileges
end open
""")!
// Create the Apple event.
let event = NSAppleEventDescriptor(
eventClass: AEEventClass(kCoreEventClass),
eventID: AEEventID(kAEOpenDocuments),
targetDescriptor: nil,
returnID: AEReturnID(kAutoGenerateReturnID),
transactionID: AETransactionID(kAnyTransactionID)
)
// Set up the direct object parameter to be a single string holding the
// path to our script.
let parameters = NSAppleEventDescriptor(string: url.path)
event.setDescriptor(parameters, forKeyword: AEKeyword(keyDirectObject))
// The `as NSAppleEventDescriptor?` is required due to a bug in the
// nullability annotation on this method’s result (r. 38702068).
var error: NSDictionary? = nil
guard let result = script.executeAppleEvent(event, error: &error) as NSAppleEventDescriptor? else {
let code = (error?[NSAppleScript.errorNumber] as? Int) ?? 1
let message = (error?[NSAppleScript.errorMessage] as? String) ?? "-"
throw NSError(domain: "ShellScript", code: code, userInfo: nil)
}
let scriptResult = result.stringValue ?? ""
Revision History
2025-03-24 Added info about authopen and osascript.
2024-11-15 Added info about SMJobSubmit. Made other minor editorial changes.
2024-07-29 Added a reference to the NSWorkspace privileged file operation feature. Made other minor editorial changes.
2022-06-22 First posted.
Is there a way to detect an incoming call with a React Native app? I have a fitness app and would like to pause the workout during the phone call.
I'd like to set the recordingYear in my Spotlight File Importer extension but the property is missing from CSSearchableItemAttributeSet
e.g. in the resulting in mdls I'd like to see:
kMDItemRecordingYear = 2008;
This would allow me to search in Finder by the recording year criteria.
There is a recordingDate property and I tried setting it to Date that only has a year but it didn't work. It just resulted in this:
kMDItemRecordingDate = "2008-01-01 00:00:00 +0000";
While testing an inapp purchase, if you purchase the same product twice from an account that does not have testflight permissions for the project and only has sandbox permissions, the second payment will receive the same transactionId as the first.
Why is that so? I know transactionID is unique.
IOS can record a key, a key video, but there is no key recording function, which is really bad👎Yeah, i hope you guys come on.💪
Topic:
App & System Services
SubTopic:
Automation & Scripting
I’m trying to develop a widget with a button that triggers an app intent.
I integrated the app intent into my app within a separate app framework. I tested it with Shortcuts and Siri, and it works well—it opens the app on the required screen. However, when I added a button Button(intent: MyIntent()) to my widget, it doesn’t work at all.
The only clue I found is the following message in the Xcode debug console:
“No ConnectionContext found for (some big integer)” when I tap on the widget's button.
However, I see the same message when running it through the Shortcuts app, and in that case, it works fine.
Does anyone know what might be causing this issue?
My Intent:
public struct OpenTextInputIntent: AppIntent {
public static var title: LocalizedStringResource = "Open text input"
public static var openAppWhenRun: Bool = true
@Parameter(title: "Predefined text")
public var predefinedText: String
@Dependency private var appCoordinator: AppCoordinatorProtocol
public init() { }
public func perform() async throws -> some IntentResult {
appCoordinator.openAddMessage(predefinedText: predefinedText)
return .result()
}
}
My widget's view:
struct SimpleWidgetView : View {
var entry: SimpleWidgetTimelineProvider.Entry
var body: some View {
ZStack(alignment: .leadingTop) {
button
}
}
private var button: some View {
Button(intent: OpenTextInputIntent()) {
Image(systemName: "mic.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.iconFrame()
}
.buttonStyle(PlainButtonStyle())
.foregroundStyle(Color.white)
.padding(10)
.background(Circle().fill(Color.accent))
}
}
Intents Registration in the app target:
struct MyAppPackage: AppIntentsPackage {
static var includedPackages: [any AppIntentsPackage.Type] {
[FrameworkIntentsPackage.self]
}
}
struct MyAppShortcutsProvider: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: OpenTextInputIntent(),
phrases: ["Add message in \(.applicationName)"],
shortTitle: "Message input",
systemImageName: "pencil.circle.fill"
)
}
}
What I'm missing?
As of iOS 18.3 SDK, Core Bluetooth is still mostly an Objective-C framework: key objects like CBPeripheral inherit from NSObjectProtocol and does not conform to Sendable.
CBCentralManager has a convenience initializer that allows the caller to provide a dispatch_queue for delegate callbacks. I want my Swift package that implements Core Bluetooth to conform to Swift 6 strict concurrency checking.
It is unsafe to dispatch the delegate events onto my own actor, as the passed in objects are presumably not thread-safe. What is the recommended concurrency safe way to implement Core Bluetooth in Swift 6 with strict concurrency checking enabled?
Hello everyone,
I’m running an Objective-C–based hybrid (native + web) shopping application and encountering a recurring issue on devices running iOS 18.1.1:
When the app launches, it only shows a white screen with the native frame visible—no web content loads.
Restarting or reinstalling the app doesn’t help. In one instance, toggling Airplane Mode on and off brought the app back to normal, but this workaround isn’t consistent.
There are no crash logs, so we can’t determine if it’s caused by a network error, cache conflict, or an OS-level bug.
So far, we have only seen this issue on iOS 18.1.1 devices. Because our app is a shopping platform, this significantly impacts users.
Questions:
Could this be related to a known bug or limitation in iOS 18.1.1?
Are there recommended diagnostic steps or workarounds for a hybrid app that shows a white screen without generating crash logs?
Which additional details (e.g., system logs, network traces, device configurations) might help isolate the cause?
Any insights or suggestions would be greatly appreciated. Thank you in advance!
Topic:
App & System Services
SubTopic:
General
Hello,
We are trying to implement Actionable Notifications on iOS via Remote Notifications.
According to Apple’s official documentation (Declaring Your Actionable Notification Types),
it is recommended to register notification categories at launch time.
However, in our use case, the number of buttons and their actions in the Actionable Notification are determined at the time of the Remote Notification request.
This means that we cannot predefine the categories at app launch but need to dynamically configure them based on the payload of the Remote Notification.
Our Approach
We are considering setting aps.mutable-content = 1 and using Notification Service Extension to modify the categoryIdentifier dynamically.
Below is the JSON payload we plan to use for Remote Notifications:
{
"aps": {
"alert": {
"title": "New Message Received!",
"body": "Check out the details."
},
"category": "DYNAMIC_CATEGORY",
"mutable-content": 1
},
"categoryData": {
"id": "DYNAMIC_CATEGORY",
"actions": [
{
"id": "REPLY_ACTION",
"title": "Reply",
"options": ["foreground"]
},
{
"id": "DELETE_ACTION",
"title": "Delete",
"options": ["destructive"]
}
]
}
}
Questions:
Can we dynamically configure Actionable Notifications based on the Remote Notification payload?
If we set categoryIdentifier in Notification Service Extension’s didReceive(_:withContentHandler:), will users still see the correct action buttons even if the app is terminated?
What is the recommended approach to dynamically configure Actionable Notifications at the time of receiving the Remote Notification, rather than at app launch?