Posts under App & System Services topic

Post

Replies

Boosts

Views

Activity

SiriKit: INPlayMediaIntent with a targeted speaker
I've got a streaming Radio app that loads an HLS stream into an AVAudioPlayer. I've set up an Intents extension that notifies SiriKit that my app must handle the INPlayMediaIntent in app, and, I'm able to successfully initiate the stream playing from my phone using the string "Play ". My intent handler in app looks like this: completionHandler(INPlayMediaIntentResponse(code: .success, userActivity: nil)) DispatchQueue.main.async { AudioPlayerService.shared.play() } The Audio Player service, in its init, does the following: try AVAudioSession.sharedInstance().setCategory( .playback, mode: .default, policy: .longFormAudio ) Additionally, in my Info.plist, I have the AirPlay optimization policy set to Long Form Audio. Having said all that, when I try to route my app to play "on a given HomePod speaker" ("play on ") the speaker routing instructions are never followed. I've looked and not been able to find where I might be able to instruct my app to follow the correct path here. I was assuming I could not trigger this behavior manually, as I believe I don't really have any control over AirPlay routing. Is there any guidance for working with SiriKit to do the right thing with regards to audio routing?
0
0
162
Feb ’26
Is testing of Age Range API available in xcode simulator?
From https://aninterestingwebsite.com/forums/thread/803945?answerId=862153022#862153022, the testing of Age Range API was not available through xcode simulator back in Oct 2025. Is this available now? In particular: Is requestAgeRange testing available through simulator? Is requestAgeRange testing with sandbox account available through simulator? Is isEligibleForAgeFeatures available through simulator? Is isEligibleForAgeFeatures testing with sandbox account available through simulator? If the answer is "yes" to any of the above, which version of the xcode and ios version should I use? So far I didn't get any of the above working on the simulator, and I can't find any documentation on the answers above. Thank you!
0
2
200
Dec ’25
Can I use AppIntent with tvOS?
The AppIntent feature is available on tvOS since OS 16. https://aninterestingwebsite.com/documentation/appintents I tried a real basic integration where I just want simply open a specific tab in my tabbar. But the perform action gets never called. Is it really possible already to use AppIntent on tvOS? Or is this feature still mostly targeted for mobile devices? Also, the documentaiton says so often something about shortcuts app and features, that are not available on tvOS, that I started doubting that the AppIntent is really usable on tvOS. If AppIntents are available and usable for tvOS, what could be wrong, so that I do not see the expected results?
0
0
34
2d
Testing TelephonyMessagingKit Outside of The EU
Is it possible to develop for TelephonyMessagingKit on iOS 26 outside of the EU? If so, how is this accomplished? I have added the 'Default Carrier Messaging App' entitlement to my project, but I do not see an option to set my app as a default option in settings on my device. I am not located inside of the EU, but would like to test this functionality.
0
0
118
Dec ’25
Texas age verification: revoked consent & notifications?
The published "Next steps for apps distributed in Texas" says "A parent or guardian in Texas can withdraw consent for any app, which will block launching of the app on the child or teen’s device." My question is: will this also block notifications sent to that app from showing up on that device? Or will notifications still be delivered to the notification center, even though the app can't be launched? (Specifically, notifications sent from a server via Firebase topic/token). If notifications are not blocked automatically, what is the expected flow for this scenario? My app sends notifications from a server like this. I could implement client-side code to say "if consent is revoked, unsubscribe from notifications", but if the OS blocks launching of the app, this client-side code would never run. Similarly, I could subscribe to the server notifications for when consent is revoked, but my app is free & accountless, so I'm not aware of any information in the server notification that I could use to identify the specific user whose notifications should be stopped. (For example my users won't have an appAccountToken because they never made a purchase). Guidance would be much appreciated. I'm trying to comply with the law but I don't know how.
0
0
233
Nov ’25
blockedApplications api to HIDE app categories?
Is there any way to use blockedApplications to hide all apps in a category? Currently, I use blockedApplications to hide individual apps, but it doesn’t work when I select an entire category. I thought the only solution would be to use shield, which doesn’t hide the apps but creates a blocking shield. However, I found an app on the App Store called Fokus, and it’s able to select a category and block all the apps in it. Does anyone know how this could be possible?
0
0
124
Nov ’25
How to identify which minor user's authorization has been revoked by the parent/guardian?
I followed the method outlined in Apple's documentation to test "Revocation of Consent." Our server received the notification sent by Apple, but the parsed data only contains the following content (some data has been modified for privacy, but the fields remain unchanged): { "receiptType": "Sandbox", "bundleId": "com.xxx.xxxxx", "receiptCreationDate": 1764932591296, "requestDate": 1764932591296, "originalPurchaseDate": 1375340400000, "originalApplicationVersion": "1.0", "appTransactionId": "705020051250081000", "originalPlatform": "iOS" } How can we identify that "a parent/guardian has revoked authorization for a specific user"? We are unable to determine which minor user should be restricted from using certain features of our app. I hope to receive a prompt response from Apple's technical experts! Thanks A Lot !
0
1
123
Dec ’25
Can the App Clip banner for full app download be disabled?
Hello, I have a question about the default UI in an App Clip. I know that when App Clip launches, a system banner appears at the top for a few seconds, prompting the user to download the full app from the App Store. I'd like to confirm if this is the standard, default behavior for all App Clips. More importantly, is there any way to disable or hide this banner? We would prefer to manage the prompt to download the full app within our own UI. Thanks in advance for your help!
0
0
65
Nov ’25
IOBluetoothHandsFreeDevice API confusion
I wonder how one would use IOBluetoothHandsFree APIs to interact from macOS app with a bluetooth device that implements bluetooth hands free profile. My current observation is as follows: IOBluetoothDevice object representing the device correctly identifies it as a hands free device, i.e.: there is a proper record in services array, that matches the kBluetoothSDPUUID16ServiceClassHandsFree uuid, the IOBluetoothDevice handsFreeDevice property returns 1 Attempt to create IOBluetoothHandsFreeDevice using IOBluetoothDevice as described above (i.e. [[IOBluetoothHandsFreeDevice alloc] initWithDevice: myIOBluetoothDeviceThatHasHandsFreeDevicePropertySetTo1 delegate: self]) results in the following output in debugger console: SRS-XB20 is not a hands free device but trying anyways. Subsequent call to connect on an object constructed as above results in the following stream of messages: API MISUSE: <CBClassicPeer: 0x1442447b0 6D801974-5457-9ECE-0A9B-8343EC4F60AA, SRS-XB20, connected, Paired, b8:d5:0b:03:62:70, devType: 19, PID: 0x1582, VID: 0x0039> Invalid RFCOMM CID -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x600003e5de00 SRS-XB20, b8-d5-0b-03-62-70, CID: 0, UUID: 110F > AddInstanceForFactory: No factory registered for id <CFUUID 0x600000b5e3e0> F8BB1C28-BAE8-11D6-9C31-00039315CD46 -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x600003e5de00 SRS-XB20, b8-d5-0b-03-62-70, CID: 0, UUID: 110F > API MISUSE: <CBClassicPeer: 0x1442447b0 6D801974-5457-9ECE-0A9B-8343EC4F60AA, SRS-XB20, connected, Paired, b8:d5:0b:03:62:70, devType: 19, PID: 0x1582, VID: 0x0039> Invalid RFCOMM CID Note that this device's handsFreeServiceRecord looks as follows: ServiceName: Hands-free unit RFCOMM ChannelID: 1 Attributes: { 0 = "uint32(65539)"; 256 = "string(Hands-free unit)"; 9 = "{ { uuid32(00 00 11 1e), uint32(262) } }"; 785 = "uint32(63)"; 1 = "uuid32(00 00 11 1e)"; 6 = "{ uint32(25966), uint32(106), uint32(256) }"; 4 = "{ { uuid32(00 00 01 00) }, { uuid32(00 00 00 03), uint32(1) } }"; } and explicit attempt to open RFCOMM channel no 1 ends like this: WARNING: Unknown error: 911 Failed to open RFCOMM channel -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x6000002036c0 SRS-XB20, b8-d5-0b-03-62-70, CID: 1, UUID: 111E > AddInstanceForFactory: No factory registered for id <CFUUID 0x600003719260> F8BB1C28-BAE8-11D6-9C31-00039315CD46 -[IOBluetoothRFCOMMChannel waitforChanneOpen] CID:1 - timed out waiting to open -[IOBluetoothDevice openRFCOMMChannelSync:withChannelID:delegate:] CID:1 error -536870212 call returned: -536870212
0
0
159
Jun ’25
WeatherKit entitlement and key not propagated — WeatherDaemon fails to generate JWT (Code=2)
Hello Apple Developer Support Team, I am the Account Holder of my Apple Developer Program team (Team ID: T2BKUF6E93). My iOS app is using Swift WeatherKit (WeatherService) on device. Although my environment is completely configured, the system WeatherDaemon consistently fails to generate the WeatherKit JWT token. My environment: Team type: Apple Developer Program (paid) Team ID: T2BKUF6E93 Account role: Account Holder Xcode: latest version Device: iPhone (real device) Provisioning Profile: iOS Team Provisioning Profile (auto-managed) Entitlement: com.apple.developer.weatherkit included WeatherKit Key: created successfully (.p8 downloaded) Bundle ID: correct and WeatherKit capability enabled App reinstalled after each configuration change Device rebooted Even after enabling WeatherKit capability and generating a WeatherKit Key, the system still fails to generate JWT: Failed to generate jwt token for: com.apple.weatherkit.authservice Error Domain=WeatherDaemon.WDSJWTAuthenticatorServiceListener.Errors Code=2 "(null)" The error persists across: multiple device restarts full clean/rebuild in Xcode deleting and reinstalling the app pulling the latest provisioning profiles waiting more than several hours for backend propagation What I suspect My WeatherKit entitlement and/or WeatherKit Key may not be fully propagated to the provisioning server or WeatherDaemon backend, even though everything appears correctly configured on the Developer Center. I kindly request the support team to: Verify whether the WeatherKit Entitlement is correctly attached to my app ID and provisioning profile. Verify whether my WeatherKit Key is properly registered and propagated for my team. Check if there are any backend propagation delays or stuck states for my Team ID (T2BKUF6E93). Confirm whether WeatherDaemon has permission to generate JWT for my app. Thank you Please let me know if any logs, screenshots, or provisioning profile identifiers are needed. Thank you for your help! Best regards, Jiangyang
0
1
281
Nov ’25
AppleScript access to "Show on all Spaces" Wallpaper setting
I am creating scripts to automatically switch the wallpapers on my multiple displays. System Events exposes almost all of the options accessible in the Wallpapers pane of system settings, but not the option to "Show on all Spaces". I want to add that option to the following script: tell application "System Events" set intervalSeconds to 900.0 set wpDir to POSIX file "/Path/to/Folder/" set picture rotation of every desktop to 1 set random order of every desktop to true set pictures folder of every desktop to wpDir set change interval of every desktop to intervalSeconds do shell script ("killall Dock") end tell Also, the foregoing script does not seem to successfully set the interval value, although it does not throw an error. Not sure why that does not work. Any thoughts or insights would be welcome. Thank you
0
0
188
May ’25
SMS Filter Extension - No Categories showing
Hi, I developed an iOS app which will do SMS filtering by following this documentation. https://aninterestingwebsite.com/documentation/identitylookup/sms-and-mms-message-filtering) I built the app and send Test Flights to different testers. All the Testers from Sri Lanka (an asian country) says filtering is working and they can see all the enabled categories on the Messages too (including iOS 26). But the testers from Mexico cannot see the categories and filtering is not working. On official documentation there is nothing about supported countries. But I found true caller article https://support.truecaller.com/support/solutions/articles/81000406341-how-do-i-enable-sms-filtering-on-iphone mentioning it support only few countries for SMS filtering. Currently available in the following countries: India, Nigeria, South Africa, Kenya, Bangladesh, Sri Lanka. Our previous Categories filtering are still available for: Australia, Bahrain, Canada, Ghana, Tanzania, United Kingdom, United Arab Emirates, United States of America, Zambia Following article https://clearstream.io/blog/ios-26-iphone-new-text-message-filtering is saying some categories are supported by only Brazil and India. Still I could not find any official documentations saying different country supports.
0
0
174
Nov ’25
Non–App Clip NFC URLs show CPSErrorDomain error 2 after creating 50+ Advanced App Clips
We’re seeing unexpected NFC behavior once our app has 50+ Advanced App Clips created. Expected: Scanning an NFC tag with a URL that is NOT an App Clip invocation should show the standard “Open in Safari” notification. Actual: After we create ~50+ Advanced App Clips, scanning NFC tags for URLs on the same domain that are not associated with App Clips consistently shows “CPSErrorDomain error 2” instead of the Safari prompt.
 QR codes for the same non–App Clip URLs work as expected (shows Safari prompt). Clearing the App Clips “Experience Cache” sometimes helps briefly, but the error returns on consequent scans. Notes: Domain has valid AASA. App Clip invocation URLs work as expected.
 The issue appears tied to the number of Advanced App Clips configured. Below ~50, non–App Clip NFC scans behave correctly; above that, they fail.
 Affected across multiple devices and iOS versions tested. Repro steps: Configure 50+ Advanced App Clips for paths on a single domain.
 Encode a different URL on the same domain that is NOT listed as an App Clip invocation into an NFC tag.
 Scan the NFC tag on iPhone.
 Observe “CPSErrorDomain error 2” instead of the “Open in Safari” notification. Impact: blocks our NFC use case for regular web links once we scale App Clip experiences. Sysdiagnose #: FB20563121
0
0
111
Nov ’25
How does ageGates actually affect the returned age range?
I’m trying to fully understand the purpose of the ageGates parameter in the AgeRangeService.requestAgeRange API. The official documentation includes the following statement: “The system may return geo-specific age ranges that override your provided age gates based on the person’s location and applicable regulations. When geo-specific ranges are required, the returned age range reflects regulatory requirements rather than the bounds of your age gates.” Based on this, it seems that even if my app provides specific age thresholds through the ageGates parameter, the system may override those boundaries depending on regional laws or regulations, and return a completely different lowerBound / upperBound than what my age gates would suggest. My current understanding is: ageGates indicates the thresholds my app uses to define its internal feature tiers, but the actual age range returned by the OS is determined by legal or regional requirements (e.g., COPPA, GDPR-K, AADC, SB2420), meaning the returned age range may not align with the age ranges implied by my ageGates values. I’d like to confirm whether this interpretation is correct. Additionally, if different regions may produce different lowerBound / upperBound values due to regulatory requirements, then it seems that: developers shouldn’t rely on fixed age buckets, and instead must implement feature gating logic dynamically based on whatever age range the OS returns. So my questions are: Is my understanding correct that ageGates is simply a hint that describes my app’s tier thresholds, and the OS may override those boundaries to comply with local regulations? If lowerBound / upperBound can vary across regions, what is the recommended way for developers to design their feature-gating logic? Should we avoid hardcoded age buckets and instead build flexible logic that adapts to whatever range the OS returns? I’d appreciate clarification so I can design our age-based policies appropriately and in a regulation-compliant way.
0
0
107
Dec ’25
Your Friend the System Log
The unified system log on Apple platforms gets a lot of stick for being ‘too verbose’. I understand that perspective: If you’re used to a traditional Unix-y system log, you might expect to learn something about an issue by manually looking through the log, and the unified system log is way too chatty for that. However, that’s a small price to pay for all its other benefits. This post is my attempt to explain those benefits, broken up into a series of short bullets. Hopefully, by the end, you’ll understand why I’m best friends with the system log, and why you should be too! If you have questions or comments about this, start a new thread and tag it with OSLog so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Your Friend the System Log Apple’s unified system log is very powerful. If you’re writing code for any Apple platform, and especially if you’re working on low-level code, it pays to become friends with the system log! The Benefits of Having a Such Good Friend The public API for logging is fast and full-featured. And it’s particularly nice in Swift. Logging is fast enough to leave log points [1] enabled in your release build, which makes it easier to debug issues that only show up in the field. The system log is used extensively by the OS itself, allowing you to correlate your log entries with the internal state of the system. Log entries persist for a long time, allowing you to investigate an issue that originated well before you noticed it. Log entries are classified by subsystem, category, and type. Each type has a default disposition, which determines whether that log entry is enable and, if it is, whether it persists in the log store. You can customise this, based on the subsystem, category, and type, in four different ways: Install a configuration profile created by Apple (all platforms) [2]. Add an OSLogPreferences property to your app’s Info.plist (all platforms). Run the log tool with the config command (macOS only) Create and install a custom configuration profile with the com.apple.system.logging payload (macOS only). When you log a value, you may tag it as private. These values are omitted from the log by default but you can configure the system to include them. For information on how to do that, see Recording Private Data in the System Log. The Console app displays the system log. On the left, select either your local Mac or an attached iOS device. Console can open and work with log snapshots (.logarchive). It also supports surprisingly sophisticated searching. For instructions on how to set up your search, choose Help > Console Help. Console’s search field supports copy and paste. For example, to set up a search for the subsystem com.foo.bar, paste subsystem:com.foo.bar into the field. Console supports saved searches. Again, Console Help has the details. Console supports viewing log entries in a specific timeframe. By default it shows the last 5 minutes. To change this, select an item in the Showing popup menu in the pane divider. If you have a specific time range of interest, select Custom, enter that range, and click Apply. Instruments has os_log and os_signpost instruments that record log entries in your trace. Use this to correlate the output of other instruments with log points in your code. Instruments can also import a log snapshot. Drop a .logarchive file on to Instruments and it’ll import the log into a trace document, then analyse the log with Instruments’ many cool features. The log command-line tool lets you do all of this and more from Terminal. The log stream subcommand supports multiple output formats. The default format includes column headers that describe the standard fields. The last column holds the log message prefixed by various fields. For example: cloudd: (Network) [com.apple.network:connection] nw_flow_disconnected … In this context: cloudd is the source process. (Network) is the source library. If this isn’t present, the log came from the main executable. [com.apple.network:connection] is the subsystem and category. Not all log entries have these. nw_flow_disconnected … is the actual message. There’s a public API to read back existing log entries, albeit one with significant limitations on iOS (more on that below). Every sysdiagnose log includes a snapshot of the system log, which is ideal for debugging hard-to-reproduce problems. For more details on that, see Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem. For general information about sysdiagnose logs, see Bug Reporting > Profiles and Logs. But you don’t have to use sysdiagnose logs. To create a quick snapshot of the system log, run the log tool with the collect subcommand. If you’re investigating recent events, use the --last argument to limit its scope. For example, the following creates a snapshot of log entries from the last 5 minutes: % sudo log collect --last 5m For more information, see: os > Logging OSLog log man page os_log man page (in section 3) os_log man page (in section 5) WWDC 2016 Session 721 Unified Logging and Activity Tracing [1] Well, most log points. If you’re logging thousands of entries per second, the very small overhead for these disabled log points add up. [2] These debug profiles can also help you focus on the right subsystems and categories. Imagine you’re investigating a CryptoTokenKit problem. If you download and dump the CryptoTokenKit debug profile, you’ll see this: % security cms -D -i "CTK_iOS_Logging.mobileconfig" | plutil -p - { … "PayloadContent" => [ 0 => { … "Subsystems" => { "com.apple.CryptoTokenKit" => {…} "com.apple.CryptoTokenKit.APDU" => {…} } } ] … } That’s a hint that log entries relevant to CryptoTokenKit have a subsystem of either com.apple.CryptoTokenKit and com.apple.CryptoTokenKit.APDU, so it’d make sense to focus on those. Foster Your Friendship Good friendships take some work on your part, and your friendship with the system log is no exception. Follow these suggestions for getting the most out of the system log. The system log has many friends, and it tries to love them all equally. Don’t abuse that by logging too much. One key benefit of the system log is that log entries persist for a long time, allowing you to debug issues with their roots in the distant past. But there’s a trade off here: The more you log, the shorter the log window, and the harder it is to debug such problems. Put some thought into your subsystem and category choices. One trick here is to use the same category across multiple subsystems, allowing you to track issues as they cross between subsystems in your product. Or use one subsystem with multiple categories, so you can search on the subsystem to see all your logging and then focus on specific categories when you need to. Don’t use too many unique subsystem and context pairs. As a rough guide: One is fine, ten is OK, 100 is too much. Choose your log types wisely. The documentation for each OSLogType value describes the default behaviour of that value; use that information to guide your choices. Remember that disabled log points have a very low cost. It’s fine to leave chatty logging in your product if it’s disabled by default. Some app extension types have access to extremely sensitive user data and thus run in a restricted sandbox, one that prevents them from exporting any data. For example, an iOS Network Extension content filter data provider runs in such a sandbox. While I’ve never investigated this for other app extension types, an iOS NE content filter data provider cannot record system log entries. This restriction only applies if the provider is distribution signed. A development-signed provider can record system log entries. Apple platforms have accumulated many different logging APIs over the years. All of these are effectively deprecated [1] in favour of the system log API discussed in this post. That includes: NSLog (documented here) CFShow (documented here) Apple System Log (see the asl man page) syslog (see the syslog man page) Most of these continue to work [2], simply calling through to the underlying system log. However, there are good reasons to move on to the system log API directly: It lets you control the subsystem and category, making it much easier to track down your log entries. It lets you control whether data is considered private or public. In Swift, the Logger API is type safe, avoiding the classic bug of mixing up your arguments and your format specifiers. [1] Some formally and some informally. [2] Although you might bump into new restrictions. For example, the macOS Tahoe 26 Release Notes describe such a change for NSLog. No Friend Is Perfect The system log API is hard to wrap. The system log is so efficient because it’s deeply integrated with the compiler. If you wrap the system log API, you undermine that efficiency. For example, a wrapper like this is very inefficient: -*-*-*-*-*- DO NOT DO THIS -*-*-*-*-*- void myLog(const char * format, ...) { va_list ap; va_start(ap, format); char * str = NULL; vasprintf(&str, format, ap); os_log_debug(sLog, "%s", str); free(str); va_end(ap); } -*-*-*-*-*- DO NOT DO THIS -*-*-*-*-*- This is mostly an issue with the C API, because the modern Swift API is nice enough that you rarely need to wrap it. If you do wrap the C API, use a macro and have that pass the arguments through to the underlying os_log_xyz macro. Note If you’re curious about why adding a wrapper is bad, see my explanation on this thread. iOS has very limited facilities for reading the system log. Currently, an iOS app can only read entries created by that specific process, using .currentProcessIdentifier scope. This is annoying if, say, the app crashed and you want to know what it was doing before the crash. What you need is a way to get all log entries written by your app (r. 57880434). There are two known bugs with the .currentProcessIdentifier scope. The first is that the .reverse option doesn’t work (r. 87622922). You always get log entries in forward order. The second is that the getEntries(with:at:matching:) method doesn’t honour its position argument (r. 87416514). You always get all available log entries. Xcode 15 has a shiny new console interface. For the details, watch WWDC 2023 Session 10226 Debug with structured logging. For some other notes about this change, search the Xcode 15 Release Notes for 109380695. In older versions of Xcode the console pane was not a system log client (r. 32863680). Rather, it just collected and displayed stdout and stderr from your process. This approach had a number of consequences: The system log does not, by default, log to stderr. Xcode enabled this by setting an environment variable, OS_ACTIVITY_DT_MODE. The existence and behaviour of this environment variable is an implementation detail and not something that you should rely on. Xcode sets this environment variable when you run your program from Xcode (Product > Run). It can’t set it when you attach to a running process (Debug > Attach to Process). Xcode’s Console pane does not support the sophisticated filtering you’d expect in a system log client. When I can’t use Xcode 15, I work around the last two by ignoring the console pane and instead running Console and viewing my log entries there. If you don’t see the expected log entries in Console, make sure that you have Action > Include Info Messages and Action > Include Debug Messages enabled. The system log interface is available within the kernel but it has some serious limitations. Here’s the ones that I’m aware of: Prior to macOS 14.4, there was no subsystem or category support (r. 28948441). There is no support for annotations like {public} and {private}. Adding such annotations causes the log entry to be dropped (r. 40636781). The system log interface is also available to DriverKit drivers. For more advice on that front, see this thread. Metal shaders can log using the interface described in section 6.19 of the Metal Shading Language Specification. Revision History 2025-09-18 Added a link to the macOS Tahoe 26 Release Notes discussion of NSLog. Remove the beta epithet when referring to Xcode 15. It’s been released for a while now (-: 2025-08-19 Added information about effectively deprecated logging APIs, like NSLog. 2025-08-11 Added information about the restricted sandbox applied to iOS Network Extension content filter data providers. 2025-07-21 Added a link to a thread that explains why wrapping the system log API is bad. 2025-05-30 Fixed a grammo. 2025-04-09 Added a note explaining how to use a debug profile to find relevant log subsystems and categories. 2025-02-20 Added some info about DriverKit. 2024-10-22 Added some notes on interpreting the output from log stream. 2024-09-17 The kernel now includes subsystem and category support. 2024-09-16 Added a link to the the Metal logging interface. 2023-10-20 Added some Instruments tidbits. 2023-10-13 Described a second known bug with the .currentProcessIdentifier scope. Added a link to Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem. 2023-08-28 Described a known bug with the .reverse option in .currentProcessIdentifier scope. 2023-06-12 Added a call-out to the Xcode 15 Beta Release Notes. 2023-06-06 Updated to reference WWDC 2023 Session 10226. Added some notes about the kernel’s system log support. 2023-03-22 Made some minor editorial changes. 2023-03-13 Reworked the Xcode discussion to mention OS_ACTIVITY_DT_MODE. 2022-10-26 Called out the Showing popup in Console and the --last argument to log collect. 2022-10-06 Added a link WWDC 2016 Session 721 Unified Logging and Activity Tracing. 2022-08-19 Add a link to Recording Private Data in the System Log. 2022-08-11 Added a bunch of hints and tips. 2022-06-23 Added the Foster Your Friendship section. Made other editorial changes. 2022-05-12 First posted.
0
0
13k
Sep ’25
Subject: Call Directory Extension Enable Failure for Individual User
Subject: Call Directory Extension Enable Failure for Individual User Dear Apple Developer Support, We are experiencing an issue with our Call Directory Extension where one specific user cannot enable it, while thousands of other users on the same iOS version can enable it successfully. Issue Details: App: 美信 (Midea Connect) Problem: Extension fails to enable with error: "请求'美信'的数据时失败" (Failed to request data from app) Affected: 1 user out of thousands iOS Version: 26.0.1 What Works: All other users can enable the extension normally Same iOS version, no issues App Group and Extension identifier are correctly configured User Has Tried: Reinstall app - No effect Toggle extension off/on - Still fails Restart device - No improvement
0
0
71
Oct ’25
CarKeyErrorCode in the CarKey framework
I have a question regarding CarKeyErrorCode in the CarKey framework. I plan to use the following methods in the CarKey framework: CarKeyRemoteControl.start CarKeyRemoteControlSession.vehicleReports CarKeyRemoteControlSession.perform RemoteKeylessEntryAction.ExecutionRequest.results Each of the above methods throws an Error. Are these different from CarKeyErrorCode? Is CarKeyErrorCode only used in CarKeyRemoteControlSessionDelegate.remoteControlSession(_:didInvalidateWithError:)? If methods 1-4 do not return CarKeyErrorCode, what kind of Error do they return? Thank you in advance.
0
0
87
Oct ’25
Presumably its not possible to use declared age range in an extension?
Its possible to add the Declared Age Range entitlement to extensions, in particular I'm looking at a Notification Service Extension. However the DAR requestAgeRange() API takes a view controller as a parameter. Presumably therefore its not possible for a notification service extension to obtain the age range itself directly? Yes the extension can read it from shared groups if the app reads it and set it into the group. However the scenario I'm thinking of is this: App runs and gets the age range. Sets its functionality accordingly. The server sends pushes which are intercepted by the notification service extension, the extension adjusts its functionality based upon what the app wrote to shared groups The user changes the age range setting, but the app doesn't run. The extension keeps receiving pushes but its functionality is now out of sync with the age range as its not able to obtain it directly
0
0
100
Oct ’25
SiriKit: INPlayMediaIntent with a targeted speaker
I've got a streaming Radio app that loads an HLS stream into an AVAudioPlayer. I've set up an Intents extension that notifies SiriKit that my app must handle the INPlayMediaIntent in app, and, I'm able to successfully initiate the stream playing from my phone using the string "Play ". My intent handler in app looks like this: completionHandler(INPlayMediaIntentResponse(code: .success, userActivity: nil)) DispatchQueue.main.async { AudioPlayerService.shared.play() } The Audio Player service, in its init, does the following: try AVAudioSession.sharedInstance().setCategory( .playback, mode: .default, policy: .longFormAudio ) Additionally, in my Info.plist, I have the AirPlay optimization policy set to Long Form Audio. Having said all that, when I try to route my app to play "on a given HomePod speaker" ("play on ") the speaker routing instructions are never followed. I've looked and not been able to find where I might be able to instruct my app to follow the correct path here. I was assuming I could not trigger this behavior manually, as I believe I don't really have any control over AirPlay routing. Is there any guidance for working with SiriKit to do the right thing with regards to audio routing?
Replies
0
Boosts
0
Views
162
Activity
Feb ’26
Is testing of Age Range API available in xcode simulator?
From https://aninterestingwebsite.com/forums/thread/803945?answerId=862153022#862153022, the testing of Age Range API was not available through xcode simulator back in Oct 2025. Is this available now? In particular: Is requestAgeRange testing available through simulator? Is requestAgeRange testing with sandbox account available through simulator? Is isEligibleForAgeFeatures available through simulator? Is isEligibleForAgeFeatures testing with sandbox account available through simulator? If the answer is "yes" to any of the above, which version of the xcode and ios version should I use? So far I didn't get any of the above working on the simulator, and I can't find any documentation on the answers above. Thank you!
Replies
0
Boosts
2
Views
200
Activity
Dec ’25
Can I use AppIntent with tvOS?
The AppIntent feature is available on tvOS since OS 16. https://aninterestingwebsite.com/documentation/appintents I tried a real basic integration where I just want simply open a specific tab in my tabbar. But the perform action gets never called. Is it really possible already to use AppIntent on tvOS? Or is this feature still mostly targeted for mobile devices? Also, the documentaiton says so often something about shortcuts app and features, that are not available on tvOS, that I started doubting that the AppIntent is really usable on tvOS. If AppIntents are available and usable for tvOS, what could be wrong, so that I do not see the expected results?
Replies
0
Boosts
0
Views
34
Activity
2d
Testing TelephonyMessagingKit Outside of The EU
Is it possible to develop for TelephonyMessagingKit on iOS 26 outside of the EU? If so, how is this accomplished? I have added the 'Default Carrier Messaging App' entitlement to my project, but I do not see an option to set my app as a default option in settings on my device. I am not located inside of the EU, but would like to test this functionality.
Replies
0
Boosts
0
Views
118
Activity
Dec ’25
Texas age verification: revoked consent & notifications?
The published "Next steps for apps distributed in Texas" says "A parent or guardian in Texas can withdraw consent for any app, which will block launching of the app on the child or teen’s device." My question is: will this also block notifications sent to that app from showing up on that device? Or will notifications still be delivered to the notification center, even though the app can't be launched? (Specifically, notifications sent from a server via Firebase topic/token). If notifications are not blocked automatically, what is the expected flow for this scenario? My app sends notifications from a server like this. I could implement client-side code to say "if consent is revoked, unsubscribe from notifications", but if the OS blocks launching of the app, this client-side code would never run. Similarly, I could subscribe to the server notifications for when consent is revoked, but my app is free & accountless, so I'm not aware of any information in the server notification that I could use to identify the specific user whose notifications should be stopped. (For example my users won't have an appAccountToken because they never made a purchase). Guidance would be much appreciated. I'm trying to comply with the law but I don't know how.
Replies
0
Boosts
0
Views
233
Activity
Nov ’25
blockedApplications api to HIDE app categories?
Is there any way to use blockedApplications to hide all apps in a category? Currently, I use blockedApplications to hide individual apps, but it doesn’t work when I select an entire category. I thought the only solution would be to use shield, which doesn’t hide the apps but creates a blocking shield. However, I found an app on the App Store called Fokus, and it’s able to select a category and block all the apps in it. Does anyone know how this could be possible?
Replies
0
Boosts
0
Views
124
Activity
Nov ’25
Reading the enabled/ disabled status of Message Filter Extension from settings
Currently I am not finding any API to read the status of Message Filter Extension from settings. Are we planning for any future releases ?
Replies
0
Boosts
0
Views
376
Activity
Nov ’25
How to identify which minor user's authorization has been revoked by the parent/guardian?
I followed the method outlined in Apple's documentation to test "Revocation of Consent." Our server received the notification sent by Apple, but the parsed data only contains the following content (some data has been modified for privacy, but the fields remain unchanged): { "receiptType": "Sandbox", "bundleId": "com.xxx.xxxxx", "receiptCreationDate": 1764932591296, "requestDate": 1764932591296, "originalPurchaseDate": 1375340400000, "originalApplicationVersion": "1.0", "appTransactionId": "705020051250081000", "originalPlatform": "iOS" } How can we identify that "a parent/guardian has revoked authorization for a specific user"? We are unable to determine which minor user should be restricted from using certain features of our app. I hope to receive a prompt response from Apple's technical experts! Thanks A Lot !
Replies
0
Boosts
1
Views
123
Activity
Dec ’25
Can the App Clip banner for full app download be disabled?
Hello, I have a question about the default UI in an App Clip. I know that when App Clip launches, a system banner appears at the top for a few seconds, prompting the user to download the full app from the App Store. I'd like to confirm if this is the standard, default behavior for all App Clips. More importantly, is there any way to disable or hide this banner? We would prefer to manage the prompt to download the full app within our own UI. Thanks in advance for your help!
Replies
0
Boosts
0
Views
65
Activity
Nov ’25
Reading the status of Call blocking extension and Message Filter Exension from settings
Are we planning to have some APIs or methods to know that status of Call blocking extension and message filter extension in future releases as currently it is not available.
Replies
0
Boosts
0
Views
114
Activity
Nov ’25
IOBluetoothHandsFreeDevice API confusion
I wonder how one would use IOBluetoothHandsFree APIs to interact from macOS app with a bluetooth device that implements bluetooth hands free profile. My current observation is as follows: IOBluetoothDevice object representing the device correctly identifies it as a hands free device, i.e.: there is a proper record in services array, that matches the kBluetoothSDPUUID16ServiceClassHandsFree uuid, the IOBluetoothDevice handsFreeDevice property returns 1 Attempt to create IOBluetoothHandsFreeDevice using IOBluetoothDevice as described above (i.e. [[IOBluetoothHandsFreeDevice alloc] initWithDevice: myIOBluetoothDeviceThatHasHandsFreeDevicePropertySetTo1 delegate: self]) results in the following output in debugger console: SRS-XB20 is not a hands free device but trying anyways. Subsequent call to connect on an object constructed as above results in the following stream of messages: API MISUSE: <CBClassicPeer: 0x1442447b0 6D801974-5457-9ECE-0A9B-8343EC4F60AA, SRS-XB20, connected, Paired, b8:d5:0b:03:62:70, devType: 19, PID: 0x1582, VID: 0x0039> Invalid RFCOMM CID -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x600003e5de00 SRS-XB20, b8-d5-0b-03-62-70, CID: 0, UUID: 110F > AddInstanceForFactory: No factory registered for id <CFUUID 0x600000b5e3e0> F8BB1C28-BAE8-11D6-9C31-00039315CD46 -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x600003e5de00 SRS-XB20, b8-d5-0b-03-62-70, CID: 0, UUID: 110F > API MISUSE: <CBClassicPeer: 0x1442447b0 6D801974-5457-9ECE-0A9B-8343EC4F60AA, SRS-XB20, connected, Paired, b8:d5:0b:03:62:70, devType: 19, PID: 0x1582, VID: 0x0039> Invalid RFCOMM CID Note that this device's handsFreeServiceRecord looks as follows: ServiceName: Hands-free unit RFCOMM ChannelID: 1 Attributes: { 0 = "uint32(65539)"; 256 = "string(Hands-free unit)"; 9 = "{ { uuid32(00 00 11 1e), uint32(262) } }"; 785 = "uint32(63)"; 1 = "uuid32(00 00 11 1e)"; 6 = "{ uint32(25966), uint32(106), uint32(256) }"; 4 = "{ { uuid32(00 00 01 00) }, { uuid32(00 00 00 03), uint32(1) } }"; } and explicit attempt to open RFCOMM channel no 1 ends like this: WARNING: Unknown error: 911 Failed to open RFCOMM channel -[IOBluetoothRFCOMMChannel setupRFCOMMChannelForDevice] No channel <IOBluetoothRFCOMMChannel: 0x6000002036c0 SRS-XB20, b8-d5-0b-03-62-70, CID: 1, UUID: 111E > AddInstanceForFactory: No factory registered for id <CFUUID 0x600003719260> F8BB1C28-BAE8-11D6-9C31-00039315CD46 -[IOBluetoothRFCOMMChannel waitforChanneOpen] CID:1 - timed out waiting to open -[IOBluetoothDevice openRFCOMMChannelSync:withChannelID:delegate:] CID:1 error -536870212 call returned: -536870212
Replies
0
Boosts
0
Views
159
Activity
Jun ’25
WeatherKit entitlement and key not propagated — WeatherDaemon fails to generate JWT (Code=2)
Hello Apple Developer Support Team, I am the Account Holder of my Apple Developer Program team (Team ID: T2BKUF6E93). My iOS app is using Swift WeatherKit (WeatherService) on device. Although my environment is completely configured, the system WeatherDaemon consistently fails to generate the WeatherKit JWT token. My environment: Team type: Apple Developer Program (paid) Team ID: T2BKUF6E93 Account role: Account Holder Xcode: latest version Device: iPhone (real device) Provisioning Profile: iOS Team Provisioning Profile (auto-managed) Entitlement: com.apple.developer.weatherkit included WeatherKit Key: created successfully (.p8 downloaded) Bundle ID: correct and WeatherKit capability enabled App reinstalled after each configuration change Device rebooted Even after enabling WeatherKit capability and generating a WeatherKit Key, the system still fails to generate JWT: Failed to generate jwt token for: com.apple.weatherkit.authservice Error Domain=WeatherDaemon.WDSJWTAuthenticatorServiceListener.Errors Code=2 "(null)" The error persists across: multiple device restarts full clean/rebuild in Xcode deleting and reinstalling the app pulling the latest provisioning profiles waiting more than several hours for backend propagation What I suspect My WeatherKit entitlement and/or WeatherKit Key may not be fully propagated to the provisioning server or WeatherDaemon backend, even though everything appears correctly configured on the Developer Center. I kindly request the support team to: Verify whether the WeatherKit Entitlement is correctly attached to my app ID and provisioning profile. Verify whether my WeatherKit Key is properly registered and propagated for my team. Check if there are any backend propagation delays or stuck states for my Team ID (T2BKUF6E93). Confirm whether WeatherDaemon has permission to generate JWT for my app. Thank you Please let me know if any logs, screenshots, or provisioning profile identifiers are needed. Thank you for your help! Best regards, Jiangyang
Replies
0
Boosts
1
Views
281
Activity
Nov ’25
AppleScript access to "Show on all Spaces" Wallpaper setting
I am creating scripts to automatically switch the wallpapers on my multiple displays. System Events exposes almost all of the options accessible in the Wallpapers pane of system settings, but not the option to "Show on all Spaces". I want to add that option to the following script: tell application "System Events" set intervalSeconds to 900.0 set wpDir to POSIX file "/Path/to/Folder/" set picture rotation of every desktop to 1 set random order of every desktop to true set pictures folder of every desktop to wpDir set change interval of every desktop to intervalSeconds do shell script ("killall Dock") end tell Also, the foregoing script does not seem to successfully set the interval value, although it does not throw an error. Not sure why that does not work. Any thoughts or insights would be welcome. Thank you
Replies
0
Boosts
0
Views
188
Activity
May ’25
SMS Filter Extension - No Categories showing
Hi, I developed an iOS app which will do SMS filtering by following this documentation. https://aninterestingwebsite.com/documentation/identitylookup/sms-and-mms-message-filtering) I built the app and send Test Flights to different testers. All the Testers from Sri Lanka (an asian country) says filtering is working and they can see all the enabled categories on the Messages too (including iOS 26). But the testers from Mexico cannot see the categories and filtering is not working. On official documentation there is nothing about supported countries. But I found true caller article https://support.truecaller.com/support/solutions/articles/81000406341-how-do-i-enable-sms-filtering-on-iphone mentioning it support only few countries for SMS filtering. Currently available in the following countries: India, Nigeria, South Africa, Kenya, Bangladesh, Sri Lanka. Our previous Categories filtering are still available for: Australia, Bahrain, Canada, Ghana, Tanzania, United Kingdom, United Arab Emirates, United States of America, Zambia Following article https://clearstream.io/blog/ios-26-iphone-new-text-message-filtering is saying some categories are supported by only Brazil and India. Still I could not find any official documentations saying different country supports.
Replies
0
Boosts
0
Views
174
Activity
Nov ’25
Non–App Clip NFC URLs show CPSErrorDomain error 2 after creating 50+ Advanced App Clips
We’re seeing unexpected NFC behavior once our app has 50+ Advanced App Clips created. Expected: Scanning an NFC tag with a URL that is NOT an App Clip invocation should show the standard “Open in Safari” notification. Actual: After we create ~50+ Advanced App Clips, scanning NFC tags for URLs on the same domain that are not associated with App Clips consistently shows “CPSErrorDomain error 2” instead of the Safari prompt.
 QR codes for the same non–App Clip URLs work as expected (shows Safari prompt). Clearing the App Clips “Experience Cache” sometimes helps briefly, but the error returns on consequent scans. Notes: Domain has valid AASA. App Clip invocation URLs work as expected.
 The issue appears tied to the number of Advanced App Clips configured. Below ~50, non–App Clip NFC scans behave correctly; above that, they fail.
 Affected across multiple devices and iOS versions tested. Repro steps: Configure 50+ Advanced App Clips for paths on a single domain.
 Encode a different URL on the same domain that is NOT listed as an App Clip invocation into an NFC tag.
 Scan the NFC tag on iPhone.
 Observe “CPSErrorDomain error 2” instead of the “Open in Safari” notification. Impact: blocks our NFC use case for regular web links once we scale App Clip experiences. Sysdiagnose #: FB20563121
Replies
0
Boosts
0
Views
111
Activity
Nov ’25
How does ageGates actually affect the returned age range?
I’m trying to fully understand the purpose of the ageGates parameter in the AgeRangeService.requestAgeRange API. The official documentation includes the following statement: “The system may return geo-specific age ranges that override your provided age gates based on the person’s location and applicable regulations. When geo-specific ranges are required, the returned age range reflects regulatory requirements rather than the bounds of your age gates.” Based on this, it seems that even if my app provides specific age thresholds through the ageGates parameter, the system may override those boundaries depending on regional laws or regulations, and return a completely different lowerBound / upperBound than what my age gates would suggest. My current understanding is: ageGates indicates the thresholds my app uses to define its internal feature tiers, but the actual age range returned by the OS is determined by legal or regional requirements (e.g., COPPA, GDPR-K, AADC, SB2420), meaning the returned age range may not align with the age ranges implied by my ageGates values. I’d like to confirm whether this interpretation is correct. Additionally, if different regions may produce different lowerBound / upperBound values due to regulatory requirements, then it seems that: developers shouldn’t rely on fixed age buckets, and instead must implement feature gating logic dynamically based on whatever age range the OS returns. So my questions are: Is my understanding correct that ageGates is simply a hint that describes my app’s tier thresholds, and the OS may override those boundaries to comply with local regulations? If lowerBound / upperBound can vary across regions, what is the recommended way for developers to design their feature-gating logic? Should we avoid hardcoded age buckets and instead build flexible logic that adapts to whatever range the OS returns? I’d appreciate clarification so I can design our age-based policies appropriately and in a regulation-compliant way.
Replies
0
Boosts
0
Views
107
Activity
Dec ’25
Your Friend the System Log
The unified system log on Apple platforms gets a lot of stick for being ‘too verbose’. I understand that perspective: If you’re used to a traditional Unix-y system log, you might expect to learn something about an issue by manually looking through the log, and the unified system log is way too chatty for that. However, that’s a small price to pay for all its other benefits. This post is my attempt to explain those benefits, broken up into a series of short bullets. Hopefully, by the end, you’ll understand why I’m best friends with the system log, and why you should be too! If you have questions or comments about this, start a new thread and tag it with OSLog so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Your Friend the System Log Apple’s unified system log is very powerful. If you’re writing code for any Apple platform, and especially if you’re working on low-level code, it pays to become friends with the system log! The Benefits of Having a Such Good Friend The public API for logging is fast and full-featured. And it’s particularly nice in Swift. Logging is fast enough to leave log points [1] enabled in your release build, which makes it easier to debug issues that only show up in the field. The system log is used extensively by the OS itself, allowing you to correlate your log entries with the internal state of the system. Log entries persist for a long time, allowing you to investigate an issue that originated well before you noticed it. Log entries are classified by subsystem, category, and type. Each type has a default disposition, which determines whether that log entry is enable and, if it is, whether it persists in the log store. You can customise this, based on the subsystem, category, and type, in four different ways: Install a configuration profile created by Apple (all platforms) [2]. Add an OSLogPreferences property to your app’s Info.plist (all platforms). Run the log tool with the config command (macOS only) Create and install a custom configuration profile with the com.apple.system.logging payload (macOS only). When you log a value, you may tag it as private. These values are omitted from the log by default but you can configure the system to include them. For information on how to do that, see Recording Private Data in the System Log. The Console app displays the system log. On the left, select either your local Mac or an attached iOS device. Console can open and work with log snapshots (.logarchive). It also supports surprisingly sophisticated searching. For instructions on how to set up your search, choose Help > Console Help. Console’s search field supports copy and paste. For example, to set up a search for the subsystem com.foo.bar, paste subsystem:com.foo.bar into the field. Console supports saved searches. Again, Console Help has the details. Console supports viewing log entries in a specific timeframe. By default it shows the last 5 minutes. To change this, select an item in the Showing popup menu in the pane divider. If you have a specific time range of interest, select Custom, enter that range, and click Apply. Instruments has os_log and os_signpost instruments that record log entries in your trace. Use this to correlate the output of other instruments with log points in your code. Instruments can also import a log snapshot. Drop a .logarchive file on to Instruments and it’ll import the log into a trace document, then analyse the log with Instruments’ many cool features. The log command-line tool lets you do all of this and more from Terminal. The log stream subcommand supports multiple output formats. The default format includes column headers that describe the standard fields. The last column holds the log message prefixed by various fields. For example: cloudd: (Network) [com.apple.network:connection] nw_flow_disconnected … In this context: cloudd is the source process. (Network) is the source library. If this isn’t present, the log came from the main executable. [com.apple.network:connection] is the subsystem and category. Not all log entries have these. nw_flow_disconnected … is the actual message. There’s a public API to read back existing log entries, albeit one with significant limitations on iOS (more on that below). Every sysdiagnose log includes a snapshot of the system log, which is ideal for debugging hard-to-reproduce problems. For more details on that, see Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem. For general information about sysdiagnose logs, see Bug Reporting > Profiles and Logs. But you don’t have to use sysdiagnose logs. To create a quick snapshot of the system log, run the log tool with the collect subcommand. If you’re investigating recent events, use the --last argument to limit its scope. For example, the following creates a snapshot of log entries from the last 5 minutes: % sudo log collect --last 5m For more information, see: os > Logging OSLog log man page os_log man page (in section 3) os_log man page (in section 5) WWDC 2016 Session 721 Unified Logging and Activity Tracing [1] Well, most log points. If you’re logging thousands of entries per second, the very small overhead for these disabled log points add up. [2] These debug profiles can also help you focus on the right subsystems and categories. Imagine you’re investigating a CryptoTokenKit problem. If you download and dump the CryptoTokenKit debug profile, you’ll see this: % security cms -D -i "CTK_iOS_Logging.mobileconfig" | plutil -p - { … "PayloadContent" => [ 0 => { … "Subsystems" => { "com.apple.CryptoTokenKit" => {…} "com.apple.CryptoTokenKit.APDU" => {…} } } ] … } That’s a hint that log entries relevant to CryptoTokenKit have a subsystem of either com.apple.CryptoTokenKit and com.apple.CryptoTokenKit.APDU, so it’d make sense to focus on those. Foster Your Friendship Good friendships take some work on your part, and your friendship with the system log is no exception. Follow these suggestions for getting the most out of the system log. The system log has many friends, and it tries to love them all equally. Don’t abuse that by logging too much. One key benefit of the system log is that log entries persist for a long time, allowing you to debug issues with their roots in the distant past. But there’s a trade off here: The more you log, the shorter the log window, and the harder it is to debug such problems. Put some thought into your subsystem and category choices. One trick here is to use the same category across multiple subsystems, allowing you to track issues as they cross between subsystems in your product. Or use one subsystem with multiple categories, so you can search on the subsystem to see all your logging and then focus on specific categories when you need to. Don’t use too many unique subsystem and context pairs. As a rough guide: One is fine, ten is OK, 100 is too much. Choose your log types wisely. The documentation for each OSLogType value describes the default behaviour of that value; use that information to guide your choices. Remember that disabled log points have a very low cost. It’s fine to leave chatty logging in your product if it’s disabled by default. Some app extension types have access to extremely sensitive user data and thus run in a restricted sandbox, one that prevents them from exporting any data. For example, an iOS Network Extension content filter data provider runs in such a sandbox. While I’ve never investigated this for other app extension types, an iOS NE content filter data provider cannot record system log entries. This restriction only applies if the provider is distribution signed. A development-signed provider can record system log entries. Apple platforms have accumulated many different logging APIs over the years. All of these are effectively deprecated [1] in favour of the system log API discussed in this post. That includes: NSLog (documented here) CFShow (documented here) Apple System Log (see the asl man page) syslog (see the syslog man page) Most of these continue to work [2], simply calling through to the underlying system log. However, there are good reasons to move on to the system log API directly: It lets you control the subsystem and category, making it much easier to track down your log entries. It lets you control whether data is considered private or public. In Swift, the Logger API is type safe, avoiding the classic bug of mixing up your arguments and your format specifiers. [1] Some formally and some informally. [2] Although you might bump into new restrictions. For example, the macOS Tahoe 26 Release Notes describe such a change for NSLog. No Friend Is Perfect The system log API is hard to wrap. The system log is so efficient because it’s deeply integrated with the compiler. If you wrap the system log API, you undermine that efficiency. For example, a wrapper like this is very inefficient: -*-*-*-*-*- DO NOT DO THIS -*-*-*-*-*- void myLog(const char * format, ...) { va_list ap; va_start(ap, format); char * str = NULL; vasprintf(&str, format, ap); os_log_debug(sLog, "%s", str); free(str); va_end(ap); } -*-*-*-*-*- DO NOT DO THIS -*-*-*-*-*- This is mostly an issue with the C API, because the modern Swift API is nice enough that you rarely need to wrap it. If you do wrap the C API, use a macro and have that pass the arguments through to the underlying os_log_xyz macro. Note If you’re curious about why adding a wrapper is bad, see my explanation on this thread. iOS has very limited facilities for reading the system log. Currently, an iOS app can only read entries created by that specific process, using .currentProcessIdentifier scope. This is annoying if, say, the app crashed and you want to know what it was doing before the crash. What you need is a way to get all log entries written by your app (r. 57880434). There are two known bugs with the .currentProcessIdentifier scope. The first is that the .reverse option doesn’t work (r. 87622922). You always get log entries in forward order. The second is that the getEntries(with:at:matching:) method doesn’t honour its position argument (r. 87416514). You always get all available log entries. Xcode 15 has a shiny new console interface. For the details, watch WWDC 2023 Session 10226 Debug with structured logging. For some other notes about this change, search the Xcode 15 Release Notes for 109380695. In older versions of Xcode the console pane was not a system log client (r. 32863680). Rather, it just collected and displayed stdout and stderr from your process. This approach had a number of consequences: The system log does not, by default, log to stderr. Xcode enabled this by setting an environment variable, OS_ACTIVITY_DT_MODE. The existence and behaviour of this environment variable is an implementation detail and not something that you should rely on. Xcode sets this environment variable when you run your program from Xcode (Product > Run). It can’t set it when you attach to a running process (Debug > Attach to Process). Xcode’s Console pane does not support the sophisticated filtering you’d expect in a system log client. When I can’t use Xcode 15, I work around the last two by ignoring the console pane and instead running Console and viewing my log entries there. If you don’t see the expected log entries in Console, make sure that you have Action > Include Info Messages and Action > Include Debug Messages enabled. The system log interface is available within the kernel but it has some serious limitations. Here’s the ones that I’m aware of: Prior to macOS 14.4, there was no subsystem or category support (r. 28948441). There is no support for annotations like {public} and {private}. Adding such annotations causes the log entry to be dropped (r. 40636781). The system log interface is also available to DriverKit drivers. For more advice on that front, see this thread. Metal shaders can log using the interface described in section 6.19 of the Metal Shading Language Specification. Revision History 2025-09-18 Added a link to the macOS Tahoe 26 Release Notes discussion of NSLog. Remove the beta epithet when referring to Xcode 15. It’s been released for a while now (-: 2025-08-19 Added information about effectively deprecated logging APIs, like NSLog. 2025-08-11 Added information about the restricted sandbox applied to iOS Network Extension content filter data providers. 2025-07-21 Added a link to a thread that explains why wrapping the system log API is bad. 2025-05-30 Fixed a grammo. 2025-04-09 Added a note explaining how to use a debug profile to find relevant log subsystems and categories. 2025-02-20 Added some info about DriverKit. 2024-10-22 Added some notes on interpreting the output from log stream. 2024-09-17 The kernel now includes subsystem and category support. 2024-09-16 Added a link to the the Metal logging interface. 2023-10-20 Added some Instruments tidbits. 2023-10-13 Described a second known bug with the .currentProcessIdentifier scope. Added a link to Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem. 2023-08-28 Described a known bug with the .reverse option in .currentProcessIdentifier scope. 2023-06-12 Added a call-out to the Xcode 15 Beta Release Notes. 2023-06-06 Updated to reference WWDC 2023 Session 10226. Added some notes about the kernel’s system log support. 2023-03-22 Made some minor editorial changes. 2023-03-13 Reworked the Xcode discussion to mention OS_ACTIVITY_DT_MODE. 2022-10-26 Called out the Showing popup in Console and the --last argument to log collect. 2022-10-06 Added a link WWDC 2016 Session 721 Unified Logging and Activity Tracing. 2022-08-19 Add a link to Recording Private Data in the System Log. 2022-08-11 Added a bunch of hints and tips. 2022-06-23 Added the Foster Your Friendship section. Made other editorial changes. 2022-05-12 First posted.
Replies
0
Boosts
0
Views
13k
Activity
Sep ’25
Subject: Call Directory Extension Enable Failure for Individual User
Subject: Call Directory Extension Enable Failure for Individual User Dear Apple Developer Support, We are experiencing an issue with our Call Directory Extension where one specific user cannot enable it, while thousands of other users on the same iOS version can enable it successfully. Issue Details: App: 美信 (Midea Connect) Problem: Extension fails to enable with error: "请求'美信'的数据时失败" (Failed to request data from app) Affected: 1 user out of thousands iOS Version: 26.0.1 What Works: All other users can enable the extension normally Same iOS version, no issues App Group and Extension identifier are correctly configured User Has Tried: Reinstall app - No effect Toggle extension off/on - Still fails Restart device - No improvement
Replies
0
Boosts
0
Views
71
Activity
Oct ’25
CarKeyErrorCode in the CarKey framework
I have a question regarding CarKeyErrorCode in the CarKey framework. I plan to use the following methods in the CarKey framework: CarKeyRemoteControl.start CarKeyRemoteControlSession.vehicleReports CarKeyRemoteControlSession.perform RemoteKeylessEntryAction.ExecutionRequest.results Each of the above methods throws an Error. Are these different from CarKeyErrorCode? Is CarKeyErrorCode only used in CarKeyRemoteControlSessionDelegate.remoteControlSession(_:didInvalidateWithError:)? If methods 1-4 do not return CarKeyErrorCode, what kind of Error do they return? Thank you in advance.
Replies
0
Boosts
0
Views
87
Activity
Oct ’25
Presumably its not possible to use declared age range in an extension?
Its possible to add the Declared Age Range entitlement to extensions, in particular I'm looking at a Notification Service Extension. However the DAR requestAgeRange() API takes a view controller as a parameter. Presumably therefore its not possible for a notification service extension to obtain the age range itself directly? Yes the extension can read it from shared groups if the app reads it and set it into the group. However the scenario I'm thinking of is this: App runs and gets the age range. Sets its functionality accordingly. The server sends pushes which are intercepted by the notification service extension, the extension adjusts its functionality based upon what the app wrote to shared groups The user changes the age range setting, but the app doesn't run. The extension keeps receiving pushes but its functionality is now out of sync with the age range as its not able to obtain it directly
Replies
0
Boosts
0
Views
100
Activity
Oct ’25