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.

Posts under General subtopic

Post

Replies

Boosts

Views

Activity

Declared Age Range API – Clarification on checkEligibility() behavior (eligibility vs region)
Hello, While reviewing the latest FAQ and documentation for the Declared Age Range API, we have some questions regarding the behavior of checkEligibility()—specifically how it relates to user eligibility, geographic jurisdiction, and regulatory requirements. Context From the documentation, it appears that checkEligibility() indicates whether a user is eligible to share their declared age range. However, it is unclear whether this eligibility also incorporates jurisdiction-specific requirements (e.g., certain U.S. states with age assurance regulations). We would appreciate clarification on the following points: Eligibility vs Region: Does checkEligibility() return true based on the user’s eligibility to share age information only, or does it also depend on the user’s geographic region (e.g., specific U.S. states like Texas)? Region-Specific Laws (Texas Example): In scenarios where certain jurisdictions (such as Texas) require age assurance features, while other U.S. states may not, how does checkEligibility() behave? User Consent vs Regulatory Requirement: If a user denies age sharing, but they are located in a region where age-related regulatory features are mandated, how does checkEligibility() behave? Will it return false because the user denied consent? Or will it still return true due to regulatory requirements overriding user preference? Source of Region Determination: Does the Declared Age Range API internally determine the user’s applicable region (e.g., based on IP address, Apple ID region, or device settings) when evaluating checkEligibility()? Should developers independently determine jurisdiction (e.g., using IP-based geolocation) to apply region-specific rules, or is checkEligibility() intended to fully abstract both eligibility and jurisdiction requirements?
1
1
424
Jul ’26
DeclaredAgeRange API not triggering in regulated regions (Brazil, Utah) — Is it functioning in production?
Hi, We've implemented age assurance logic in our app using the DeclaredAgeRange framework to comply with regulations in Brazil (Digital ECA, effective March 17, 2026) and Utah (App Store Accountability Act, effective May 6, 2026). Our implementation calls AgeRangeService.shared.isEligibleForAgeFeatures on app launch to determine whether the current user is subject to age assurance requirements, and proceeds to call requestAgeRange(ageGates:) accordingly. However, after monitoring in production since the Brazil enforcement date, we've consistently observed isEligibleForAgeFeatures returning false for users in regulated regions, with no age range data being returned. What we'd like to clarify: Is isEligibleForAgeFeatures currently returning true for users in Brazil in production (not sandbox)? For Utah — given that HB 498 pushed the developer compliance deadline to May 6, 2027, will isEligibleForAgeFeatures reflect the original May 6, 2026 activation date or the revised 2027 date? Is there a known rollout schedule or gradual activation plan for these regions that would explain why the flag remains false even after the legal enforcement dates have passed? We've seen similar reports from other developers on these forums, so it seems this may be a widespread issue rather than an implementation problem on our end. Any official guidance on the current status of the API in regulated regions would be greatly appreciated. Thanks.
1
1
683
Jul ’26
Shallow Depth Entitlement and Underwater Auto-Launch: App Not Appearing in "When Submerged"
I've a question for you maybe you can help me. My watchOS app has: WKSupportsAutomaticDepthLaunch = true WKBackgroundModes = underwater-depth com.apple.developer.submerged-shallow-depth-and-pressure = true entitlement present in codesign and embedded provisioning profile The app uses the shallow depth entitlement, but it does not appear in: Settings → General → Auto-Launch → When Submerged. Is the shallow depth entitlement sufficient for appearing in the system underwater auto-launch app list, or is the full submerged depth entitlement required?
0
0
242
Jul ’26
PushToTalk session sometimes returns silence data after activation
Hello! Thank you for bringing the new iPhone experience with the PushToTalk framework. I have a working walkie talkie app based on the PushToTalk framework. Everything works fine except for an intermittent bug that I face from time to time on different devices with different iOS versions, from iOS 18 to iOS 26.2 Beta. Sometimes the app goes into a state where the AVAudioInputNode input node tap returns buffers with a constant size that contain only silence. Leaving and rejoining a channel helps, but relaunching or reinstalling (from Xcode) the app does not. Rebooting the device or deleting and reinstalling the app also helps. I do not activate the audio session in my app. I only configure it on launch using setCategory(.playAndRecord, options: [.defaultToSpeaker, .allowBluetooth]) So the flow is: channelManager?.requestBeginTransmitting(channelUUID: globalChannelUUID) func channelManager( _ channelManager: PTChannelManager, channelUUID: UUID, didBeginTransmittingFrom source: PTChannelTransmitRequestSource ) func channelManager( _ channelManager: PTChannelManager, didActivate audioSession: AVAudioSession ) { /// ... installTapAndStart() } private func installTapAndStart() { let inputNode = audioEngine.inputNode let hardwareFormat = inputNode.outputFormat(forBus: 0) guard let targetFormat = AVAudioFormat( commonFormat: .pcmFormatFloat32, sampleRate: configuration.audioSampleRate, channels: configuration.audioChannelsCount, interleaved: true ) else { handleError(RecorderError.invalidAudioFormat) return } let converter = AVAudioConverter(from: hardwareFormat, to: targetFormat)! print("[QUICOpusRecorder]: installTap") inputNode.installTap(onBus: 0, bufferSize: tapBufferSize, format: hardwareFormat) { [weak self] buffer, _ in guard let self else { return } // Here I handle audio data and sometimes get silence } //... do { audioEngine.prepare() try audioEngine.start() } catch { print(" ⚠️ Audio engine start error: \(error)") handleError(error) } } Moreover, if the app is in the foreground and PushToTalk gets stuck in this “silence bug”, I can avoid relying on the PushToTalk flow and simulate audio session activation manually in code. In this case I do not request a transmission and do not use any PushToTalk related code, and the app captures audio data perfectly. Once I leave the channel and rejoin it again, the issue is fixed and I start to receive non silent buffers of varying size, as expected. It works for a while. It can work fine for a day or more, communicating without launching the app, or with the app in the foreground. But it can also go into the “silence” state 30 minutes after working normally. I have no clue why this happens. The only thing I notice is that when the app is in this “stuck silence bug” state, iOS does not play its “chirp” system sound when audio recording starts. P.S. Channel descriptor restoration code: extension PushToTalkEngine: PTChannelRestorationDelegate { public func channelDescriptor(restoredChannelUUID channelUUID: UUID) -> PTChannelDescriptor { print("☀️ \(#function) channelUUID: \(channelUUID)") Task { @MainActor in // Here I fetch more detailed channel data asynchronously do { await initChannelManagerIfNeeded(channelUUID: channelUUID) let channelDescriptor = currentChannelDescriptor() lastChannelDescriptorName = channelDescriptor.name try await channelManager?.setChannelDescriptor( channelDescriptor, channelUUID: channelUUID ) } catch { handleError(error) } } return PTChannelDescriptor(name: "Loading...", image: nil) } } private func initChannelManagerIfNeeded(channelUUID: UUID? = nil) async { guard let channelUUID = channelUUID ?? currentUser?.globalChannelUUID else { print("❌ No global channel uuid found") return } do { guard channelManager == nil else { try await channelManager?.setTransmissionMode(.halfDuplex, channelUUID: channelUUID) return } channelManager = try await PTChannelManager.channelManager( delegate: self, restorationDelegate: self ) try await channelManager?.setTransmissionMode(.halfDuplex, channelUUID: channelUUID) } catch { handleError(error) } }
3
0
1k
Jul ’26
Understanding Crash Reporter Extension lifecycle and debugging behavior
Hi! I have a few questions about the lifecycle and capabilities of the Crash Reporter Extension. Besides using the corpsePort to inspect the crashed process through Mach APIs, is it safe/supported/recommended for the extension to access files in a shared App Group container? Are there any caveats or exceptions we should be aware of, for example around memory-mapped files, file coordination, or filesystem access after the host app has crashed? Shall we use some particular APIs for this kind of shared resource or not? While debugging the extension, I noticed that when I trigger a crash in the app I am debugging, LLDB does not stop inside the extension (it also ends up stopping the debugging session). However, I can observe that the extension does run, because it writes data into a shared App Group directory related to the crash. Is this expected behavior? Is there a recommended way to debug the Crash Reporter Extension reliably (with lldb, or other way)? More generally, I would like to better understand the extension lifecycle: When exactly does the extension start running? How long can it live after the app crashes? Is there a time limit for operating on the corpse process? Is the extension subject to resource limits similar to other app extensions, such as memory, disk, CPU, watchdog, or jetsam constraints? If the Crash Reporter Extension itself crashes, how can we detect that? Would those crashes appear in Xcode Organizer, or is there another recommended way to observe them? Any clarification around the supported lifecycle, debugging model, and resource limits would be very useful.
4
1
591
Jun ’26
AlertConfiguration.AlertSound.named plays system default despite CAF in main bundle (AlarmKit, iOS 26.5)
We need an official answer: wrong wiring, known bug on 26.5, or unsupported? AlertConfiguration.AlertSound.default works. AlertConfiguration.AlertSound.named("lifeloop_alarm_silent") schedules successfully (Stop/Snooze UI, no API error) but playback is always system default — never our bundled CAF. OFFICIAL API WE FOLLOW Documentation: AlertConfiguration.AlertSound.named(:) https://developer.apple.com/documentation/activitykit/alertconfiguration/alertsound/named(:) "The name of the sound file to use for the alert. Choose a file that's in your app's main bundle or the Library/Sounds folder of your app's data container." WWDC25 session 230 shows: let sound = AlertConfiguration.AlertSound.named("Chime") with the file in the main bundle. We use: AlertConfiguration.AlertSound.named("lifeloop_alarm_silent") Our Swift schedules with AlarmManager.AlarmConfiguration.alarm(..., sound: alertSound). REFERENCES WE ALREADY READ AlarmConfiguration overview: https://developer.apple.com/documentation/alarmkit/alarmmanager/alarmconfiguration Albert Pascual DTS reply (Feb 2026) on this thread pointed at nested alertConfiguration with sound AlarmKit FAQ: https://developer.apple.com/forums/thread/797158 Older forum reply (~2025): claimed .named("Glass Drum.caf") worked — not verified on 26.5 today On iOS 26.5: Bundle.main finds our file with AND without ".caf" in the lookup string; playback still system default OUR WIRING (please confirm correct or tell us what to change) We schedule fixed-time dose alarms with: AlarmManager.AlarmConfiguration.alarm( schedule: .fixed(fireDate), attributes: attributes, stopIntent: stopIntent, secondaryIntent: snoozeIntent, sound: alertSound) .default on this parameter works. .named("lifeloop_alarm_silent") does not — despite Bundle.main finding the file (proof below). Question: Is sound: on .alarm(...) correct for custom AlertSound.named, or must sound go in nested AlertConfiguration(title:body:sound:) as in the overview example? WHAT WE HEAR ON DEVICE sound = .default → loud system alarm (works) sound = .named("lifeloop_alarm_silent") → same loud system/default every time No API error — silent fallback to default PROOF 1 — FILE IN SHIPPED IPA $ find Payload -name "lifeloop_alarm_*.caf" Payload/LifeLoop.app/lifeloop_alarm_silent.caf PROOF 2 — RUNTIME ON DEVICE (2026-06-30, iOS 26.5) Bundle.main.url(forResource:withExtension:): FOUND Bundle.main.url(full filename in name): FOUND Path: .../LifeLoop.app/lifeloop_alarm_silent.caf All .caf in main bundle: lifeloop_alarm_silent.caf Library/Sounds: (none) Widget .appex .caf: (none) Native log at schedule: [alarmkit] build_config · soundModeRaw=silent alertSound=named:lifeloop_alarm_silent silentCafInBundle=true [alarmkit] schedule_ok · alarmID=FBDF2082-61F1-4C93-8B20-094A60EA8626 CAF: lifeloop_alarm_silent.caf — mono, 44100 Hz, 16-bit PCM, ~0.5 s QUESTIONS FOR DTS Main app bundle only, or must CAF also be in widget .appex? Must named(_:) include ".caf" or base name only? Bundle.main FOUND at schedule time but playback is default — known bug on 26.5? Please answer: (A) wrong wiring + correct recipe, (B) known bug + fix version, or (C) not supported — please document. Thank you. Same problem as tonny00 — custom CAF never plays, always the loud system/default alarm. App: LifeLoop (com.stujacks.lifeloop) on iOS 26.5 (physical device). https://developer.apple.com/forums/thread/814732
1
0
205
Jun ’26
Clarification on Screen Time API capabilities for per-child and per-device activity reports
Hello, I am developing a parental control app using FamilyControls, DeviceActivity, and DeviceActivityReport. My current setup is: The child device requests FamilyControls authorization with .child The parent device requests FamilyControls authorization with .individual The parent app displays reports through a DeviceActivityReportExtension The report filter uses users: .children and devices: .all I would like to clarify two questions: Can a third-party app use the Screen Time API to retrieve or display screen time activity per child or per child device from the parent app? For example: Child A's total screen time today Child A's iPhone screen time today Child A's iPad screen time today At the moment, I can only display an aggregated report using users: .children and devices: .all. I do not see a public API for selecting a specific child or a specific child device. Is this a current limitation of the public Screen Time API, or is there a recommended approach to implement this? Can the Screen Time API report activity data for family members aged 14-17? Specifically, if a family member is between 14 and 17 years old and their device has completed .child authorization, can the parent app still display their Screen Time data using DeviceActivityReport(users: .children)? Or are there restrictions related to Apple ID age, Family Sharing, or Screen Time permissions that prevent third-party apps from retrieving or displaying activity data for users in this age range? My goal is to understand what third-party apps can implement in a compliant way using the public APIs, without attempting to bypass any system limitations. Thank you.
0
0
191
Jun ’26
iOS 26.4 — How to return from main app to host app after a keyboard-extension dictation round-trip, without private APIs?
I'm building a custom keyboard extension that offers voice dictation. Because keyboard extensions are constrained (memory cap ~30–48 MB, restricted audio session access), I delegate recording to my container app: User in a host app (e.g., Safari) taps the mic in my keyboard extension. The keyboard calls extensionContext.open(URL("myapp://dictation")) to launch the container app. The container app records audio via AVAudioEngine + SFSpeechRecognizer, writes the final transcript to the App Group, and signals completion via a Darwin notification. 4. The user is expected to be returned to the original host app (Safari) automatically so they can keep typing. The problem (step 4): On iOS 26.4 I can no longer identify which app was the host. Every previously-known path returns nil for the keyboard extension's host: parent.value(forKey: "_hostBundleID") → returns the literal string parent.value(forKey: "_hostApplicationBundleIdentifier") → returns NSNull xpc_connection_copy_bundle_id on the underlying XPC connection (via PKService.defaultService.personalities[…]) → returns NULL NSXPCConnection.processBundleIdentifier on extensionContext._extensionHostProxy._connection → returns nil proc_pidpath(hostPID, …) → EPERM from the keyboard sandbox LSApplicationWorkspace.frontmostApplication → selector unavailable from the extension RBSProcessHandle.handleForIdentifier:error: → returns an RBSServiceErrorDomain error Without the host's bundle ID, the container app has no way to call LSApplicationWorkspace.openApplicationWithBundleID: (the technique that worked on iOS 25 and earlier). UIApplication.suspend() correctly sends the container to background, but iOS treats us as a "fresh launch" — it returns the user to the Home Screen instead of Safari, because the container app was launched by an extension, not directly by Safari. KeyboardKit's maintainer reached the same conclusion (issue #1014) and shipped 10.4 without the feature. My questions: Is there a public, App-Store-safe API in iOS 26+ for a custom keyboard extension to identify its host application, or for the container app (launched via the extension's openURL) to identify which app initially hosted the extension that opened it? UIOpenURLContext.options.sourceApplication reports the extension's own container, not the actual host. 2. Is there a public mechanism for "return to source app" when the container app was launched by an extension's openURL? Equivalent to the ← Source affordance iOS shows for normal inter-app openURL, but triggered programmatically by the launched app. 3. Some popular keyboards (e.g., 微信输入法 / WeChat Keyboard) still appear to round-trip through their container app on iOS 26.4 and return the user to the original host — including the iOS ← WeChat back affordance in the host's status bar afterward. What's the recommended approach to achieve this? If it requires a specific scene-activation flow, NSUserActivity pattern, or extension-context configuration, please point at the relevant docs. 4. If there is no public path today, is FB22247647 (or a related radar) the right place to track this? Should developers in this position migrate to in-extension audio capture (which has its own significant constraints in keyboard extensions)? I'd much rather not rely on private APIs. Concrete guidance — or even an acknowledgment of which direction Apple intends — would help thousands of custom-keyboard developers who currently have a degraded voice-input experience on iOS 26.4+. Tested on iPhone 12 Pro Max running iOS 26.4.2 (build 23E261), Xcode 26.x, Swift 5. Thanks!
3
0
909
Jun ’26
Identifying the host app from a custom keyboard on iOS 26.4+ (host bundle id is now nil)
I have a custom keyboard (UIInputViewController, Full Access). For a dictation feature it opens its containing app to record audio (the keyboard can't use the microphone) and then needs to return the user to the host app they were typing in. That requires knowing the host app. Through iOS 26.3 this worked, because the host bundle id was exposed on the keyboard's input-session connection. On iOS 26.4 / 26.5 it is now nil, and every route I have tried is blocked: UIInputViewController _hostApplicationBundleIdentifier -> nil _hostProcessIdentifier and the host audit token are available, but: RBSProcessHandle handleForAuditToken: / handleForIdentifier: -> "Client not entitled" SecTaskCopySigningIdentifier / SecTaskCopyValueForEntitlement -> nil (sandbox) proc_pidpath -> EPERM UIKeyboardImpl _remoteAppId / _remoteLocalizedAppName -> nil The keyboard arbiter client-change event fires in SpringBoard, not in the extension process However, at least one shipping keyboard still does this on iOS 26.5. I verified in device logs that Yandex Keyboard launches its container app with a URL containing the correct, current host bundle id, and it is live: it reported net.whatsapp.WhatsApp, then net.whatsapp.WhatsAppSMB when the host was WhatsApp Business. So the capability clearly still exists for some apps. Questions: Is there a supported API on iOS 26.4+ for a keyboard extension to identify its host app? If it requires an entitlement, can developers request it, and how? If there is no public path, is the intended approach the system "back to previous app" breadcrumb (manual) plus a containing-app round trip? I have also filed Feedback (FB#######). Thanks.
1
0
276
Jun ’26
iOS Universal Link opens app and then opens browser (Flutter + Universal Links) — only when using paths/params
Hi everyone, I’ve been stuck on an issue with iOS Universal Links for about a week and could really use some help. The problem When tapping a Universal Link on iOS, my Flutter app opens correctly (desired behavior) — but immediately afterward, Safari opens the same link in the browser. So both the app and the browser open. This only happens on iOS. On Android everything works as expected. What works If the link is simply the domain, like: https://mydomain.com …then the app opens without triggering the browser afterward. This is the correct behavior. What doesn’t work If the link includes a path or parameters, like: https://mydomain.com/path https://mydomain.com/path?param=value …then the app opens, and then the browser opens immediately after. What I’ve tried Verified my AASA file using Branch’s validator: https://branch.io/resources/aasa-validator/ → The AASA file is valid. Universal Links do open the correct screen inside the app — the issue is the unwanted second step (Safari opening). Behavior is consistent across different iOS devices. Extra details Using Flutter. Universal Links set up with the standard configuration (associatedDomains, AASA hosted at /.well-known/apple-app-site-association, etc.). Question Has anyone encountered this issue where Universal Links with paths/params open the app and then open Safari? What could cause iOS to trigger the browser fallback even when the AASA file is valid and the app handles the link correctly? Any insights, debugging tips, or known edge cases would be incredibly appreciated!
5
2
817
Jun ’26
Age assurance in Texas
Hello Apple Developer Support Team, We understand from the Declared Age Range documentation that, in some regulated regions, the system automatically provides the person’s age range and they can’t decline sharing it with the app. We have implemented the API as prescribed in the documentation. For certain users in Texas, the API returns: isEligibleForAgeFeatures == true declaredAgeRangeRequired == true However, in our testing we observe that these Texas users can still decline sharing their age range, either via the system prompt or later via Settings, which results in no age range being provided to the app. This behavior appears inconsistent with the documentation’s statement that, in regulated regions, the person “can’t decline” sharing their age range, and it also raises questions for us about how this aligns with the applicable legal requirements in Texas. Could you please clarify: Whether this behavior (Texas users being able to decline sharing their age range even when declaredAgeRangeRequired is true) is expected, and Under what exact conditions the “they can’t decline sharing” behavior is enforced for Texas accounts (for example, only for new Apple Accounts created in Texas after a certain date, or only for particular age categories)? Any guidance on how we should interpret isEligibleForAgeFeatures and declaredAgeRangeRequired in this scenario would be greatly appreciated. Thank you.
0
0
277
Jun ’26
Message Filter Extension: undocumented per-sender ILMessageFilterAction categorization state on iOS 26.5 — by design or bug?
Environment: iOS 26.5, Message Filter app extension (IdentityLookup framework), offline filtering. Setup My Message Filter Extension performs offline string matching on the message body and returns one of: ILMessageFilterAction.allow / .junk / .transaction / .promotion In the Messages app the filtering UI shows these folders: Messages (the main/default folder), Transactions, Promotions, Junk. .allow is expected to surface a message in the main Messages folder. The documented behavior (API docs + WWDC22 "Explore SMS message filters") only describes a static mapping from action → folder. On iOS 26.5 I'm seeing what looks like a stateful, per-sender behavior that I cannot find documented anywhere, and I can't tell whether it is intended or a bug. Test methodology All messages in every sequence are sent from the same single phone number. Before each Case, I fully clear the receive history for that number, so every sequence starts from a clean slate with no prior state for that sender. The notation shows how many conversations/entries appear in each folder after each step. Case A — first message = allow allow → Messages: 1 promotion → Messages: 2 (allow + promotion), Promotions: 1 junk → everything collapses into Junk; Messages & Promotions become empty every subsequent message lands in Junk regardless of the action I return Case B — first message = allow, then transaction allow → Messages: 1 transaction → Messages: 2 (allow + transaction), Transactions: 1 junk → everything collapses into Junk; Messages & Transactions empty every subsequent message lands in Junk regardless of returned action Case C — first message = transaction transaction → Messages: 1, Transactions: 1 ← also appears in Messages allow → Messages: 2, Transactions: 1 promotion → Messages: 3, Transactions: 1, Promotions: 1 junk → Messages: 4, Transactions: 1, Promotions: 1, Junk: 1 (NOTE: here junk does NOT collapse the thread, and there is no "sticky junk") Case D — first message = promotion promotion → Promotions: 1 only (does NOT appear in Messages) allow → Messages: 2 (the earlier promotion now also appears in Messages), Promotions: 1 junk → everything collapses into Junk (sticky, same as Case A/B) every subsequent message lands in Junk regardless of returned action My core question: are the following two behaviors by design, or are they bugs? (1) "Sticky junk" after allow-first / promotion-first. In Cases A, B and D, once .junk is returned the whole sender thread collapses into Junk, and from then on every message is forced into Junk regardless of the action my extension returns. Is this expected/by-design, or a bug? If by design: is it permanent, and what resets it — does the extension have any control, or is it purely user-driven (e.g. the user moving the thread out of Junk)? What concerns me is that the system appears to ignore my returned action entirely once this state is entered. (2) .transaction-first behaving differently from .allow-first. A sender whose first message is .transaction (Case C) behaves differently: the message also appears in the main Messages folder, and a later .junk does not collapse the thread (no sticky junk). Is this .transaction-first behavior expected/by-design, or a bug? If by design, what is the underlying rule that makes .transaction-first confer this state while .allow-first does not? Since the history is cleared before each test, this is determined purely by the first action returned. Additional clarifying questions Is any of this per-sender state behavior documented beyond the static action → folder mapping in the API docs / WWDC22 "Explore SMS message filters"? If so, where? More generally, what determines whether a categorized (.transaction / .promotion) message is also mirrored into the main Messages folder? Thanks — I'd like my extension's return values to produce predictable categorization for users, and right now this first-message-dependent behavior makes that hard to reason about.
0
1
272
Jun ’26
NSMenuItem.separator() appears as blank space in Finder Sync extension context menu
Hi, I’m developing a macOS Finder Sync extension and noticed that NSMenuItem.separator() does not appear to render as a standard separator line when used inside the menu returned from FIFinderSyncController. In a normal AppKit NSMenu, the separator renders as expected. However, when the same kind of menu is returned from the Finder Sync extension, the separator appears as a blank/full-height empty row rather than a thin dividing line. Example: override func menu(for menuKind: FIMenuKind) -> NSMenu { let menu = NSMenu(title: "") menu.addItem(NSMenuItem( title: "First Action", action: #selector(firstAction(_:)), keyEquivalent: "" )) menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem( title: "Second Action", action: #selector(secondAction(_:)), keyEquivalent: "" )) return menu } Expected result: The separator should render as a normal macOS menu separator line between the two menu items. Actual result: In Finder’s context menu, the separator is displayed as blank vertical space / an empty menu row. I understand that Finder Sync menus are rendered by Finder and may not support every NSMenuItem feature. However, NSMenuItem.separator() is a very standard way to visually group menu commands, so I wanted to ask: Is this a known limitation of Finder Sync extension menus? Is there a supported way to display a real separator line in Finder Sync context menus? Should this be filed as a Feedback Assistant issue against Finder Sync / AppKit? I’m trying to avoid fake separators such as disabled menu items with "────" as the title, since that does not feel native and may not behave well with different fonts, accessibility settings, or appearance modes. Thanks!
0
0
278
Jun ’26
UserDefaults.standard.integer(forKey: ) crashes the app with EXC_BAD_ACCESS (code=1, address=0x0)
With the 27 OSes using UserDefaults.standard.integer(forKey: ) can cause a crash with EXC_BAD_ACCESS (code=1, address=0x0) It has been seen on a Multiplatform app, up to now tested on iOS/iPadOS and visionOS 27 Beta 1. In our code we use UserDefaults.standard.integer(forKey: ) from a singleton called during the SwiftUI app init(), and we don't know yet if this is the only moment there is a crash as we can't go farther. The API should return 0 if it can't get a value. There is no reason the app should crash if the API conforms to its contract. Running the same code from Xcode on iOS 26 runs it without issue. FeedBack FB23310748
7
0
570
Jun ’26
Age ratings vs parental consent for 16+ apps
Hello, Quick clarification regarding age ratings: If a user is 17 years old and wants to download a 16+ app, is parental approval required? Or is parental consent only needed if the app’s rating does not match (or exceeds) the user’s actual age? Also, is this fully enforced by Apple, or is it up to developers how to implement these checks? Thanks!
0
0
250
Jun ’26
iOS 26 Phone Recents: CXHandle.generic no longer groups CallKit VoIP calls/history by handle value
Hello there, I am trying to clarify whether iOS 26 changed the expected Phone Recents behavior for CallKit calls reported with CXHandle.generic. On iOS 18 and earlier, CallKit calls reported with: CXHandle(type: .generic, value: <stable custom identifier>) were grouped and displayed in Phone Recents based on the stable handle value. The details/history screen for a Recents entry showed calls for that same handle value. On iOS 26, the same approach no longer appears to work the same way. Observed behavior on iOS 26 I tested multiple stable CXHandle.generic values. The Recents rows are created, but when opening the details/history screen for one Recents entry, the history shows all calls, not only calls for the selected generic handle value. I also tested other handle types: CXHandle(type: .emailAddress, value: <stable email-like identifier>) works as expected: Recents grouping and the details/history screen are isolated to that handle value. CXHandle(type: .phoneNumber, value: <phone number>) also works as expected for real phone-number-style identities: Recents grouping and the details/history screen are isolated to that phone number. CXHandle(type: .generic, value: <stable custom identifier>) does not work the same way on iOS 26: the details/history screen is not isolated to that generic handle value and instead shows all calls. Questions Is CXHandle.generic still intended to be a supported identity for Phone Recents grouping and the details/history screen on iOS 26? Given that .emailAddress and .phoneNumber handles appear to isolate history correctly, is .generic intentionally treated differently by the iOS 26 Phone app, or is this a regression? Did iOS 26 change Phone Recents/details matching so that CXHandle.generic values are no longer used as isolated per-caller identities? If this behavior is intentional, what handle type should be used for stable non-phone CallKit identities? Is using CXHandle(type: .emailAddress, value: "@example.invalid") an acceptable supported approach for stable non-phone identities, if the value is not a real user email address? Is there documentation describing the iOS 26 Phone Recents identity-matching behavior for CallKit calls? Minimal repro Configure a CXProvider with calls included in Recents. Report several CallKit calls using different stable generic handles, for example: CXHandle(type: .generic, value: "app-target-1") CXHandle(type: .generic, value: "app-target-2") End the calls. Open Phone Recents on iOS 26. Open the details/history screen for one of the Recents entries. Expected result: The details/history screen shows only calls for the selected generic handle value. Actual result: The details/history screen shows all calls. Could you clarify whether this is expected behavior on iOS 26, a regression, or an unsupported use of CXHandle.generic? Thank you.
1
0
339
Jun ’26
Potential iOS26 regression on AASA file not download on app install
Original discussion pre iOS 26 Our app uses Auth0 with HTTPS callback, we've found the issue where AASA file is not ready immediately when app is initially launched, which is the exact issue from the above link. The issue seems mostly fixed on later versions on iOS 18, however, we are seeing some indications of a regression on iOS 26. Here's some measurement over the last week. | Platform | iOS 18 | iOS 26 | |---------------|----------|--------| | Adoption rate | 55% | 45% | | Issue seen | 1 | 5 | | Recover? | Yes | No | This only 1 iOS 18 instance was able to recover after 1 second after the first try, however, all iOS 26 instances were not able to recover in couple tens of seconds and less than 1 minute, the user eventually gave up. Is there a way to force app to update AASA file? Are there some iOS setting (like using a VPN) that could potentially downgrade the AASA fetch? Related Auth0 discussion: https://community.auth0.com/t/ios-application-not- recognizing-auth0-associated-domain/134847/27
18
1
2.2k
Jun ’26
VoIP PKPushKit notifications not delivered when powerd assertion policy 3 hits before apsd completes APNs reconnection
We are seeing a reproducible scenario on iOS 26 where incoming VoIP push notifications are never delivered when the device has been idle and screen-locked for 30+ minutes. The same failure was observed simultaneously on WhatsApp, and Microsoft Teams and our app as well, on the same device during one incident, confirming this is a platform-level issue and not specific to our implementation. We have captured full system logs across three separate incidents. Below are the exact log sequences. Incident — All VoIP apps fail simultaneously (Our app, WhatsApp, Teams) Device: iPhone 17 Pro · iOS: 18.x · Network: 5G NSA (kNRNSA) The device had been idle with the screen locked for approximately 31 minutes. An LTE cell handover caused apsd to begin an APNs reconnection. powerd entered policy 3 before apsd reached channel-flow viable, defuncting the app. 17:45:59.562 symptomsd New RRC 0 when previous 1 from pdp_ip0 ↑ Radio drops to RRC_Idle. Device has been idle since 17:14:56 (31 min). 17:46:01.206 CommCenter #I Mapping the registration state to kRegisteredHome ↑ LTE cell handover triggers RRC reconnect. 17:46:01.330 apsd [C138 IPv4#b71cac13:5223 ready parent-flow (satisfied (Path is satisfied), interface: pdp_ip0[lte], scoped, ipv4, ipv6, dns, expensive, uses cell, LQM: good)] event: path:satisfied_change @594.391s ↑ APNs path re-satisfied. Reconnection begins. channel-flow viable NOT yet reached — TLS handshake still in progress. 17:48:08.057 apsd Powerd has requested assertion activity update ↑ Warning: powerd about to change policy. ── 2 minutes 40 seconds after APNs reconnect started ── 17:48:41.248 powerd Sending com.apple.powerd.assertionpolicy 3 17:48:41.250 apsd Update assertion policy 3 17:48:41.250 powerd Activity changes from 0x1 to 0x0. UseActiveState:0 17:48:41.250 powerd hidActive:0 displayOff:1 assertionActivityValid:0 ↑ Screen off, device locked. OS enters restricted idle. apsd restricted. APNs reconnection abandoned. 17:48:42.669 kernel necp_process_defunct_list: necp_update_client abort nexus error (2) for pid 1518 Comera ↑ Kernel terminates Comera's network stack via NECP. No API available to prevent this. WhatsApp and Teams remain suspended — no DEFUNCT, but apsd in policy 3 means no push delivery for them either. ── Dead zone: VoIP pushes for all 3 apps undeliverable ── 17:50:04.028 powerd Process CommCenter.104 Created SystemIsActive "com.apple.ipTelephony.sipIncoming.cell" ↑ Incoming cellular PSTN call forces system wake. 17:50:04.494 powerd Sending com.apple.powerd.assertionpolicy 0 17:50:04.598 apsd Update assertion policy 0 ↑ Full wake. Queued VoIP pushes from Comera, WhatsApp, and Teams are delivered simultaneously. Gap between channel-flow viable needed and actual delivery: 4 minutes 3 seconds. Recovery trigger: external cellular call from carrier — not any app action. Working case (same test, different conditions) Device: iPhone 17 Pro · iOS: 26.5.1 · Screen unlocked, no hotspot 19:2x:xx apsd policy state {downgradeWhenLocked: NO, isSystemLocked: NO, isConnectedOnUltraConstrainedInterface: NO} ↑ Device unlocked. No policy 3. Comera NOT defuncted. Push delivered. Call rings normally. Our implementation PKPushRegistry is held strongly and re-registered on every applicationWillEnterForeground reportNewIncomingCall(with:update:completion:) is called synchronously within pushRegistry(_:didReceiveIncomingPushWith:) VoIP background mode entitlement is present App has com.apple.developer.pushkit.voip entitlement Questions Is there any entitlement or API to prevent NECP from defuncting a process holding an active PKPushRegistry? The VoIP push entitlement exists for exactly this background delivery scenario. Is pushDisallowed being applied to apps with VoIP push entitlements when InternetSharingActive == 1 intentional? Should VoIP entitlements exempt an app from the Internet Sharing Policy gate in dasd? Is there a documented way to know when apsd has fully completed APNs reconnection (i.e. channel-flow viable) so a server can time push retries more accurately within a call validity window? What is the recommended apns-expiration value for VoIP pushes to survive brief APNs reconnection windows without exceeding a 60-second call validity period? Full log stream captures available for all incidents.
7
0
533
Jun ’26
CSSearchableItem init(appEntity:) crashes on iOS 18.0+
Hello, In my app, I want to create a CSSearchableItem using the initialiser that accepts an appEntity so I can update the item expirationDate when indexing. This initialiser is marked as iOS 18.0+ but as soon as I launch my app, it crashes. I filed a feedback: FB23270394 Can you help? Thank you Axel dyld[62169]: Symbol not found: _$s10AppIntents13IndexedEntityPAAE15hideInSpotlightSbvg Referenced from: <150E43FA-D9F4-3DF3-88C1-86E3DA3B272B> /Users/axel/Library/Developer/CoreSimulator/Devices/2C645A0F-45E5-429E-82EE-0C71D83407E3/data/Containers/Bundle/Application/18F00389-5CE8-49A2-883A-CDA38DDB03C4/Skipper.app/Skipper.debug.dylib Expected in: <F5744EDB-79CF-333C-A49A-8E9C5C3ACD10> /Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/AppIntents.framework/AppIntents Symbol not found: _$s10AppIntents13IndexedEntityPAAE15hideInSpotlightSbvg Referenced from: <150E43FA-D9F4-3DF3-88C1-86E3DA3B272B> /Users/axel/Library/Developer/CoreSimulator/Devices/2C645A0F-45E5-429E-82EE-0C71D83407E3/data/Containers/Bundle/Application/18F00389-5CE8-49A2-883A-CDA38DDB03C4/Skipper.app/Skipper.debug.dylib Expected in: <F5744EDB-79CF-333C-A49A-8E9C5C3ACD10> /Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/AppIntents.framework/AppIntents dyld config: DYLD_ROOT_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot DYLD_LIBRARY_PATH=/Users/axel/Library/Developer/Xcode/DerivedData/Skipper-gayhthkwqznqqkeoqazrmncvolcq/Build/Products/Debug-iphonesimulator DYLD_INSERT_LIBRARIES=/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libLogRedirect.dylib:/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libViewDebuggerSupport.dylib DYLD_FRAMEWORK_PATH=/Users/axel/Library/Developer/Xcode/DerivedData/Skipper-gayhthkwqznqqkeoqazrmncvolcq/Build/Products/Debug-iphonesimulator:/Users/axel/Library/Developer/Xcode/DerivedData/Skipper-gayhthkwqznqqkeoqazrmncvolcq/Build/Products/Debug-iphonesimulator/PackageFrameworks DYLD_FALLBACK_FRAMEWORK_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks DYLD_FALLBACK_LIBRARY_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/usr/lib Debug session ended with code 9: killed
1
0
270
Jun ’26
WeatherKit JWT token generation fails with WDSJWTAuthenticator Code=2 despite correct entitlement
I enabled the WeatherKit capability on my App ID (com.saimcan.darkweather, Team 6SWSD6V4ZC) about 12 hours ago. The entitlement is embedded in the binary and the provisioning profile authorizes it, but every request fails at the JWT generation step. Error from the logs: Error Domain=WeatherDaemon.WDSJWTAuthenticatorServiceListener.Errors Code=2 "(null)" Relevant log excerpt (iOS 26.4 Simulator, same result on a physical device): [AuthService] Calling process is 3rd party process and has the correct entitlement ... accepting the connection [AuthService] Received proxy request for generating a jwt token. url=https://weatherkit.apple.com [WeatherDataService] Starting to generate JWT token request. bundleIdentifier=com.saimcan.darkweather [AuthService] Signed successfully [WeatherDataService] Make new JWT token request. requestIdentifier=... [AuthService] Failed to generate jwt token ... Code=2 What I have verified: Active Apple Developer Program membership (renewed through April 2027) All agreements accepted WeatherKit capability enabled on the App ID codesign -d --entitlements confirms com.apple.developer.weatherkit in the built binary embedded.mobileprovision also includes com.apple.developer.weatherkit App Group (group.com.saimcan.darkweather.shared) correctly bound to both the app and widget App IDs Since "Signed successfully" is logged, the device-side auth plumbing is working. The rejection appears to be server-side. Could someone from the WeatherKit team check whether JWT minting is enabled for this Team ID / Bundle ID? Team ID: 6SWSD6V4ZC Bundle ID: com.saimcan.darkweather
5
1
653
Jun ’26
Declared Age Range API – Clarification on checkEligibility() behavior (eligibility vs region)
Hello, While reviewing the latest FAQ and documentation for the Declared Age Range API, we have some questions regarding the behavior of checkEligibility()—specifically how it relates to user eligibility, geographic jurisdiction, and regulatory requirements. Context From the documentation, it appears that checkEligibility() indicates whether a user is eligible to share their declared age range. However, it is unclear whether this eligibility also incorporates jurisdiction-specific requirements (e.g., certain U.S. states with age assurance regulations). We would appreciate clarification on the following points: Eligibility vs Region: Does checkEligibility() return true based on the user’s eligibility to share age information only, or does it also depend on the user’s geographic region (e.g., specific U.S. states like Texas)? Region-Specific Laws (Texas Example): In scenarios where certain jurisdictions (such as Texas) require age assurance features, while other U.S. states may not, how does checkEligibility() behave? User Consent vs Regulatory Requirement: If a user denies age sharing, but they are located in a region where age-related regulatory features are mandated, how does checkEligibility() behave? Will it return false because the user denied consent? Or will it still return true due to regulatory requirements overriding user preference? Source of Region Determination: Does the Declared Age Range API internally determine the user’s applicable region (e.g., based on IP address, Apple ID region, or device settings) when evaluating checkEligibility()? Should developers independently determine jurisdiction (e.g., using IP-based geolocation) to apply region-specific rules, or is checkEligibility() intended to fully abstract both eligibility and jurisdiction requirements?
Replies
1
Boosts
1
Views
424
Activity
Jul ’26
DeclaredAgeRange API not triggering in regulated regions (Brazil, Utah) — Is it functioning in production?
Hi, We've implemented age assurance logic in our app using the DeclaredAgeRange framework to comply with regulations in Brazil (Digital ECA, effective March 17, 2026) and Utah (App Store Accountability Act, effective May 6, 2026). Our implementation calls AgeRangeService.shared.isEligibleForAgeFeatures on app launch to determine whether the current user is subject to age assurance requirements, and proceeds to call requestAgeRange(ageGates:) accordingly. However, after monitoring in production since the Brazil enforcement date, we've consistently observed isEligibleForAgeFeatures returning false for users in regulated regions, with no age range data being returned. What we'd like to clarify: Is isEligibleForAgeFeatures currently returning true for users in Brazil in production (not sandbox)? For Utah — given that HB 498 pushed the developer compliance deadline to May 6, 2027, will isEligibleForAgeFeatures reflect the original May 6, 2026 activation date or the revised 2027 date? Is there a known rollout schedule or gradual activation plan for these regions that would explain why the flag remains false even after the legal enforcement dates have passed? We've seen similar reports from other developers on these forums, so it seems this may be a widespread issue rather than an implementation problem on our end. Any official guidance on the current status of the API in regulated regions would be greatly appreciated. Thanks.
Replies
1
Boosts
1
Views
683
Activity
Jul ’26
Shallow Depth Entitlement and Underwater Auto-Launch: App Not Appearing in "When Submerged"
I've a question for you maybe you can help me. My watchOS app has: WKSupportsAutomaticDepthLaunch = true WKBackgroundModes = underwater-depth com.apple.developer.submerged-shallow-depth-and-pressure = true entitlement present in codesign and embedded provisioning profile The app uses the shallow depth entitlement, but it does not appear in: Settings → General → Auto-Launch → When Submerged. Is the shallow depth entitlement sufficient for appearing in the system underwater auto-launch app list, or is the full submerged depth entitlement required?
Replies
0
Boosts
0
Views
242
Activity
Jul ’26
PushToTalk session sometimes returns silence data after activation
Hello! Thank you for bringing the new iPhone experience with the PushToTalk framework. I have a working walkie talkie app based on the PushToTalk framework. Everything works fine except for an intermittent bug that I face from time to time on different devices with different iOS versions, from iOS 18 to iOS 26.2 Beta. Sometimes the app goes into a state where the AVAudioInputNode input node tap returns buffers with a constant size that contain only silence. Leaving and rejoining a channel helps, but relaunching or reinstalling (from Xcode) the app does not. Rebooting the device or deleting and reinstalling the app also helps. I do not activate the audio session in my app. I only configure it on launch using setCategory(.playAndRecord, options: [.defaultToSpeaker, .allowBluetooth]) So the flow is: channelManager?.requestBeginTransmitting(channelUUID: globalChannelUUID) func channelManager( _ channelManager: PTChannelManager, channelUUID: UUID, didBeginTransmittingFrom source: PTChannelTransmitRequestSource ) func channelManager( _ channelManager: PTChannelManager, didActivate audioSession: AVAudioSession ) { /// ... installTapAndStart() } private func installTapAndStart() { let inputNode = audioEngine.inputNode let hardwareFormat = inputNode.outputFormat(forBus: 0) guard let targetFormat = AVAudioFormat( commonFormat: .pcmFormatFloat32, sampleRate: configuration.audioSampleRate, channels: configuration.audioChannelsCount, interleaved: true ) else { handleError(RecorderError.invalidAudioFormat) return } let converter = AVAudioConverter(from: hardwareFormat, to: targetFormat)! print("[QUICOpusRecorder]: installTap") inputNode.installTap(onBus: 0, bufferSize: tapBufferSize, format: hardwareFormat) { [weak self] buffer, _ in guard let self else { return } // Here I handle audio data and sometimes get silence } //... do { audioEngine.prepare() try audioEngine.start() } catch { print(" ⚠️ Audio engine start error: \(error)") handleError(error) } } Moreover, if the app is in the foreground and PushToTalk gets stuck in this “silence bug”, I can avoid relying on the PushToTalk flow and simulate audio session activation manually in code. In this case I do not request a transmission and do not use any PushToTalk related code, and the app captures audio data perfectly. Once I leave the channel and rejoin it again, the issue is fixed and I start to receive non silent buffers of varying size, as expected. It works for a while. It can work fine for a day or more, communicating without launching the app, or with the app in the foreground. But it can also go into the “silence” state 30 minutes after working normally. I have no clue why this happens. The only thing I notice is that when the app is in this “stuck silence bug” state, iOS does not play its “chirp” system sound when audio recording starts. P.S. Channel descriptor restoration code: extension PushToTalkEngine: PTChannelRestorationDelegate { public func channelDescriptor(restoredChannelUUID channelUUID: UUID) -> PTChannelDescriptor { print("☀️ \(#function) channelUUID: \(channelUUID)") Task { @MainActor in // Here I fetch more detailed channel data asynchronously do { await initChannelManagerIfNeeded(channelUUID: channelUUID) let channelDescriptor = currentChannelDescriptor() lastChannelDescriptorName = channelDescriptor.name try await channelManager?.setChannelDescriptor( channelDescriptor, channelUUID: channelUUID ) } catch { handleError(error) } } return PTChannelDescriptor(name: "Loading...", image: nil) } } private func initChannelManagerIfNeeded(channelUUID: UUID? = nil) async { guard let channelUUID = channelUUID ?? currentUser?.globalChannelUUID else { print("❌ No global channel uuid found") return } do { guard channelManager == nil else { try await channelManager?.setTransmissionMode(.halfDuplex, channelUUID: channelUUID) return } channelManager = try await PTChannelManager.channelManager( delegate: self, restorationDelegate: self ) try await channelManager?.setTransmissionMode(.halfDuplex, channelUUID: channelUUID) } catch { handleError(error) } }
Replies
3
Boosts
0
Views
1k
Activity
Jul ’26
Understanding Crash Reporter Extension lifecycle and debugging behavior
Hi! I have a few questions about the lifecycle and capabilities of the Crash Reporter Extension. Besides using the corpsePort to inspect the crashed process through Mach APIs, is it safe/supported/recommended for the extension to access files in a shared App Group container? Are there any caveats or exceptions we should be aware of, for example around memory-mapped files, file coordination, or filesystem access after the host app has crashed? Shall we use some particular APIs for this kind of shared resource or not? While debugging the extension, I noticed that when I trigger a crash in the app I am debugging, LLDB does not stop inside the extension (it also ends up stopping the debugging session). However, I can observe that the extension does run, because it writes data into a shared App Group directory related to the crash. Is this expected behavior? Is there a recommended way to debug the Crash Reporter Extension reliably (with lldb, or other way)? More generally, I would like to better understand the extension lifecycle: When exactly does the extension start running? How long can it live after the app crashes? Is there a time limit for operating on the corpse process? Is the extension subject to resource limits similar to other app extensions, such as memory, disk, CPU, watchdog, or jetsam constraints? If the Crash Reporter Extension itself crashes, how can we detect that? Would those crashes appear in Xcode Organizer, or is there another recommended way to observe them? Any clarification around the supported lifecycle, debugging model, and resource limits would be very useful.
Replies
4
Boosts
1
Views
591
Activity
Jun ’26
AlertConfiguration.AlertSound.named plays system default despite CAF in main bundle (AlarmKit, iOS 26.5)
We need an official answer: wrong wiring, known bug on 26.5, or unsupported? AlertConfiguration.AlertSound.default works. AlertConfiguration.AlertSound.named("lifeloop_alarm_silent") schedules successfully (Stop/Snooze UI, no API error) but playback is always system default — never our bundled CAF. OFFICIAL API WE FOLLOW Documentation: AlertConfiguration.AlertSound.named(:) https://developer.apple.com/documentation/activitykit/alertconfiguration/alertsound/named(:) "The name of the sound file to use for the alert. Choose a file that's in your app's main bundle or the Library/Sounds folder of your app's data container." WWDC25 session 230 shows: let sound = AlertConfiguration.AlertSound.named("Chime") with the file in the main bundle. We use: AlertConfiguration.AlertSound.named("lifeloop_alarm_silent") Our Swift schedules with AlarmManager.AlarmConfiguration.alarm(..., sound: alertSound). REFERENCES WE ALREADY READ AlarmConfiguration overview: https://developer.apple.com/documentation/alarmkit/alarmmanager/alarmconfiguration Albert Pascual DTS reply (Feb 2026) on this thread pointed at nested alertConfiguration with sound AlarmKit FAQ: https://developer.apple.com/forums/thread/797158 Older forum reply (~2025): claimed .named("Glass Drum.caf") worked — not verified on 26.5 today On iOS 26.5: Bundle.main finds our file with AND without ".caf" in the lookup string; playback still system default OUR WIRING (please confirm correct or tell us what to change) We schedule fixed-time dose alarms with: AlarmManager.AlarmConfiguration.alarm( schedule: .fixed(fireDate), attributes: attributes, stopIntent: stopIntent, secondaryIntent: snoozeIntent, sound: alertSound) .default on this parameter works. .named("lifeloop_alarm_silent") does not — despite Bundle.main finding the file (proof below). Question: Is sound: on .alarm(...) correct for custom AlertSound.named, or must sound go in nested AlertConfiguration(title:body:sound:) as in the overview example? WHAT WE HEAR ON DEVICE sound = .default → loud system alarm (works) sound = .named("lifeloop_alarm_silent") → same loud system/default every time No API error — silent fallback to default PROOF 1 — FILE IN SHIPPED IPA $ find Payload -name "lifeloop_alarm_*.caf" Payload/LifeLoop.app/lifeloop_alarm_silent.caf PROOF 2 — RUNTIME ON DEVICE (2026-06-30, iOS 26.5) Bundle.main.url(forResource:withExtension:): FOUND Bundle.main.url(full filename in name): FOUND Path: .../LifeLoop.app/lifeloop_alarm_silent.caf All .caf in main bundle: lifeloop_alarm_silent.caf Library/Sounds: (none) Widget .appex .caf: (none) Native log at schedule: [alarmkit] build_config · soundModeRaw=silent alertSound=named:lifeloop_alarm_silent silentCafInBundle=true [alarmkit] schedule_ok · alarmID=FBDF2082-61F1-4C93-8B20-094A60EA8626 CAF: lifeloop_alarm_silent.caf — mono, 44100 Hz, 16-bit PCM, ~0.5 s QUESTIONS FOR DTS Main app bundle only, or must CAF also be in widget .appex? Must named(_:) include ".caf" or base name only? Bundle.main FOUND at schedule time but playback is default — known bug on 26.5? Please answer: (A) wrong wiring + correct recipe, (B) known bug + fix version, or (C) not supported — please document. Thank you. Same problem as tonny00 — custom CAF never plays, always the loud system/default alarm. App: LifeLoop (com.stujacks.lifeloop) on iOS 26.5 (physical device). https://developer.apple.com/forums/thread/814732
Replies
1
Boosts
0
Views
205
Activity
Jun ’26
Clarification on Screen Time API capabilities for per-child and per-device activity reports
Hello, I am developing a parental control app using FamilyControls, DeviceActivity, and DeviceActivityReport. My current setup is: The child device requests FamilyControls authorization with .child The parent device requests FamilyControls authorization with .individual The parent app displays reports through a DeviceActivityReportExtension The report filter uses users: .children and devices: .all I would like to clarify two questions: Can a third-party app use the Screen Time API to retrieve or display screen time activity per child or per child device from the parent app? For example: Child A's total screen time today Child A's iPhone screen time today Child A's iPad screen time today At the moment, I can only display an aggregated report using users: .children and devices: .all. I do not see a public API for selecting a specific child or a specific child device. Is this a current limitation of the public Screen Time API, or is there a recommended approach to implement this? Can the Screen Time API report activity data for family members aged 14-17? Specifically, if a family member is between 14 and 17 years old and their device has completed .child authorization, can the parent app still display their Screen Time data using DeviceActivityReport(users: .children)? Or are there restrictions related to Apple ID age, Family Sharing, or Screen Time permissions that prevent third-party apps from retrieving or displaying activity data for users in this age range? My goal is to understand what third-party apps can implement in a compliant way using the public APIs, without attempting to bypass any system limitations. Thank you.
Replies
0
Boosts
0
Views
191
Activity
Jun ’26
iOS 26.4 — How to return from main app to host app after a keyboard-extension dictation round-trip, without private APIs?
I'm building a custom keyboard extension that offers voice dictation. Because keyboard extensions are constrained (memory cap ~30–48 MB, restricted audio session access), I delegate recording to my container app: User in a host app (e.g., Safari) taps the mic in my keyboard extension. The keyboard calls extensionContext.open(URL("myapp://dictation")) to launch the container app. The container app records audio via AVAudioEngine + SFSpeechRecognizer, writes the final transcript to the App Group, and signals completion via a Darwin notification. 4. The user is expected to be returned to the original host app (Safari) automatically so they can keep typing. The problem (step 4): On iOS 26.4 I can no longer identify which app was the host. Every previously-known path returns nil for the keyboard extension's host: parent.value(forKey: "_hostBundleID") → returns the literal string parent.value(forKey: "_hostApplicationBundleIdentifier") → returns NSNull xpc_connection_copy_bundle_id on the underlying XPC connection (via PKService.defaultService.personalities[…]) → returns NULL NSXPCConnection.processBundleIdentifier on extensionContext._extensionHostProxy._connection → returns nil proc_pidpath(hostPID, …) → EPERM from the keyboard sandbox LSApplicationWorkspace.frontmostApplication → selector unavailable from the extension RBSProcessHandle.handleForIdentifier:error: → returns an RBSServiceErrorDomain error Without the host's bundle ID, the container app has no way to call LSApplicationWorkspace.openApplicationWithBundleID: (the technique that worked on iOS 25 and earlier). UIApplication.suspend() correctly sends the container to background, but iOS treats us as a "fresh launch" — it returns the user to the Home Screen instead of Safari, because the container app was launched by an extension, not directly by Safari. KeyboardKit's maintainer reached the same conclusion (issue #1014) and shipped 10.4 without the feature. My questions: Is there a public, App-Store-safe API in iOS 26+ for a custom keyboard extension to identify its host application, or for the container app (launched via the extension's openURL) to identify which app initially hosted the extension that opened it? UIOpenURLContext.options.sourceApplication reports the extension's own container, not the actual host. 2. Is there a public mechanism for "return to source app" when the container app was launched by an extension's openURL? Equivalent to the ← Source affordance iOS shows for normal inter-app openURL, but triggered programmatically by the launched app. 3. Some popular keyboards (e.g., 微信输入法 / WeChat Keyboard) still appear to round-trip through their container app on iOS 26.4 and return the user to the original host — including the iOS ← WeChat back affordance in the host's status bar afterward. What's the recommended approach to achieve this? If it requires a specific scene-activation flow, NSUserActivity pattern, or extension-context configuration, please point at the relevant docs. 4. If there is no public path today, is FB22247647 (or a related radar) the right place to track this? Should developers in this position migrate to in-extension audio capture (which has its own significant constraints in keyboard extensions)? I'd much rather not rely on private APIs. Concrete guidance — or even an acknowledgment of which direction Apple intends — would help thousands of custom-keyboard developers who currently have a degraded voice-input experience on iOS 26.4+. Tested on iPhone 12 Pro Max running iOS 26.4.2 (build 23E261), Xcode 26.x, Swift 5. Thanks!
Replies
3
Boosts
0
Views
909
Activity
Jun ’26
Identifying the host app from a custom keyboard on iOS 26.4+ (host bundle id is now nil)
I have a custom keyboard (UIInputViewController, Full Access). For a dictation feature it opens its containing app to record audio (the keyboard can't use the microphone) and then needs to return the user to the host app they were typing in. That requires knowing the host app. Through iOS 26.3 this worked, because the host bundle id was exposed on the keyboard's input-session connection. On iOS 26.4 / 26.5 it is now nil, and every route I have tried is blocked: UIInputViewController _hostApplicationBundleIdentifier -> nil _hostProcessIdentifier and the host audit token are available, but: RBSProcessHandle handleForAuditToken: / handleForIdentifier: -> "Client not entitled" SecTaskCopySigningIdentifier / SecTaskCopyValueForEntitlement -> nil (sandbox) proc_pidpath -> EPERM UIKeyboardImpl _remoteAppId / _remoteLocalizedAppName -> nil The keyboard arbiter client-change event fires in SpringBoard, not in the extension process However, at least one shipping keyboard still does this on iOS 26.5. I verified in device logs that Yandex Keyboard launches its container app with a URL containing the correct, current host bundle id, and it is live: it reported net.whatsapp.WhatsApp, then net.whatsapp.WhatsAppSMB when the host was WhatsApp Business. So the capability clearly still exists for some apps. Questions: Is there a supported API on iOS 26.4+ for a keyboard extension to identify its host app? If it requires an entitlement, can developers request it, and how? If there is no public path, is the intended approach the system "back to previous app" breadcrumb (manual) plus a containing-app round trip? I have also filed Feedback (FB#######). Thanks.
Replies
1
Boosts
0
Views
276
Activity
Jun ’26
iOS Universal Link opens app and then opens browser (Flutter + Universal Links) — only when using paths/params
Hi everyone, I’ve been stuck on an issue with iOS Universal Links for about a week and could really use some help. The problem When tapping a Universal Link on iOS, my Flutter app opens correctly (desired behavior) — but immediately afterward, Safari opens the same link in the browser. So both the app and the browser open. This only happens on iOS. On Android everything works as expected. What works If the link is simply the domain, like: https://mydomain.com …then the app opens without triggering the browser afterward. This is the correct behavior. What doesn’t work If the link includes a path or parameters, like: https://mydomain.com/path https://mydomain.com/path?param=value …then the app opens, and then the browser opens immediately after. What I’ve tried Verified my AASA file using Branch’s validator: https://branch.io/resources/aasa-validator/ → The AASA file is valid. Universal Links do open the correct screen inside the app — the issue is the unwanted second step (Safari opening). Behavior is consistent across different iOS devices. Extra details Using Flutter. Universal Links set up with the standard configuration (associatedDomains, AASA hosted at /.well-known/apple-app-site-association, etc.). Question Has anyone encountered this issue where Universal Links with paths/params open the app and then open Safari? What could cause iOS to trigger the browser fallback even when the AASA file is valid and the app handles the link correctly? Any insights, debugging tips, or known edge cases would be incredibly appreciated!
Replies
5
Boosts
2
Views
817
Activity
Jun ’26
Age assurance in Texas
Hello Apple Developer Support Team, We understand from the Declared Age Range documentation that, in some regulated regions, the system automatically provides the person’s age range and they can’t decline sharing it with the app. We have implemented the API as prescribed in the documentation. For certain users in Texas, the API returns: isEligibleForAgeFeatures == true declaredAgeRangeRequired == true However, in our testing we observe that these Texas users can still decline sharing their age range, either via the system prompt or later via Settings, which results in no age range being provided to the app. This behavior appears inconsistent with the documentation’s statement that, in regulated regions, the person “can’t decline” sharing their age range, and it also raises questions for us about how this aligns with the applicable legal requirements in Texas. Could you please clarify: Whether this behavior (Texas users being able to decline sharing their age range even when declaredAgeRangeRequired is true) is expected, and Under what exact conditions the “they can’t decline sharing” behavior is enforced for Texas accounts (for example, only for new Apple Accounts created in Texas after a certain date, or only for particular age categories)? Any guidance on how we should interpret isEligibleForAgeFeatures and declaredAgeRangeRequired in this scenario would be greatly appreciated. Thank you.
Replies
0
Boosts
0
Views
277
Activity
Jun ’26
Message Filter Extension: undocumented per-sender ILMessageFilterAction categorization state on iOS 26.5 — by design or bug?
Environment: iOS 26.5, Message Filter app extension (IdentityLookup framework), offline filtering. Setup My Message Filter Extension performs offline string matching on the message body and returns one of: ILMessageFilterAction.allow / .junk / .transaction / .promotion In the Messages app the filtering UI shows these folders: Messages (the main/default folder), Transactions, Promotions, Junk. .allow is expected to surface a message in the main Messages folder. The documented behavior (API docs + WWDC22 "Explore SMS message filters") only describes a static mapping from action → folder. On iOS 26.5 I'm seeing what looks like a stateful, per-sender behavior that I cannot find documented anywhere, and I can't tell whether it is intended or a bug. Test methodology All messages in every sequence are sent from the same single phone number. Before each Case, I fully clear the receive history for that number, so every sequence starts from a clean slate with no prior state for that sender. The notation shows how many conversations/entries appear in each folder after each step. Case A — first message = allow allow → Messages: 1 promotion → Messages: 2 (allow + promotion), Promotions: 1 junk → everything collapses into Junk; Messages & Promotions become empty every subsequent message lands in Junk regardless of the action I return Case B — first message = allow, then transaction allow → Messages: 1 transaction → Messages: 2 (allow + transaction), Transactions: 1 junk → everything collapses into Junk; Messages & Transactions empty every subsequent message lands in Junk regardless of returned action Case C — first message = transaction transaction → Messages: 1, Transactions: 1 ← also appears in Messages allow → Messages: 2, Transactions: 1 promotion → Messages: 3, Transactions: 1, Promotions: 1 junk → Messages: 4, Transactions: 1, Promotions: 1, Junk: 1 (NOTE: here junk does NOT collapse the thread, and there is no "sticky junk") Case D — first message = promotion promotion → Promotions: 1 only (does NOT appear in Messages) allow → Messages: 2 (the earlier promotion now also appears in Messages), Promotions: 1 junk → everything collapses into Junk (sticky, same as Case A/B) every subsequent message lands in Junk regardless of returned action My core question: are the following two behaviors by design, or are they bugs? (1) "Sticky junk" after allow-first / promotion-first. In Cases A, B and D, once .junk is returned the whole sender thread collapses into Junk, and from then on every message is forced into Junk regardless of the action my extension returns. Is this expected/by-design, or a bug? If by design: is it permanent, and what resets it — does the extension have any control, or is it purely user-driven (e.g. the user moving the thread out of Junk)? What concerns me is that the system appears to ignore my returned action entirely once this state is entered. (2) .transaction-first behaving differently from .allow-first. A sender whose first message is .transaction (Case C) behaves differently: the message also appears in the main Messages folder, and a later .junk does not collapse the thread (no sticky junk). Is this .transaction-first behavior expected/by-design, or a bug? If by design, what is the underlying rule that makes .transaction-first confer this state while .allow-first does not? Since the history is cleared before each test, this is determined purely by the first action returned. Additional clarifying questions Is any of this per-sender state behavior documented beyond the static action → folder mapping in the API docs / WWDC22 "Explore SMS message filters"? If so, where? More generally, what determines whether a categorized (.transaction / .promotion) message is also mirrored into the main Messages folder? Thanks — I'd like my extension's return values to produce predictable categorization for users, and right now this first-message-dependent behavior makes that hard to reason about.
Replies
0
Boosts
1
Views
272
Activity
Jun ’26
NSMenuItem.separator() appears as blank space in Finder Sync extension context menu
Hi, I’m developing a macOS Finder Sync extension and noticed that NSMenuItem.separator() does not appear to render as a standard separator line when used inside the menu returned from FIFinderSyncController. In a normal AppKit NSMenu, the separator renders as expected. However, when the same kind of menu is returned from the Finder Sync extension, the separator appears as a blank/full-height empty row rather than a thin dividing line. Example: override func menu(for menuKind: FIMenuKind) -> NSMenu { let menu = NSMenu(title: "") menu.addItem(NSMenuItem( title: "First Action", action: #selector(firstAction(_:)), keyEquivalent: "" )) menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem( title: "Second Action", action: #selector(secondAction(_:)), keyEquivalent: "" )) return menu } Expected result: The separator should render as a normal macOS menu separator line between the two menu items. Actual result: In Finder’s context menu, the separator is displayed as blank vertical space / an empty menu row. I understand that Finder Sync menus are rendered by Finder and may not support every NSMenuItem feature. However, NSMenuItem.separator() is a very standard way to visually group menu commands, so I wanted to ask: Is this a known limitation of Finder Sync extension menus? Is there a supported way to display a real separator line in Finder Sync context menus? Should this be filed as a Feedback Assistant issue against Finder Sync / AppKit? I’m trying to avoid fake separators such as disabled menu items with "────" as the title, since that does not feel native and may not behave well with different fonts, accessibility settings, or appearance modes. Thanks!
Replies
0
Boosts
0
Views
278
Activity
Jun ’26
UserDefaults.standard.integer(forKey: ) crashes the app with EXC_BAD_ACCESS (code=1, address=0x0)
With the 27 OSes using UserDefaults.standard.integer(forKey: ) can cause a crash with EXC_BAD_ACCESS (code=1, address=0x0) It has been seen on a Multiplatform app, up to now tested on iOS/iPadOS and visionOS 27 Beta 1. In our code we use UserDefaults.standard.integer(forKey: ) from a singleton called during the SwiftUI app init(), and we don't know yet if this is the only moment there is a crash as we can't go farther. The API should return 0 if it can't get a value. There is no reason the app should crash if the API conforms to its contract. Running the same code from Xcode on iOS 26 runs it without issue. FeedBack FB23310748
Replies
7
Boosts
0
Views
570
Activity
Jun ’26
Age ratings vs parental consent for 16+ apps
Hello, Quick clarification regarding age ratings: If a user is 17 years old and wants to download a 16+ app, is parental approval required? Or is parental consent only needed if the app’s rating does not match (or exceeds) the user’s actual age? Also, is this fully enforced by Apple, or is it up to developers how to implement these checks? Thanks!
Replies
0
Boosts
0
Views
250
Activity
Jun ’26
iOS 26 Phone Recents: CXHandle.generic no longer groups CallKit VoIP calls/history by handle value
Hello there, I am trying to clarify whether iOS 26 changed the expected Phone Recents behavior for CallKit calls reported with CXHandle.generic. On iOS 18 and earlier, CallKit calls reported with: CXHandle(type: .generic, value: <stable custom identifier>) were grouped and displayed in Phone Recents based on the stable handle value. The details/history screen for a Recents entry showed calls for that same handle value. On iOS 26, the same approach no longer appears to work the same way. Observed behavior on iOS 26 I tested multiple stable CXHandle.generic values. The Recents rows are created, but when opening the details/history screen for one Recents entry, the history shows all calls, not only calls for the selected generic handle value. I also tested other handle types: CXHandle(type: .emailAddress, value: <stable email-like identifier>) works as expected: Recents grouping and the details/history screen are isolated to that handle value. CXHandle(type: .phoneNumber, value: <phone number>) also works as expected for real phone-number-style identities: Recents grouping and the details/history screen are isolated to that phone number. CXHandle(type: .generic, value: <stable custom identifier>) does not work the same way on iOS 26: the details/history screen is not isolated to that generic handle value and instead shows all calls. Questions Is CXHandle.generic still intended to be a supported identity for Phone Recents grouping and the details/history screen on iOS 26? Given that .emailAddress and .phoneNumber handles appear to isolate history correctly, is .generic intentionally treated differently by the iOS 26 Phone app, or is this a regression? Did iOS 26 change Phone Recents/details matching so that CXHandle.generic values are no longer used as isolated per-caller identities? If this behavior is intentional, what handle type should be used for stable non-phone CallKit identities? Is using CXHandle(type: .emailAddress, value: "@example.invalid") an acceptable supported approach for stable non-phone identities, if the value is not a real user email address? Is there documentation describing the iOS 26 Phone Recents identity-matching behavior for CallKit calls? Minimal repro Configure a CXProvider with calls included in Recents. Report several CallKit calls using different stable generic handles, for example: CXHandle(type: .generic, value: "app-target-1") CXHandle(type: .generic, value: "app-target-2") End the calls. Open Phone Recents on iOS 26. Open the details/history screen for one of the Recents entries. Expected result: The details/history screen shows only calls for the selected generic handle value. Actual result: The details/history screen shows all calls. Could you clarify whether this is expected behavior on iOS 26, a regression, or an unsupported use of CXHandle.generic? Thank you.
Replies
1
Boosts
0
Views
339
Activity
Jun ’26
Potential iOS26 regression on AASA file not download on app install
Original discussion pre iOS 26 Our app uses Auth0 with HTTPS callback, we've found the issue where AASA file is not ready immediately when app is initially launched, which is the exact issue from the above link. The issue seems mostly fixed on later versions on iOS 18, however, we are seeing some indications of a regression on iOS 26. Here's some measurement over the last week. | Platform | iOS 18 | iOS 26 | |---------------|----------|--------| | Adoption rate | 55% | 45% | | Issue seen | 1 | 5 | | Recover? | Yes | No | This only 1 iOS 18 instance was able to recover after 1 second after the first try, however, all iOS 26 instances were not able to recover in couple tens of seconds and less than 1 minute, the user eventually gave up. Is there a way to force app to update AASA file? Are there some iOS setting (like using a VPN) that could potentially downgrade the AASA fetch? Related Auth0 discussion: https://community.auth0.com/t/ios-application-not- recognizing-auth0-associated-domain/134847/27
Replies
18
Boosts
1
Views
2.2k
Activity
Jun ’26
VoIP PKPushKit notifications not delivered when powerd assertion policy 3 hits before apsd completes APNs reconnection
We are seeing a reproducible scenario on iOS 26 where incoming VoIP push notifications are never delivered when the device has been idle and screen-locked for 30+ minutes. The same failure was observed simultaneously on WhatsApp, and Microsoft Teams and our app as well, on the same device during one incident, confirming this is a platform-level issue and not specific to our implementation. We have captured full system logs across three separate incidents. Below are the exact log sequences. Incident — All VoIP apps fail simultaneously (Our app, WhatsApp, Teams) Device: iPhone 17 Pro · iOS: 18.x · Network: 5G NSA (kNRNSA) The device had been idle with the screen locked for approximately 31 minutes. An LTE cell handover caused apsd to begin an APNs reconnection. powerd entered policy 3 before apsd reached channel-flow viable, defuncting the app. 17:45:59.562 symptomsd New RRC 0 when previous 1 from pdp_ip0 ↑ Radio drops to RRC_Idle. Device has been idle since 17:14:56 (31 min). 17:46:01.206 CommCenter #I Mapping the registration state to kRegisteredHome ↑ LTE cell handover triggers RRC reconnect. 17:46:01.330 apsd [C138 IPv4#b71cac13:5223 ready parent-flow (satisfied (Path is satisfied), interface: pdp_ip0[lte], scoped, ipv4, ipv6, dns, expensive, uses cell, LQM: good)] event: path:satisfied_change @594.391s ↑ APNs path re-satisfied. Reconnection begins. channel-flow viable NOT yet reached — TLS handshake still in progress. 17:48:08.057 apsd Powerd has requested assertion activity update ↑ Warning: powerd about to change policy. ── 2 minutes 40 seconds after APNs reconnect started ── 17:48:41.248 powerd Sending com.apple.powerd.assertionpolicy 3 17:48:41.250 apsd Update assertion policy 3 17:48:41.250 powerd Activity changes from 0x1 to 0x0. UseActiveState:0 17:48:41.250 powerd hidActive:0 displayOff:1 assertionActivityValid:0 ↑ Screen off, device locked. OS enters restricted idle. apsd restricted. APNs reconnection abandoned. 17:48:42.669 kernel necp_process_defunct_list: necp_update_client abort nexus error (2) for pid 1518 Comera ↑ Kernel terminates Comera's network stack via NECP. No API available to prevent this. WhatsApp and Teams remain suspended — no DEFUNCT, but apsd in policy 3 means no push delivery for them either. ── Dead zone: VoIP pushes for all 3 apps undeliverable ── 17:50:04.028 powerd Process CommCenter.104 Created SystemIsActive "com.apple.ipTelephony.sipIncoming.cell" ↑ Incoming cellular PSTN call forces system wake. 17:50:04.494 powerd Sending com.apple.powerd.assertionpolicy 0 17:50:04.598 apsd Update assertion policy 0 ↑ Full wake. Queued VoIP pushes from Comera, WhatsApp, and Teams are delivered simultaneously. Gap between channel-flow viable needed and actual delivery: 4 minutes 3 seconds. Recovery trigger: external cellular call from carrier — not any app action. Working case (same test, different conditions) Device: iPhone 17 Pro · iOS: 26.5.1 · Screen unlocked, no hotspot 19:2x:xx apsd policy state {downgradeWhenLocked: NO, isSystemLocked: NO, isConnectedOnUltraConstrainedInterface: NO} ↑ Device unlocked. No policy 3. Comera NOT defuncted. Push delivered. Call rings normally. Our implementation PKPushRegistry is held strongly and re-registered on every applicationWillEnterForeground reportNewIncomingCall(with:update:completion:) is called synchronously within pushRegistry(_:didReceiveIncomingPushWith:) VoIP background mode entitlement is present App has com.apple.developer.pushkit.voip entitlement Questions Is there any entitlement or API to prevent NECP from defuncting a process holding an active PKPushRegistry? The VoIP push entitlement exists for exactly this background delivery scenario. Is pushDisallowed being applied to apps with VoIP push entitlements when InternetSharingActive == 1 intentional? Should VoIP entitlements exempt an app from the Internet Sharing Policy gate in dasd? Is there a documented way to know when apsd has fully completed APNs reconnection (i.e. channel-flow viable) so a server can time push retries more accurately within a call validity window? What is the recommended apns-expiration value for VoIP pushes to survive brief APNs reconnection windows without exceeding a 60-second call validity period? Full log stream captures available for all incidents.
Replies
7
Boosts
0
Views
533
Activity
Jun ’26
CSSearchableItem init(appEntity:) crashes on iOS 18.0+
Hello, In my app, I want to create a CSSearchableItem using the initialiser that accepts an appEntity so I can update the item expirationDate when indexing. This initialiser is marked as iOS 18.0+ but as soon as I launch my app, it crashes. I filed a feedback: FB23270394 Can you help? Thank you Axel dyld[62169]: Symbol not found: _$s10AppIntents13IndexedEntityPAAE15hideInSpotlightSbvg Referenced from: <150E43FA-D9F4-3DF3-88C1-86E3DA3B272B> /Users/axel/Library/Developer/CoreSimulator/Devices/2C645A0F-45E5-429E-82EE-0C71D83407E3/data/Containers/Bundle/Application/18F00389-5CE8-49A2-883A-CDA38DDB03C4/Skipper.app/Skipper.debug.dylib Expected in: <F5744EDB-79CF-333C-A49A-8E9C5C3ACD10> /Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/AppIntents.framework/AppIntents Symbol not found: _$s10AppIntents13IndexedEntityPAAE15hideInSpotlightSbvg Referenced from: <150E43FA-D9F4-3DF3-88C1-86E3DA3B272B> /Users/axel/Library/Developer/CoreSimulator/Devices/2C645A0F-45E5-429E-82EE-0C71D83407E3/data/Containers/Bundle/Application/18F00389-5CE8-49A2-883A-CDA38DDB03C4/Skipper.app/Skipper.debug.dylib Expected in: <F5744EDB-79CF-333C-A49A-8E9C5C3ACD10> /Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/AppIntents.framework/AppIntents dyld config: DYLD_ROOT_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot DYLD_LIBRARY_PATH=/Users/axel/Library/Developer/Xcode/DerivedData/Skipper-gayhthkwqznqqkeoqazrmncvolcq/Build/Products/Debug-iphonesimulator DYLD_INSERT_LIBRARIES=/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libLogRedirect.dylib:/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libMainThreadChecker.dylib:/usr/lib/libRPAC.dylib:/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libViewDebuggerSupport.dylib DYLD_FRAMEWORK_PATH=/Users/axel/Library/Developer/Xcode/DerivedData/Skipper-gayhthkwqznqqkeoqazrmncvolcq/Build/Products/Debug-iphonesimulator:/Users/axel/Library/Developer/Xcode/DerivedData/Skipper-gayhthkwqznqqkeoqazrmncvolcq/Build/Products/Debug-iphonesimulator/PackageFrameworks DYLD_FALLBACK_FRAMEWORK_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks DYLD_FALLBACK_LIBRARY_PATH=/Library/Developer/CoreSimulator/Volumes/iOS_22A3351/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.0.simruntime/Contents/Resources/RuntimeRoot/usr/lib Debug session ended with code 9: killed
Replies
1
Boosts
0
Views
270
Activity
Jun ’26
WeatherKit JWT token generation fails with WDSJWTAuthenticator Code=2 despite correct entitlement
I enabled the WeatherKit capability on my App ID (com.saimcan.darkweather, Team 6SWSD6V4ZC) about 12 hours ago. The entitlement is embedded in the binary and the provisioning profile authorizes it, but every request fails at the JWT generation step. Error from the logs: Error Domain=WeatherDaemon.WDSJWTAuthenticatorServiceListener.Errors Code=2 "(null)" Relevant log excerpt (iOS 26.4 Simulator, same result on a physical device): [AuthService] Calling process is 3rd party process and has the correct entitlement ... accepting the connection [AuthService] Received proxy request for generating a jwt token. url=https://weatherkit.apple.com [WeatherDataService] Starting to generate JWT token request. bundleIdentifier=com.saimcan.darkweather [AuthService] Signed successfully [WeatherDataService] Make new JWT token request. requestIdentifier=... [AuthService] Failed to generate jwt token ... Code=2 What I have verified: Active Apple Developer Program membership (renewed through April 2027) All agreements accepted WeatherKit capability enabled on the App ID codesign -d --entitlements confirms com.apple.developer.weatherkit in the built binary embedded.mobileprovision also includes com.apple.developer.weatherkit App Group (group.com.saimcan.darkweather.shared) correctly bound to both the app and widget App IDs Since "Signed successfully" is logged, the device-side auth plumbing is working. The rejection appears to be server-side. Could someone from the WeatherKit team check whether JWT minting is enabled for this Team ID / Bundle ID? Team ID: 6SWSD6V4ZC Bundle ID: com.saimcan.darkweather
Replies
5
Boosts
1
Views
653
Activity
Jun ’26