Posts under App & System Services topic

Post

Replies

Boosts

Views

Activity

Accuracy of IBI Values Measured by Apple Watch
I am currently developing an app that measures HRV to estimate stress levels. To align the values more closely with those from Galaxy devices, I decided not to use the heartRateVariabilitySDNN value provided by HealthKit. Instead, I extracted individual interbeat intervals (IBI) using the HKHeartBeatSeries data. Can I obtain accurate IBI data using this method? If not, I would like to know how I can retrieve more precise data. Any insights or suggestions would be greatly appreciated. Here is a sample code I tried. @Observable class HealthKitManager: ObservableObject { let healthStore = HKHealthStore() var ibiValues: [Double] = [] var isAuthorized = false func requestAuthorization() { let types = Set([ HKSeriesType.heartbeat(), HKQuantityType.quantityType(forIdentifier: .heartRateVariabilitySDNN)!, ]) healthStore.requestAuthorization(toShare: nil, read: types) { success, error in DispatchQueue.main.async { self.isAuthorized = success if success { self.fetchIBIData() } } } } func fetchIBIData() { var timePoints: [TimeInterval] = [] var absoluteStartTime: Date? let dateFormatter = DateFormatter() dateFormatter.timeZone = TimeZone(identifier: "Asia/Seoul") dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS" var calendar = Calendar.current calendar.timeZone = TimeZone(identifier: "Asia/Seoul") ?? .current var components = DateComponents() components.year = 2025 components.month = 4 components.day = 3 components.hour = 15 components.minute = 52 components.second = 0 let startTime = calendar.date(from: components)! components.hour = 16 components.minute = 0 let endTime = calendar.date(from: components)! let predicate = HKQuery.predicateForSamples(withStart: startTime, end: endTime, options: .strictStartDate) let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false) let query = HKSampleQuery(sampleType: HKSeriesType.heartbeat(), predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: [sortDescriptor]) { (_, samples, _) in if let sample = samples?.first as? HKHeartbeatSeriesSample { absoluteStartTime = sample.startDate let startDateKST = dateFormatter.string(from: sample.startDate) let endDateKST = dateFormatter.string(from: sample.endDate) print("series start(KST):\(startDateKST)\tend(KST):\(endDateKST)") let seriesQuery = HKHeartbeatSeriesQuery(heartbeatSeries: sample) { query, timeSinceSeriesStart, precededByGap, done, error in if !precededByGap { timePoints.append(timeSinceSeriesStart) } if done { for i in 1..<timePoints.count { let ibi = (timePoints[i] - timePoints[i-1]) * 1000 // Convert to milliseconds // Calculate absolute time for current beat if let startTime = absoluteStartTime { let beatTime = startTime.addingTimeInterval(timePoints[i]) let beatTimeString = dateFormatter.string(from: beatTime) print("IBI: \(String(format: "%.2f", ibi)) ms at \(beatTimeString)") } self.ibiValues.append(ibi) } } } self.healthStore.execute(seriesQuery) } else { print("No samples found for the specified time range") } } self.healthStore.execute(query) } }
1
0
115
Apr ’25
Detection of file eviction
I want to implement quota feature to my file provider extension. I am able to keep track of materialized files total size. (Content download and edit operations) However I cannot detect file eviction operation (User right click to file and select "Remove Download"). Is there anyway to detect this action Or any suggestion to keep track of materialized files total size?
2
0
193
Apr ’25
Guidance on Continuous Location & Direction Updates to watchOS App Without Screen Dimming
Dear Apple Developer Support, I am reaching out for guidance on implementing continuous directional and location updates in a watchOS app designed as part of a mapping/navigation solution. Current Scenario: We send continuous location and direction updates from our iOS app to the watchOS companion app. When viewing directions on the Apple Watch, the screen dims after a short period, and the live data stops updating consistently, even though the user is actively looking at the screen. This negatively impacts the usability of real-time navigation on watchOS. Our Objective: Prevent screen dimming (or extend screen-on time) while the user is viewing navigation directions. Ensure reliable, continuous data updates on the watch screen during active navigation sessions. Request: We would appreciate your guidance on: The recommended method to keep the watchOS screen active while displaying real-time navigation data. Proper use of APIs such as WKExtendedRuntimeSession, WorkoutSession, or any other mechanism suitable for this use case. Any best practices or App Store review considerations for apps that require extended screen time and continuous updates. How such use cases were traditionally handled on watchOS and what has or hasn’t worked. We want to ensure we're implementing this in a battery-efficient, user-respectful, and Apple-compliant manner. Thank you for your assistance and guidance.
1
0
100
Apr ’25
UNEXPECTED_CANCEL_AFTER_completeMerchantValidation
Hi, We are trying to make payment from ecomm merchant. The last request during process is { "sessionData": { "epochTimestamp": "1741082241", "expiresAt": "1741092241", "merchantSessionIdentifier": "SSH88312C485D_7E0DD10173", "nonce": "3f6dc197", "merchantIdentifier": "5F9BC6BAF8", "domainName": "libertybank.ge", "displayName": "Apple Pay Purchase", "signature": "3080060000", "operationalAnalyticsIdentifier": "Apple Pay Purchase:5F9BC6BAF8", "retries": 0, "pspId": "5F9BC6BAF8" } } which is successfully validated applePaySession.completeMerchantValidation(data.sessionData) After this, the "oncancel" handler is triggered in applePay. Please help us to understand what is wrong. Please note the domain where the applepay button is located is at txpg.libertypay.ge Which is successfully verified.
1
0
106
Apr ’25
Issues with Siri Shortcuts: Confirmation Prompt, Inconsistent Behavior
Hello Apple Developer Community, I’m working on integrating Siri into my React Native app using native iOS code and bridging to React Native. I’ve followed the necessary steps to set up Siri support, including: Adding the Siri capability. Adding Siri usage descriptions in Info.plist. Using AppIntent and AppShortcutsProvider to define shortcuts. However, I’m facing the following issues: Siri Prompts for Confirmation When a user says a phrase, Siri asks, "Turn on 'MyApp' shortcuts with Siri?" instead of directly recognizing the phrase. Is this expected behavior? If so, how can I reduce friction for users and make the experience more seamless? Inconsistent Behavior for Existing Users For users updating to a version with Siri support: When the app is closed, Siri says, "MyApp hasn't added support for that with Siri." When the app is open, Siri prompts, "Turn on shortcut for MyApp?" and rest all working fine Why does Siri not recognize the shortcut when the app is closed, even though the shortcut is defined in AppShortcutsProvider? How can I ensure that Siri recognizes the shortcut regardless of whether the app is open or closed? Other than using AppIntent and AppShortcutsProvider should i try Donating shortcuts(will that helps for updated user case). Please help me on this
8
1
633
Apr ’25
WidgetKit And Picture rotation
I'm developing a widget with WidgetKit, and I'm having a problem: I need to click on an image, and when I click it triggers a network request, the image automatically rotates clockwise, and when the network ends, the image automatically stops rotating. How to do that? My current idea is to click on the image and await the call to the network request. Should Toggle be used for the control corresponding to the picture? Because Toggle has two states. Then there is how to do image rotation, did not find support API.
1
0
129
Apr ’25
can bluetooth peripheral device maintain connection when app is killed?
Is there a way for the bluetooth peripheral device to remain connected to iOS even after the app which was used to pair with it has been swipe killed by the user? I have - enabled Background Modes (Uses Bluetooth LE Accessory) given all the relevant permissions (Background refresh) implemented state preservation and restoration. properly handled Connection Events with proper options (CBConnectPeripheralOptionNotifyOnConnectionKey and CBConnectPeripheralOptionNotifyOnDisconnectionKey) e.g Fitbit shows as connected in bluetooth settings even after the app has been swipe killed by the user.
1
1
131
Apr ’25
Issues with Opening iOS Settings from App
Hi there! We are working on our SkyElectric App which is being developed in Flutter framework, where we need user to connect with the Wifi of the the inverter. We are trying to direct user to WiFi Settings page of the iOS in general settings where all the available WiFi Networks are listed but unfortunately user is being directed to App's Settings page. We are using package of app_settings and launcher. I've read that Apple changed a policy in 2019 where it restricts Apps to navigate to OS pages. Question: Could you please verify if I APPLE allows us to access the General Settings or WiFi Settings through clicking a button in our App name "Open WiFi Settings", If not then Why?
2
0
91
Apr ’25
how to register listener to `NWConnectionGroup` for QUIC
I am trying to make http3 client with Network.framework on Apple platforms. Codes that implement NWConnectionGroup.start with NWListener don't always work with warning below. I assume NWConnectionGroup.newConnectionHandler or NWListener.newConnectionHandler will be called to start connection from the server if it works. nw_protocol_instance_add_new_flow [C1.1.1:2] No listener registered, cannot accept new flow quic_stream_add_new_flow [C1.1.1:2] [-fde1594b83caa9b7] failed to create new stream for received stream id 3 so I tried: create the NWListener -> not work check whether NWConnectionGroup has a member to register or not NWListener -> not work (it doesn't have). use NWConnection instead of NWConnectionGroup -> not work Is my understanding correct? How should I do to set or associate listener with NWConnection/Group for newConnectionHandler is called and to delete wanings? What is the best practice in the case? Sample codes are below. Thanks in advance. // http3 needs unidirectional stream by the server and client. // listener private let _listener: NWListener let option: NWProtocolQUIC.Options = .init(alpn:["h3"]) let param: NWParameters = .init(quic: option) _listener = try! .init(using: param) _listener.stateUpdateHandler = { state in print("listener state: \(state)") } _listener.newConnectionHandler = { newConnection in print("new connection added") } _listener.serviceRegistrationUpdateHandler = { registrationState in print("connection registrationstate") } // create connection private let _group: NWConnectionGroup let options: NWProtocolQUIC.Options = .init(alpn: ["h3"]) options.direction = .unidirectional options.isDatagram = false options.maxDatagramFrameSize = 65535 sec_protocol_options_set_verify_block(options.securityProtocolOptions, {(_: sec_protocol_metadata_t, _: sec_trust_t, completion: @escaping sec_protocol_verify_complete_t) in print("cert completion.") completion(true) }, .global()) let params: NWParameters = .init(quic: options) let group: NWMultiplexGroup = .init( to: .hostPort(host: NWEndpoint.Host("google.com"), port: NWEndpoint.Port(String(443))!)) _group = .init(with: group, using: params) _group.setReceiveHandler {message,content,isComplete in print("receive: \(message)") } _group.newConnectionHandler = {newConnection in print("newConnectionHandler: \(newConnection.state)") } _group.stateUpdateHandler = { state in print("state: \(state)") } _group.start(queue: .global()) _listener.start(queue: .global()) if let conn = _group.extract() { let data: Data = .init() let _ = _group.reinsert(connection: conn) conn.send(content: data, completion: .idempotent) }
4
0
223
Apr ’25
How to implement normal loading of web content when I intercept all request header information using the Swizzling method
I am developing a web application, I hope to be able to intercept all requests in the loaded web page, match the network request I want to specifically intercept the network request and then obtain the request header information (not the user's personal privacy data interception), if the use is the method of injection, the request header information is incomplete, such as the more important "content-type" field in the request header, so I try to use Swizzling method to intercept all http and https requests, and I can now intercept all the request information. But there is still a problem with my project, when loading x.com, logging in, appearing white screen after the successful landing, and not loading to the page after the successful landing, I don't know where the reason is。 Below is my core code implementation fragment. import WebKit // MARK: - WebViewController class WebViewController: UIViewController { fileprivate var webView: WKWebView! private var schemeHandler: WWKProxyWKURLSchemeHandler! override func viewDidLoad() { super.viewDidLoad() Self.initSwizzling setupWebView() loadInitialContent() } private func setupWebView() { let config = WKWebViewConfiguration() schemeHandler = WWKProxyWKURLSchemeHandler() config.setURLSchemeHandler(self.schemeHandler, forURLScheme: "https") config.setURLSchemeHandler(self.schemeHandler, forURLScheme: "http") webView = WKWebView(frame: view.bounds, configuration: config) webView.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.addSubview(webView) } private func loadInitialContent() { if let url = URL(string: "https://x.com") { let request = URLRequest(url: url,cachePolicy:.reloadIgnoringLocalCacheData,timeoutInterval: 15) webView.load(request) } } func reloadWebView() { webView?.reloadFromOrigin() } } class WWKProxyWKURLSchemeHandler: NSObject, WKURLSchemeHandler { private let lock = NSLock() private var activeTasks = [ObjectIdentifier: URLSessionDataTask]() func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) { lock.lock() defer { lock.unlock() } let taskID = ObjectIdentifier(urlSchemeTask) guard !activeTasks.keys.contains(taskID) else { print("⚠️ Task already started: \(urlSchemeTask.request.url?.absoluteString ?? "")") return } print("Intercepted URL---:",urlSchemeTask.request.url?.absoluteString ?? "") print("All requests intercepted----:",urlSchemeTask.request.allHTTPHeaderFields) let request = urlSchemeTask.request let dataTask = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in guard let self = self else { return } self.lock.lock() let isActive = self.activeTasks[taskID] != nil self.lock.unlock() guard isActive else { print("🌀 Task already cancelled: \(urlSchemeTask.request.url?.absoluteString ?? "")") return } // Make sure it only handles once guard self.activeTasks.keys.contains(taskID) else { return } self.activeTasks.removeValue(forKey: taskID) DispatchQueue.main.async { if let error = error { urlSchemeTask.didFailWithError(error) print("🔴 Task failed: \(urlSchemeTask.request.url?.absoluteString ?? "") - \(error.localizedDescription)") return } guard let response = response, let data = data else { urlSchemeTask.didFailWithError(URLError(.unknown)) print("🔴 Invalid response: \(urlSchemeTask.request.url?.absoluteString ?? "")") return } urlSchemeTask.didReceive(response) urlSchemeTask.didReceive(data) urlSchemeTask.didFinish() print("🟢 Task completed: \(urlSchemeTask.request.url?.absoluteString ?? "")") } } self.activeTasks[taskID] = dataTask dataTask.resume() } func webView(_ webView: WKWebView, stop task: WKURLSchemeTask) {} private func finishTask(taskID: ObjectIdentifier ,task: WKURLSchemeTask, response: URLResponse?, data: Data?, error: Error?) { lock.lock() defer { lock.unlock() } guard activeTasks.keys.contains(taskID) else { return } activeTasks.removeValue(forKey: taskID) DispatchQueue.main.async { if let error = error { task.didFailWithError(error) print("🔴 Task failed: \(task.request.url?.absoluteString ?? "") - \(error.localizedDescription)")return} guard let response = response, let data = data else { task.didFailWithError(URLError(.unknown)) print("🔴 Invalid response: \(task.request.url?.absoluteString ?? "")") return } task.didReceive(response) task.didReceive(data) task.didFinish() print("🟢 Task completed: \(task.request.url?.absoluteString ?? "")") } } } extension WKWebView { @objc dynamic class func qm_handlesURLScheme(_ urlScheme: String) -> Bool { if urlScheme == "https" || urlScheme == "http" {return false} return self.qm_handlesURLScheme(urlScheme) } // Exchange of execution methods static func setupSwizzling() { let originalSelector = #selector(handlesURLScheme(_:)) let swizzledSelector = #selector(qm_handlesURLScheme(_:)) // Implemented by Runtime Get Method guard let originalMethod = class_getClassMethod(WKWebView.self, originalSelector), let swizzledMethod = class_getClassMethod(WKWebView.self, swizzledSelector) else { return } // Implementation of Exchange Methods method_exchangeImplementations(originalMethod, swizzledMethod) } } extension WebViewController { private static let initSwizzling: Void = { DispatchQueue.once(token: "com.webview.swizzling") { WKWebView.setupSwizzling() } }() } // GCD Once extension DispatchQueue { private static var tokens = Set<String>() class func once(token: String, block: () -> Void) { objc_sync_enter(self) defer { objc_sync_exit(self) } guard !tokens.contains(token) else { return } tokens.insert(token) block() } } extension WebViewController: WKNavigationDelegate { func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { decisionHandler(.allow) } }
1
0
105
Apr ’25
On-demand rules
I've implemented a custom system extension VPN for macOS using Packet Tunnel Provider. The VPN is configured with on-demand, and a rule to always connect whenever there's traffic: onDemandRules = [NEOnDemandRuleConnect()] As expected, if the VPN isn't active, all traffic gets blocked until it is ready. Not expected: In the following scenario, there is some 'traffic leak': Use only WiFi (not wired cable) Connect the VPN Disable the WiFi and wait for the VPN to disconnect Enable the WiFi Some packets are routed outside the VPN, and aren't being blocked Some moments after, all traffic will be blocked, and the VPN will start the 'connecting' process. Is the above scenario a 'known' issue? Can it be a race condition in the OS, where some packets can be sent after the network is brought back before the VPN process starts? Is there any way to fix this problem? P.S: I'm not using flags such as 'capture all network'
3
1
203
Apr ’25
Working with Input/Output stream with Swift 6 and concurrency framework
Hello, I am developing an application which is communicating with external device using BLE and L2CAP. I wonder what are the best practices of using Input & Output streams that are established with L2CAP connection when working with Swift 6 concurrency model. I've been trying to find some examples and hints for some time now but unfortunately there isn't much available. One useful thread I've found is: https://aninterestingwebsite.com/forums/thread/756281 but it does not offer much insight into using eg. actor model with streams. I wonder if something has changed in this regards? Also, are there any plans to migrate eg. CoreBluetooth stack to new swift 6 concurrency ?
2
0
170
Apr ’25
Not Receiving Incoming VoIP Push Notifications on iOS 18.4 (React Native App)
Hi Apple Dev Team, We have a React Native application that includes call functionality using PushKit and VoIP notifications. We are using APNS to send the VoIP notifications, and everything has been working smoothly on iOS versions up to 18.3.1. However, after updating to iOS 18.4, we are no longer receiving incoming VoIP push notifications on the device. There have been no code changes related to our PushKit or notification logic — the exact same build continues to work correctly on devices running iOS 18.3.1 and earlier. We're trying to understand if anything has changed in iOS 18.4 that affects VoIP push delivery or registration behavior. Would appreciate any guidance, and happy to share code snippets or configuration if needed. Thanks in advance!
1
1
175
Apr ’25
Push payload is not present on notification tap
I am checking if the user taps on the firebase push notification and get the payload. override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo os_log("notification tapped %{public}@", log: OSLog.push, type: .info, userInfo) handleNotificationPayload(userInfo as! [String: AnyObject]) setFlutterLinkClickedVariable() } My use case is in app terminated state when push notification is tapped, get the link from payload and navigate to corresponding screen based on the link. This is working when there is only one push notification. When there are multiple push notifications with different links in the payload, only the first notification I tap works. Rest of the notifications just launches the app and does not navigate because the link is not set. I am getting the link from the payload and invoking flutter code which sets the link in the user defaults (shared preferences) and when the app launches in the home screen it checks for this variable and navigates accordingly. func handleNotificationPayload(_ payload: [String: AnyObject]) { if let link = payload["link"] as? String { setFlutterLinkVariable(link) } } override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { os_log("app did receive remote notification %{public}@", log: OSLog.push, type: .info, userInfo) handleNotificationPayload(userInfo as! [String : AnyObject]) completionHandler(.newData) } Currently when there is only one push notification it works because the link is set from the above method. The click delegate is not calling. I did set the delegate in application(:didFinishLaunchingWithOptions). UNUserNotificationCenter.current().delegate = self application.registerForRemoteNotifications() How to solve this issue? Thanks.
2
0
794
Apr ’25
How can you tick between live activities?
I have been watching the following moment from wwdc (Design dynamic Live Activities): https://aninterestingwebsite.com/videos/play/wwdc2023/10194/?time=728 It suggest that you should 'tick' between multiple live activities of your app: When you want to show multiple sessions for your app going on at once, consider ticking between the display of them to continue to give users an eye on everything that’s going on. How can I tick between them? More specifically how can I do that when my app is in the background?
1
1
252
Apr ’25
Background Push Notifications for Emergency App Delayed Despite Critical Alert Entitlement
I’m using Appnotic from my server to send notifications for an emergency service, where it is critical that notifications are delivered immediately. My payload looks like this: "aps": { "alert": "Test alert", "sound": { "critical": 1, "name": "sound.wav", "volume": 0.5 }, "content-available": 1, "category": "alert" }, "topic": "com.fireservicerota.FSR-Primary-Alerting", "custom_payload": { "id": "11", "type": "alert", "incident_id": 23434, "incident_response_id": 2652343, "expiration_time": "2024-06-06T16:59:05+01:00" } } I already have the critical alert entitlement and background processing enabled. Everything seems fine when debugging, but I’m experiencing issues: • Some notifications never arrive • Around 60% of notifications arrive with noticeable delay Since this is an emergency app, delivery speed is crucial. What could be causing this inconsistency?
1
0
154
Apr ’25
VZLinuxBootLoader failed to boot Aarch64 64K kernel
Works: runs-on: ubuntu-24.04-arm container: image: ubuntu:latest env: DEBIAN_FRONTEND: noninteractive steps: - uses: actions/checkout@v4 - run: | apt-get --assume-yes update apt-get --assume-yes install linux-image-generic dracut binutils - run: | dracut --conf $(mktemp) \ --confdir $(mktemp --directory) \ --verbose \ --modules "base bash" \ --add-drivers "virtio-rng bcachefs btrfs virtiofs overlay xfs" \ --kernel-cmdline "console=hvc0" \ --no-early-microcode \ --no-hostonly \ --no-compress \ --no-uefi \ initramfs \ $(ls /lib/modules/) - run: | cp /boot/vmlinuz-$(ls /lib/modules/) vmlinuz - uses: actions/upload-artifact@v4 with: path: | vmlinuz initramfs Will NOT work: runs-on: ubuntu-24.04-arm container: image: ubuntu:latest env: DEBIAN_FRONTEND: noninteractive steps: - uses: actions/checkout@v4 - run: | apt-get --assume-yes update apt-get --assume-yes install linux-image-generic-64k dracut binutils - run: | dracut --conf $(mktemp) \ --confdir $(mktemp --directory) \ --verbose \ --modules "base bash" \ --add-drivers "virtio-rng bcachefs btrfs virtiofs overlay xfs" \ --kernel-cmdline "console=hvc0" \ --no-early-microcode \ --no-hostonly \ --no-compress \ --no-uefi \ initramfs \ $(ls /lib/modules/) - run: | cp /boot/vmlinuz-$(ls /lib/modules/) vmlinuz - uses: actions/upload-artifact@v4 with: path: | vmlinuz initramfs You can try it on Github Actions
1
0
106
Apr ’25
Accuracy of IBI Values Measured by Apple Watch
I am currently developing an app that measures HRV to estimate stress levels. To align the values more closely with those from Galaxy devices, I decided not to use the heartRateVariabilitySDNN value provided by HealthKit. Instead, I extracted individual interbeat intervals (IBI) using the HKHeartBeatSeries data. Can I obtain accurate IBI data using this method? If not, I would like to know how I can retrieve more precise data. Any insights or suggestions would be greatly appreciated. Here is a sample code I tried. @Observable class HealthKitManager: ObservableObject { let healthStore = HKHealthStore() var ibiValues: [Double] = [] var isAuthorized = false func requestAuthorization() { let types = Set([ HKSeriesType.heartbeat(), HKQuantityType.quantityType(forIdentifier: .heartRateVariabilitySDNN)!, ]) healthStore.requestAuthorization(toShare: nil, read: types) { success, error in DispatchQueue.main.async { self.isAuthorized = success if success { self.fetchIBIData() } } } } func fetchIBIData() { var timePoints: [TimeInterval] = [] var absoluteStartTime: Date? let dateFormatter = DateFormatter() dateFormatter.timeZone = TimeZone(identifier: "Asia/Seoul") dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS" var calendar = Calendar.current calendar.timeZone = TimeZone(identifier: "Asia/Seoul") ?? .current var components = DateComponents() components.year = 2025 components.month = 4 components.day = 3 components.hour = 15 components.minute = 52 components.second = 0 let startTime = calendar.date(from: components)! components.hour = 16 components.minute = 0 let endTime = calendar.date(from: components)! let predicate = HKQuery.predicateForSamples(withStart: startTime, end: endTime, options: .strictStartDate) let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false) let query = HKSampleQuery(sampleType: HKSeriesType.heartbeat(), predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: [sortDescriptor]) { (_, samples, _) in if let sample = samples?.first as? HKHeartbeatSeriesSample { absoluteStartTime = sample.startDate let startDateKST = dateFormatter.string(from: sample.startDate) let endDateKST = dateFormatter.string(from: sample.endDate) print("series start(KST):\(startDateKST)\tend(KST):\(endDateKST)") let seriesQuery = HKHeartbeatSeriesQuery(heartbeatSeries: sample) { query, timeSinceSeriesStart, precededByGap, done, error in if !precededByGap { timePoints.append(timeSinceSeriesStart) } if done { for i in 1..<timePoints.count { let ibi = (timePoints[i] - timePoints[i-1]) * 1000 // Convert to milliseconds // Calculate absolute time for current beat if let startTime = absoluteStartTime { let beatTime = startTime.addingTimeInterval(timePoints[i]) let beatTimeString = dateFormatter.string(from: beatTime) print("IBI: \(String(format: "%.2f", ibi)) ms at \(beatTimeString)") } self.ibiValues.append(ibi) } } } self.healthStore.execute(seriesQuery) } else { print("No samples found for the specified time range") } } self.healthStore.execute(query) } }
Replies
1
Boosts
0
Views
115
Activity
Apr ’25
Detection of file eviction
I want to implement quota feature to my file provider extension. I am able to keep track of materialized files total size. (Content download and edit operations) However I cannot detect file eviction operation (User right click to file and select "Remove Download"). Is there anyway to detect this action Or any suggestion to keep track of materialized files total size?
Replies
2
Boosts
0
Views
193
Activity
Apr ’25
Guidance on Continuous Location & Direction Updates to watchOS App Without Screen Dimming
Dear Apple Developer Support, I am reaching out for guidance on implementing continuous directional and location updates in a watchOS app designed as part of a mapping/navigation solution. Current Scenario: We send continuous location and direction updates from our iOS app to the watchOS companion app. When viewing directions on the Apple Watch, the screen dims after a short period, and the live data stops updating consistently, even though the user is actively looking at the screen. This negatively impacts the usability of real-time navigation on watchOS. Our Objective: Prevent screen dimming (or extend screen-on time) while the user is viewing navigation directions. Ensure reliable, continuous data updates on the watch screen during active navigation sessions. Request: We would appreciate your guidance on: The recommended method to keep the watchOS screen active while displaying real-time navigation data. Proper use of APIs such as WKExtendedRuntimeSession, WorkoutSession, or any other mechanism suitable for this use case. Any best practices or App Store review considerations for apps that require extended screen time and continuous updates. How such use cases were traditionally handled on watchOS and what has or hasn’t worked. We want to ensure we're implementing this in a battery-efficient, user-respectful, and Apple-compliant manner. Thank you for your assistance and guidance.
Replies
1
Boosts
0
Views
100
Activity
Apr ’25
UNEXPECTED_CANCEL_AFTER_completeMerchantValidation
Hi, We are trying to make payment from ecomm merchant. The last request during process is { "sessionData": { "epochTimestamp": "1741082241", "expiresAt": "1741092241", "merchantSessionIdentifier": "SSH88312C485D_7E0DD10173", "nonce": "3f6dc197", "merchantIdentifier": "5F9BC6BAF8", "domainName": "libertybank.ge", "displayName": "Apple Pay Purchase", "signature": "3080060000", "operationalAnalyticsIdentifier": "Apple Pay Purchase:5F9BC6BAF8", "retries": 0, "pspId": "5F9BC6BAF8" } } which is successfully validated applePaySession.completeMerchantValidation(data.sessionData) After this, the "oncancel" handler is triggered in applePay. Please help us to understand what is wrong. Please note the domain where the applepay button is located is at txpg.libertypay.ge Which is successfully verified.
Replies
1
Boosts
0
Views
106
Activity
Apr ’25
Issues with Siri Shortcuts: Confirmation Prompt, Inconsistent Behavior
Hello Apple Developer Community, I’m working on integrating Siri into my React Native app using native iOS code and bridging to React Native. I’ve followed the necessary steps to set up Siri support, including: Adding the Siri capability. Adding Siri usage descriptions in Info.plist. Using AppIntent and AppShortcutsProvider to define shortcuts. However, I’m facing the following issues: Siri Prompts for Confirmation When a user says a phrase, Siri asks, "Turn on 'MyApp' shortcuts with Siri?" instead of directly recognizing the phrase. Is this expected behavior? If so, how can I reduce friction for users and make the experience more seamless? Inconsistent Behavior for Existing Users For users updating to a version with Siri support: When the app is closed, Siri says, "MyApp hasn't added support for that with Siri." When the app is open, Siri prompts, "Turn on shortcut for MyApp?" and rest all working fine Why does Siri not recognize the shortcut when the app is closed, even though the shortcut is defined in AppShortcutsProvider? How can I ensure that Siri recognizes the shortcut regardless of whether the app is open or closed? Other than using AppIntent and AppShortcutsProvider should i try Donating shortcuts(will that helps for updated user case). Please help me on this
Replies
8
Boosts
1
Views
633
Activity
Apr ’25
WidgetKit And Picture rotation
I'm developing a widget with WidgetKit, and I'm having a problem: I need to click on an image, and when I click it triggers a network request, the image automatically rotates clockwise, and when the network ends, the image automatically stops rotating. How to do that? My current idea is to click on the image and await the call to the network request. Should Toggle be used for the control corresponding to the picture? Because Toggle has two states. Then there is how to do image rotation, did not find support API.
Replies
1
Boosts
0
Views
129
Activity
Apr ’25
can bluetooth peripheral device maintain connection when app is killed?
Is there a way for the bluetooth peripheral device to remain connected to iOS even after the app which was used to pair with it has been swipe killed by the user? I have - enabled Background Modes (Uses Bluetooth LE Accessory) given all the relevant permissions (Background refresh) implemented state preservation and restoration. properly handled Connection Events with proper options (CBConnectPeripheralOptionNotifyOnConnectionKey and CBConnectPeripheralOptionNotifyOnDisconnectionKey) e.g Fitbit shows as connected in bluetooth settings even after the app has been swipe killed by the user.
Replies
1
Boosts
1
Views
131
Activity
Apr ’25
NSPasteboard in System Extension
I am trying to access clipboard via NSPasteboard API from a System Extension. However, all of its get methods return empty arrays and nil objects. Is that expected? Is there some permission or entitlement required for a System Extension to access clipboard?
Replies
2
Boosts
0
Views
118
Activity
Apr ’25
Issues with Opening iOS Settings from App
Hi there! We are working on our SkyElectric App which is being developed in Flutter framework, where we need user to connect with the Wifi of the the inverter. We are trying to direct user to WiFi Settings page of the iOS in general settings where all the available WiFi Networks are listed but unfortunately user is being directed to App's Settings page. We are using package of app_settings and launcher. I've read that Apple changed a policy in 2019 where it restricts Apps to navigate to OS pages. Question: Could you please verify if I APPLE allows us to access the General Settings or WiFi Settings through clicking a button in our App name "Open WiFi Settings", If not then Why?
Replies
2
Boosts
0
Views
91
Activity
Apr ’25
how to register listener to `NWConnectionGroup` for QUIC
I am trying to make http3 client with Network.framework on Apple platforms. Codes that implement NWConnectionGroup.start with NWListener don't always work with warning below. I assume NWConnectionGroup.newConnectionHandler or NWListener.newConnectionHandler will be called to start connection from the server if it works. nw_protocol_instance_add_new_flow [C1.1.1:2] No listener registered, cannot accept new flow quic_stream_add_new_flow [C1.1.1:2] [-fde1594b83caa9b7] failed to create new stream for received stream id 3 so I tried: create the NWListener -> not work check whether NWConnectionGroup has a member to register or not NWListener -> not work (it doesn't have). use NWConnection instead of NWConnectionGroup -> not work Is my understanding correct? How should I do to set or associate listener with NWConnection/Group for newConnectionHandler is called and to delete wanings? What is the best practice in the case? Sample codes are below. Thanks in advance. // http3 needs unidirectional stream by the server and client. // listener private let _listener: NWListener let option: NWProtocolQUIC.Options = .init(alpn:["h3"]) let param: NWParameters = .init(quic: option) _listener = try! .init(using: param) _listener.stateUpdateHandler = { state in print("listener state: \(state)") } _listener.newConnectionHandler = { newConnection in print("new connection added") } _listener.serviceRegistrationUpdateHandler = { registrationState in print("connection registrationstate") } // create connection private let _group: NWConnectionGroup let options: NWProtocolQUIC.Options = .init(alpn: ["h3"]) options.direction = .unidirectional options.isDatagram = false options.maxDatagramFrameSize = 65535 sec_protocol_options_set_verify_block(options.securityProtocolOptions, {(_: sec_protocol_metadata_t, _: sec_trust_t, completion: @escaping sec_protocol_verify_complete_t) in print("cert completion.") completion(true) }, .global()) let params: NWParameters = .init(quic: options) let group: NWMultiplexGroup = .init( to: .hostPort(host: NWEndpoint.Host("google.com"), port: NWEndpoint.Port(String(443))!)) _group = .init(with: group, using: params) _group.setReceiveHandler {message,content,isComplete in print("receive: \(message)") } _group.newConnectionHandler = {newConnection in print("newConnectionHandler: \(newConnection.state)") } _group.stateUpdateHandler = { state in print("state: \(state)") } _group.start(queue: .global()) _listener.start(queue: .global()) if let conn = _group.extract() { let data: Data = .init() let _ = _group.reinsert(connection: conn) conn.send(content: data, completion: .idempotent) }
Replies
4
Boosts
0
Views
223
Activity
Apr ’25
How to implement normal loading of web content when I intercept all request header information using the Swizzling method
I am developing a web application, I hope to be able to intercept all requests in the loaded web page, match the network request I want to specifically intercept the network request and then obtain the request header information (not the user's personal privacy data interception), if the use is the method of injection, the request header information is incomplete, such as the more important "content-type" field in the request header, so I try to use Swizzling method to intercept all http and https requests, and I can now intercept all the request information. But there is still a problem with my project, when loading x.com, logging in, appearing white screen after the successful landing, and not loading to the page after the successful landing, I don't know where the reason is。 Below is my core code implementation fragment. import WebKit // MARK: - WebViewController class WebViewController: UIViewController { fileprivate var webView: WKWebView! private var schemeHandler: WWKProxyWKURLSchemeHandler! override func viewDidLoad() { super.viewDidLoad() Self.initSwizzling setupWebView() loadInitialContent() } private func setupWebView() { let config = WKWebViewConfiguration() schemeHandler = WWKProxyWKURLSchemeHandler() config.setURLSchemeHandler(self.schemeHandler, forURLScheme: "https") config.setURLSchemeHandler(self.schemeHandler, forURLScheme: "http") webView = WKWebView(frame: view.bounds, configuration: config) webView.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.addSubview(webView) } private func loadInitialContent() { if let url = URL(string: "https://x.com") { let request = URLRequest(url: url,cachePolicy:.reloadIgnoringLocalCacheData,timeoutInterval: 15) webView.load(request) } } func reloadWebView() { webView?.reloadFromOrigin() } } class WWKProxyWKURLSchemeHandler: NSObject, WKURLSchemeHandler { private let lock = NSLock() private var activeTasks = [ObjectIdentifier: URLSessionDataTask]() func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) { lock.lock() defer { lock.unlock() } let taskID = ObjectIdentifier(urlSchemeTask) guard !activeTasks.keys.contains(taskID) else { print("⚠️ Task already started: \(urlSchemeTask.request.url?.absoluteString ?? "")") return } print("Intercepted URL---:",urlSchemeTask.request.url?.absoluteString ?? "") print("All requests intercepted----:",urlSchemeTask.request.allHTTPHeaderFields) let request = urlSchemeTask.request let dataTask = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in guard let self = self else { return } self.lock.lock() let isActive = self.activeTasks[taskID] != nil self.lock.unlock() guard isActive else { print("🌀 Task already cancelled: \(urlSchemeTask.request.url?.absoluteString ?? "")") return } // Make sure it only handles once guard self.activeTasks.keys.contains(taskID) else { return } self.activeTasks.removeValue(forKey: taskID) DispatchQueue.main.async { if let error = error { urlSchemeTask.didFailWithError(error) print("🔴 Task failed: \(urlSchemeTask.request.url?.absoluteString ?? "") - \(error.localizedDescription)") return } guard let response = response, let data = data else { urlSchemeTask.didFailWithError(URLError(.unknown)) print("🔴 Invalid response: \(urlSchemeTask.request.url?.absoluteString ?? "")") return } urlSchemeTask.didReceive(response) urlSchemeTask.didReceive(data) urlSchemeTask.didFinish() print("🟢 Task completed: \(urlSchemeTask.request.url?.absoluteString ?? "")") } } self.activeTasks[taskID] = dataTask dataTask.resume() } func webView(_ webView: WKWebView, stop task: WKURLSchemeTask) {} private func finishTask(taskID: ObjectIdentifier ,task: WKURLSchemeTask, response: URLResponse?, data: Data?, error: Error?) { lock.lock() defer { lock.unlock() } guard activeTasks.keys.contains(taskID) else { return } activeTasks.removeValue(forKey: taskID) DispatchQueue.main.async { if let error = error { task.didFailWithError(error) print("🔴 Task failed: \(task.request.url?.absoluteString ?? "") - \(error.localizedDescription)")return} guard let response = response, let data = data else { task.didFailWithError(URLError(.unknown)) print("🔴 Invalid response: \(task.request.url?.absoluteString ?? "")") return } task.didReceive(response) task.didReceive(data) task.didFinish() print("🟢 Task completed: \(task.request.url?.absoluteString ?? "")") } } } extension WKWebView { @objc dynamic class func qm_handlesURLScheme(_ urlScheme: String) -> Bool { if urlScheme == "https" || urlScheme == "http" {return false} return self.qm_handlesURLScheme(urlScheme) } // Exchange of execution methods static func setupSwizzling() { let originalSelector = #selector(handlesURLScheme(_:)) let swizzledSelector = #selector(qm_handlesURLScheme(_:)) // Implemented by Runtime Get Method guard let originalMethod = class_getClassMethod(WKWebView.self, originalSelector), let swizzledMethod = class_getClassMethod(WKWebView.self, swizzledSelector) else { return } // Implementation of Exchange Methods method_exchangeImplementations(originalMethod, swizzledMethod) } } extension WebViewController { private static let initSwizzling: Void = { DispatchQueue.once(token: "com.webview.swizzling") { WKWebView.setupSwizzling() } }() } // GCD Once extension DispatchQueue { private static var tokens = Set<String>() class func once(token: String, block: () -> Void) { objc_sync_enter(self) defer { objc_sync_exit(self) } guard !tokens.contains(token) else { return } tokens.insert(token) block() } } extension WebViewController: WKNavigationDelegate { func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { decisionHandler(.allow) } }
Replies
1
Boosts
0
Views
105
Activity
Apr ’25
On-demand rules
I've implemented a custom system extension VPN for macOS using Packet Tunnel Provider. The VPN is configured with on-demand, and a rule to always connect whenever there's traffic: onDemandRules = [NEOnDemandRuleConnect()] As expected, if the VPN isn't active, all traffic gets blocked until it is ready. Not expected: In the following scenario, there is some 'traffic leak': Use only WiFi (not wired cable) Connect the VPN Disable the WiFi and wait for the VPN to disconnect Enable the WiFi Some packets are routed outside the VPN, and aren't being blocked Some moments after, all traffic will be blocked, and the VPN will start the 'connecting' process. Is the above scenario a 'known' issue? Can it be a race condition in the OS, where some packets can be sent after the network is brought back before the VPN process starts? Is there any way to fix this problem? P.S: I'm not using flags such as 'capture all network'
Replies
3
Boosts
1
Views
203
Activity
Apr ’25
Working with Input/Output stream with Swift 6 and concurrency framework
Hello, I am developing an application which is communicating with external device using BLE and L2CAP. I wonder what are the best practices of using Input & Output streams that are established with L2CAP connection when working with Swift 6 concurrency model. I've been trying to find some examples and hints for some time now but unfortunately there isn't much available. One useful thread I've found is: https://aninterestingwebsite.com/forums/thread/756281 but it does not offer much insight into using eg. actor model with streams. I wonder if something has changed in this regards? Also, are there any plans to migrate eg. CoreBluetooth stack to new swift 6 concurrency ?
Replies
2
Boosts
0
Views
170
Activity
Apr ’25
Decode Tool BaseSystem.chunklist
How can i decode all this message I found in File name BaseSystem.chunklist because I use all decode online tool not work at all?
Replies
2
Boosts
0
Views
69
Activity
Apr ’25
Swift MacOS-Check if a file at a URL is open
Hi Is there a way to check if a file at a specified URL is open and being edited by another application. Assuming that we have permission to access the file at the URL.
Replies
4
Boosts
0
Views
209
Activity
Apr ’25
Not Receiving Incoming VoIP Push Notifications on iOS 18.4 (React Native App)
Hi Apple Dev Team, We have a React Native application that includes call functionality using PushKit and VoIP notifications. We are using APNS to send the VoIP notifications, and everything has been working smoothly on iOS versions up to 18.3.1. However, after updating to iOS 18.4, we are no longer receiving incoming VoIP push notifications on the device. There have been no code changes related to our PushKit or notification logic — the exact same build continues to work correctly on devices running iOS 18.3.1 and earlier. We're trying to understand if anything has changed in iOS 18.4 that affects VoIP push delivery or registration behavior. Would appreciate any guidance, and happy to share code snippets or configuration if needed. Thanks in advance!
Replies
1
Boosts
1
Views
175
Activity
Apr ’25
Push payload is not present on notification tap
I am checking if the user taps on the firebase push notification and get the payload. override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo os_log("notification tapped %{public}@", log: OSLog.push, type: .info, userInfo) handleNotificationPayload(userInfo as! [String: AnyObject]) setFlutterLinkClickedVariable() } My use case is in app terminated state when push notification is tapped, get the link from payload and navigate to corresponding screen based on the link. This is working when there is only one push notification. When there are multiple push notifications with different links in the payload, only the first notification I tap works. Rest of the notifications just launches the app and does not navigate because the link is not set. I am getting the link from the payload and invoking flutter code which sets the link in the user defaults (shared preferences) and when the app launches in the home screen it checks for this variable and navigates accordingly. func handleNotificationPayload(_ payload: [String: AnyObject]) { if let link = payload["link"] as? String { setFlutterLinkVariable(link) } } override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { os_log("app did receive remote notification %{public}@", log: OSLog.push, type: .info, userInfo) handleNotificationPayload(userInfo as! [String : AnyObject]) completionHandler(.newData) } Currently when there is only one push notification it works because the link is set from the above method. The click delegate is not calling. I did set the delegate in application(:didFinishLaunchingWithOptions). UNUserNotificationCenter.current().delegate = self application.registerForRemoteNotifications() How to solve this issue? Thanks.
Replies
2
Boosts
0
Views
794
Activity
Apr ’25
How can you tick between live activities?
I have been watching the following moment from wwdc (Design dynamic Live Activities): https://aninterestingwebsite.com/videos/play/wwdc2023/10194/?time=728 It suggest that you should 'tick' between multiple live activities of your app: When you want to show multiple sessions for your app going on at once, consider ticking between the display of them to continue to give users an eye on everything that’s going on. How can I tick between them? More specifically how can I do that when my app is in the background?
Replies
1
Boosts
1
Views
252
Activity
Apr ’25
Background Push Notifications for Emergency App Delayed Despite Critical Alert Entitlement
I’m using Appnotic from my server to send notifications for an emergency service, where it is critical that notifications are delivered immediately. My payload looks like this: "aps": { "alert": "Test alert", "sound": { "critical": 1, "name": "sound.wav", "volume": 0.5 }, "content-available": 1, "category": "alert" }, "topic": "com.fireservicerota.FSR-Primary-Alerting", "custom_payload": { "id": "11", "type": "alert", "incident_id": 23434, "incident_response_id": 2652343, "expiration_time": "2024-06-06T16:59:05+01:00" } } I already have the critical alert entitlement and background processing enabled. Everything seems fine when debugging, but I’m experiencing issues: • Some notifications never arrive • Around 60% of notifications arrive with noticeable delay Since this is an emergency app, delivery speed is crucial. What could be causing this inconsistency?
Replies
1
Boosts
0
Views
154
Activity
Apr ’25
VZLinuxBootLoader failed to boot Aarch64 64K kernel
Works: runs-on: ubuntu-24.04-arm container: image: ubuntu:latest env: DEBIAN_FRONTEND: noninteractive steps: - uses: actions/checkout@v4 - run: | apt-get --assume-yes update apt-get --assume-yes install linux-image-generic dracut binutils - run: | dracut --conf $(mktemp) \ --confdir $(mktemp --directory) \ --verbose \ --modules "base bash" \ --add-drivers "virtio-rng bcachefs btrfs virtiofs overlay xfs" \ --kernel-cmdline "console=hvc0" \ --no-early-microcode \ --no-hostonly \ --no-compress \ --no-uefi \ initramfs \ $(ls /lib/modules/) - run: | cp /boot/vmlinuz-$(ls /lib/modules/) vmlinuz - uses: actions/upload-artifact@v4 with: path: | vmlinuz initramfs Will NOT work: runs-on: ubuntu-24.04-arm container: image: ubuntu:latest env: DEBIAN_FRONTEND: noninteractive steps: - uses: actions/checkout@v4 - run: | apt-get --assume-yes update apt-get --assume-yes install linux-image-generic-64k dracut binutils - run: | dracut --conf $(mktemp) \ --confdir $(mktemp --directory) \ --verbose \ --modules "base bash" \ --add-drivers "virtio-rng bcachefs btrfs virtiofs overlay xfs" \ --kernel-cmdline "console=hvc0" \ --no-early-microcode \ --no-hostonly \ --no-compress \ --no-uefi \ initramfs \ $(ls /lib/modules/) - run: | cp /boot/vmlinuz-$(ls /lib/modules/) vmlinuz - uses: actions/upload-artifact@v4 with: path: | vmlinuz initramfs You can try it on Github Actions
Replies
1
Boosts
0
Views
106
Activity
Apr ’25