Hi apple team,
I'm using Apple Root Certificates from https://www.apple.com/certificateauthority/ for communicating with App Store Server Library for receipt validation API.
Apple Computer, Inc Root certificate from the website is Not Valid After: Monday, 10 February 2025 at 01:18:14 Central European Standard Time.
When we can expect update of this certificate.
Thank you
Delve into the world of built-in app and system services available to developers. Discuss leveraging these services to enhance your app's functionality and user experience.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
After opening the Apple Pay Popup and try to close the popup (without scanning the QR Code), the oncancel handler (accociated with the created session) doesn't fire.
Meanwhile if the merchant scanned the QR code and the UI of the popup changed, then cancel the popup manually (using close (X) button), it fires the session.oncancel event handler.
Here is applied setup:
const { ApplePaySession } = window;
if (!(ApplePaySession && ApplePaySession.canMakePayments())) {
return new Error('Apple Pay Session is not available');
}
const paymentCapabilities = await ApplePaySession.applePayCapabilities(
applePaymentOptionsMetaData.merchantIdentifier,
);
if (paymentCapabilities.paymentCredentialStatus === 'applePayUnsupported') {
console.error('ApplePaySession is not supported.');
return;
}
const request = {
"countryCode": "KW",
"currencyCode": "KWD",
"merchantCapabilities": [
"supports3DS"
],
"supportedNetworks": [
"VISA",
"MASTERCARD"
],
"billingContact": {
"phoneNumber": "201000000000",
"emailAddress": "example@test.com",
"givenName": "Ahmed",
"familyName": "Sharkawy"
},
"total": {
"amount": "3.085",
"label": "Merchant Testing"
}
}
const session = new ApplePaySession(5, request);
session.onvalidatemerchant = async event => {
if (debug) {
console.info('Creating merchant session and validating merchant session');
console.info('onvalidatemerchant event', event);
}
try {
// Validation Merchant Request
session.completeMerchantValidation(data);
} catch (error: any) {
session.completePayment({ status: ApplePaySession.STATUS_FAILURE });
}
};
session.onpaymentauthorized = async (event) => {
session.completePayment({ status: ApplePaySession.STATUS_SUCCESS });
};
// This doesn't fire
session.oncancel = () => {
console.info('EVENT: oncancel');
};
session.begin();
Hello
My app has implementation of In App Provisioning which is working fine. We have now added Wallet Extensions to it, but my App is not shown in Apple Wallet "From apps on your iphone"
I have uploaded Feedback (FB16450547) at
https://feedbackassistant.apple.com/feedback/16450547
Kindly request for your advice
Hello,
I am encountering an issue with maintaining socket connections in iOS applications that need to remain active while in background mode.
I am developing an application that requires maintaining an active socket connection in the background to receive real-time data. However, I've noticed that the socket connection is terminated as soon as the app enters background mode, which affects the intended functionality of my app.
I understand that there are restrictions on background activities in iOS to preserve battery life and system resources. However, I would like to know what approach Apple recommends for handling this type of requirement. Are there specific APIs or configurations I should consider to ensure the socket remains active in the background?
I would greatly appreciate any guidance or resources you could provide. I am eager to ensure that my app complies with Apple's guidelines and delivers the best possible experience for users.
Topic:
App & System Services
SubTopic:
Notifications
We recently notified from Apple that our Hotspot helper is delaying device to switch Wifi Networks. To handle this issue better, we need to refactor our code a bit handle the scenario gracefully and while reading this documentation https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/Hotspot_Network_Subsystem_Guide/Contents/AuthStateMachine.html#//apple_ref/doc/uid/TP40016639-CH2-SW1
Some questions came up while responding back to evaluate and filterscanlist command. Here are our questions
What is the lifecycle of exclude_list? Does it get cleared every time Authentication State Machine goes into Inactive State?
What happens if we send commandNotRecognized/unsupportedNetwork/temporaryFailure after evaluate command? Does our app get an evaluate command next time when device joins the same network?
What is the actual time for the app to respond to network change evaluate command? Is 45 seconds the timeout limit for app to evaluate and respond?
After responding to the evaluate command, how quickly is it terminated from running in the background?
Topic:
App & System Services
SubTopic:
Networking
The UIApplication background task mechanism allows you to prevent your app from being suspended for short periods of time. While the API involved is quite small, there’s still a bunch of things to watch out for.
The name background task is somewhat misappropriate. Specifically, beginBackgroundTask(expirationHandler:) doesn’t actually start any sort of background task, but rather it tells the system that you have started some ongoing work that you want to continue even if your app is in the background. You still have to write the code to create and manage that work. So it’s best to think of the background task API as raising a “don’t suspend me” assertion.
You must end every background task that you begin. Failure to do so will result in your app being killed by the watchdog. For this reason I recommend that you attach a name to each background task you start (by calling beginBackgroundTask(withName:expirationHandler:) rather than beginBackgroundTask(expirationHandler:)). A good name is critical for tracking down problems when things go wrong.
IMPORTANT Failing to end a background task is the number one cause of background task problems on iOS. This usually involves some easy-to-overlook error in bookkeeping that results in the app begining a background task and not ending it. For example, you might have a property that stores your current background task identifier (of type UIBackgroundTaskIdentifier). If you accidentally creates a second background task and store it in that property without calling endBackgroundTask on the identifier that’s currently stored there, the app will ‘leak’ a background task, something that will get it killed by the watchdog. One way to avoid this is to wrap the background task in an object; see the QRunInBackgroundAssertion post on this thread for an example.
Background tasks can end in one of two ways:
When your app has finished doing whatever it set out to do.
When the system calls the task’s expiry handler.
Your code is responsible for calling endBackgroundTask(_:) in both cases.
All background tasks must have an expiry handler that the system can use to ‘call in’ the task. The background task API allows the system to do that at any time.
Your expiry handler is your opportunity to clean things up. It should not return until everything is actually cleaned up. It must run quickly, that is, in less than a second or so. If it takes too long, your app will be killed by the watchdog.
Your expiry handler is called on the main thread.
It is legal to begin and end background tasks on any thread, but doing this from a secondary thread can be tricky because you have to coordinate that work with the expiry handler, which is always called on the main thread.
The system puts strict limits on the total amount of time that you can prevent suspension using background tasks. On current systems you can expect about 30 seconds.
IMPORTANT I’m quoting these numbers just to give you a rough idea of what to expect. The target values have changed in the past and may well change in the future, and the amount of time you actually get depends on the state of the system. The thing to remember here is that the exact value doesn’t matter as long as your background tasks have a functional expiry handler.
You can get a rough estimate of the amount of time available to you by looking at UIApplication’s backgroundTimeRemaining property.
IMPORTANT The value returned by backgroundTimeRemaining is an estimate and can change at any time. You must design your app to function correctly regardless of the value returned. It’s reasonable to use this property for debugging but we strongly recommend that you avoid using as part of your app’s logic.
IMPORTANT Basing app behaviour on the value returned by backgroundTimeRemaining is the number two cause of background task problems on iOS.
The system does not guarantee any background task execution time. It’s possible (albeit unlikely, as covered in the next point) that you’ll be unable to create a background task. And even if you do manage to create one, its expiry handler can be called at any time.
beginBackgroundTask(expirationHandler:) can fail, returning UIBackgroundTaskInvalid, to indicate that you the system is unable to create a background task. While this was a real possibility when background tasks were first introduced, where some devices did not support multitasking, you’re unlikely to see this on modern systems.
The background time ‘clock’ only starts to tick when the background task becomes effective. For example, if you start a background task while the app is in the foreground and then stay in the foreground, the background task remains dormant until your app moves to the background. This can help simplify your background task tracking logic.
The amount of background execution time you get is a property of your app, not a property of the background tasks themselves. For example, starting two background task in a row won’t give you 60 seconds of background execution time.
Notwithstanding the previous point, it can still make sense to create multiple background tasks, just to help with your tracking logic. For example, it’s common to create a background task for each job being done by your app, ending the task when the job is done.
Do not create too many background tasks. How many is too many? It’s absolutely fine to create tens of background tasks but creating thousands is not a good idea.
IMPORTANT iOS 11 introduced a hard limit on the number of background task assertions a process can have (currently about 1000, but the specific value may change in the future). If you see a crash report with the exception code 0xbada5e47, you’ve hit that limit.
Note The practical limit that you’re most likely to see here is the time taken to call your expiry handlers. The watchdog has a strict limit (a few seconds) on the total amount of time taken to run background task expiry handlers. If you have thousands of handlers, you may well run into this limit.
If you’re working in a context where you don’t have access to UIApplication (an app extension or on watchOS) you can achieve a similar effect using the performExpiringActivity(withReason:using:) method on ProcessInfo.
If your app ‘leaks’ a background task, it may end up being killed by the watchdog. This results in a crash report with the exception code 0x8badf00d (“ate bad food”).
IMPORTANT A leaked background task is not the only reason for an 0x8badf00d crash. You should look at the backtrace of the main thread to see if the main thread is stuck in your code, for example, in a synchronous networking request. If, however, the main thread is happily blocked in the run loop, a leaked background task should be your primary suspect.
Prior to iOS 11 information about any outstanding background tasks would appear in the resulting crash report (look for the text BKProcessAssertion). This information is not included by iOS 11 and later, but you can find equivalent information in the system log.
The system log is very noisy so it’s important that you give each of your background tasks an easy-to-find name.
For more system log hints and tips, see Your Friend the System Log.
iOS 13 introduced the Background Tasks framework. This supports two type of requests:
The BGAppRefreshTaskRequest class subsumes UIKit’s older background app refresh functionality.
The BGProcessingTaskRequest class lets you request extended background execution time, typically overnight.
WWDC 2020 Session 10063 Background execution demystified is an excellent summary of iOS’s background execution model. Watch it, learn it, love it!
For more background execution hints and tips, see Background Tasks Resources.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Revision History
2023-06-16 Added a link to my QRunInBackgroundAssertion post.
2022-06-08 Corrected a serious error in the discussion of BGProcessingTaskRequest. Replaced the basic system log info with a reference to Your Friend the System Log. Added a link to Background Tasks Resources. Made other minor editorial changes.
2021-02-27 Fixed the formatting. Added a reference to the Background Tasks framework and the Background execution demystified WWDC presentation. Minor editorial changes.
2019-01-20 Added a note about changes in the iOS 13 beta. Added a short discussion about beginning and ending background tasks on a secondary thread.
2018-02-28 Updated the task name discussion to account for iOS 11 changes. Added a section on how to debug ‘leaked’ background tasks.
2017-10-31 Added a note about iOS 11’s background task limit.
2017-09-12 Numerous updates to clarify various points.
2017-08-17 First posted.
Hello Everyone,
We have some doubts regarding the apple notification alert update received in Oct 2024 for APNS server certificate update.
Does this change is already live for sandbox environment?
As we have checked on sandbox environment without changing any certificate its working and we are able to get push notification.
Does that means our system does not need any change for production as well?
If required where we should add https://www.sectigo.com/knowledge-base/detail/Sectigo-Intermediate-Certificates/kA01N000000rfBO. This certificate.
For FYI we are using python library called django-push-notifications which internally call to the APNS server for push notifications.
Hello everyone,
I want send haptics to ps4 controller.
CHHapticPatternPlayer and CHHapticAdvancedPatternPlayer good work with iPhone.
On PS4 controller If I use CHHapticPatternPlayer all work good, but if I use CHHapticAdvancedPatternPlayer I get error. I want use CHHapticAdvancedPatternPlayer to use additional settings. I don't found any information how to fix it -
CHHapticEngine.mm:624 -[CHHapticEngine finishInit:]_block_invoke: ERROR: Server connection broke with error 'Не удалось завершить операцию. (com.apple.CoreHaptics, ошибка -4811)'
The engine stopped because a system error occurred.
AVHapticClient.mm:1228 -[AVHapticClient getSyncDelegateForMethod:errorHandler:]_block_invoke: ERROR: Sync XPC call for 'loadAndPrepareHapticSequenceFromEvents:reply:' (client ID 0x21) failed: Не удалось установить связь с приложением-помощником.
Не удалось создать или воспроизвести паттерн: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service with pid 5087 named com.apple.GameController.gamecontrollerd.haptics" UserInfo={NSDebugDescription=connection to service with pid 5087 named com.apple.GameController.gamecontrollerd.haptics}
My Haptic class -
import Foundation
import CoreHaptics
import GameController
protocol HapticsControllerDelegate: AnyObject {
func didConnectController()
func didDisconnectController()
func enginePlayerStart(value: Bool)
}
final class HapticsControllerManager {
static let shared = HapticsControllerManager()
private var isSetup = false
private var hapticEngine: CHHapticEngine?
private var hapticPlayer: CHHapticAdvancedPatternPlayer?
weak var delegate: HapticsControllerDelegate? {
didSet {
if delegate != nil {
startObserving()
}
}
}
deinit {
NotificationCenter.default.removeObserver(self)
}
private func startObserving() {
guard !isSetup else { return }
NotificationCenter.default.addObserver(
self,
selector: #selector(controllerDidConnect),
name: .GCControllerDidConnect,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(controllerDidDisconnect),
name: .GCControllerDidDisconnect,
object: nil
)
isSetup = true
}
@objc private func controllerDidConnect(notification: Notification) {
delegate?.didConnectController()
self.createAndStartHapticEngine()
}
@objc private func controllerDidDisconnect(notification: Notification) {
delegate?.didDisconnectController()
hapticEngine = nil
hapticPlayer = nil
}
private func createAndStartHapticEngine() {
guard let controller = GCController.controllers().first else {
print("No controller connected")
return
}
guard controller.haptics != nil else {
print("Haptics not supported on this controller")
return
}
hapticEngine = createEngine(for: controller, locality: .default)
hapticEngine?.playsHapticsOnly = true
do {
try hapticEngine?.start()
} catch {
print("Не удалось запустить движок тактильной обратной связи: \(error)")
}
}
private func createEngine(for controller: GCController, locality: GCHapticsLocality) -> CHHapticEngine? {
guard let engine = controller.haptics?.createEngine(withLocality: locality) else {
print("Failed to create engine.")
return nil
}
print("Successfully created engine.")
engine.stoppedHandler = { reason in
print("The engine stopped because \(reason.message)")
}
engine.resetHandler = {
print("The engine reset --> Restarting now!")
do {
try engine.start()
} catch {
print("Failed to restart the engine: \(error)")
}
}
return engine
}
func startHapticFeedback(haptics: [CHHapticEvent]) {
do {
let pattern = try CHHapticPattern(events: haptics, parameters: [])
hapticPlayer = try hapticEngine?.makeAdvancedPlayer(with: pattern)
hapticPlayer?.loopEnabled = true
try hapticPlayer?.start(atTime: 0)
self.delegate?.enginePlayerStart(value: true)
} catch {
self.delegate?.enginePlayerStart(value: false)
print("Не удалось создать или воспроизвести паттерн: \(error)")
}
}
func stopHapticFeedback() {
do {
try hapticPlayer?.stop(atTime: 0)
self.delegate?.enginePlayerStart(value: false)
} catch {
self.delegate?.enginePlayerStart(value: true)
print("Не удалось остановить воспроизведение вибрации: \(error)")
}
}
}
extension CHHapticEngine.StoppedReason {
var message: String {
switch self {
case .audioSessionInterrupt:
return "the audio session was interrupted."
case .applicationSuspended:
return "the application was suspended."
case .idleTimeout:
return "an idle timeout occurred."
case .systemError:
return "a system error occurred."
case .notifyWhenFinished:
return "playback finished."
case .engineDestroyed:
return "the engine was destroyed."
case .gameControllerDisconnect:
return "the game controller disconnected."
@unknown default:
return "an unknown error occurred."
}
}
}
custom haptic events -
static func changeVibrationPower(power: HapricPower) -> [CHHapticEvent] {
let continuousEvent = CHHapticEvent(eventType: .hapticContinuous, parameters: [
CHHapticEventParameter(parameterID: .hapticSharpness, value: 1.0),
CHHapticEventParameter(parameterID: .hapticIntensity, value: power.value)
], relativeTime: 0, duration: 0.5)
return [continuousEvent]
}
The code below using LookAroundPreview works fine on iOS (showing the preview image with a button saying "Look Around" at the top to enter full screen with navigation), but on macOS (15.3) there is no button and no way to navigate the view. Is this a bug or is there something I need to do differently on macOS? I have also tried using AppKit with MKLookAroundViewController and I don't seem get the button to launch full screen there either.
import SwiftUI
import MapKit
struct ContentView: View {
var body: some View {
LookAroundPreviewView(coordinate: CLLocationCoordinate2D(latitude: 37.33182, longitude: -122.03118))
.frame(width: 300, height: 200)
}
}
struct LookAroundPreviewView: View {
let coordinate: CLLocationCoordinate2D
@State private var scene: MKLookAroundScene?
@State private var errorMessage: String?
var body: some View {
Group {
if scene != nil {
LookAroundPreview(scene: $scene, allowsNavigation: true)
} else if let errorMessage = errorMessage {
Text("Error: \(errorMessage)")
.foregroundColor(.red)
} else {
ProgressView("Loading Look Around Preview...")
}
}
.task {
do {
let request = MKLookAroundSceneRequest(coordinate: coordinate)
let fetchedScene = try await request.scene
scene = fetchedScene
} catch {
errorMessage = error.localizedDescription
print("Error loading Look Around scene: \(error)")
}
}
}
}
Hi, I’m working on a case in our organisation where we encounter regular wireless network disconnections - 30 and 60 minutes. ~ 1800 sec session is widely seen across hundreds if not thousand Macbooks.
We excluded internal wireless configuration issue and vendor specific problem as the disconnections happen on both Cisco and Ubiquiti Access Points.
Wireless Controller debugging most often show EAP timeout error.
Sniffer shows that the disassociation is initiated by Macbook.
MacOS logs show wifianalyticsd performing some actions before the disconnection (generated with sudo log show --debug [time]):
2025-02-04 14:16:31.219169+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[WAEngine gatherConsecutiveDatapathReadings:forProcessToken:andReply:]_block_invoke::4238:SDNS: WiFi Not Primary - setting suppressedReason kSymptomsDnsWiFiInterfaceNotPrimary
2025-02-04 14:16:31.219192+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine updateTimeSincePreviousTriggerForStudy:msgKey:dictKey:]::913:msgkey:WFAAWDWASDS_symptomsDnsTimeSincePreviousTriggerMinutes dictKey:dps_lastSymptomsDpsTrigger previous_TS:(null) current_TS:Tue
Feb 4 14:16:31 2025 difference:0
2025-02-04 14:16:31.219704+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine updateScreenState]::198:DPS Fast Reset Recommendation Engine: (screenON & foreGrnd traffic) is DETECTED
2025-02-04 14:16:31.219713+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine recommendSymptomsDpsRecovery:symptomsDnsStats:awdlState:currentSymptomsCondition:isLANPingSuccessful:appUsage:averageCCA:]::966:PeerDiagnostics: Data not received from peerDiagnostics
2025-02-04 14:16:31.219714+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine checkForPriorityNetwork]::256:Priority Network Check Disabled: NO IsPriorityNetwork: YES
2025-02-04 14:16:31.219732+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine isResetAllowedForKey:forPrefSelector:]::330:key:symptomsDps_lastScreenOnRecoveryWD previousWD_TS:(null) currentWD_TS:Tue Feb 4 14:16:31 2025 recommendation:YES
2025-02-04 14:16:31.219735+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine updateSymptomsDPSRecoveryWDStatsForKey:]::210:Added key: symptomsDps_numRecommendedScreenOnRecoveryWD value:1 dict:(null)
2025-02-04 14:16:31.219737+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine recommendSymptomsDpsRecovery:symptomsDnsStats:awdlState:currentSymptomsCondition:isLANPingSuccessful:appUsage:averageCCA:]::1023:PeerDiagnostics: Recommendation for DNS Symptoms Recovery: Reassoc
2025-02-04 14:16:31.219740+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[WAEngine gatherConsecutiveDatapathReadings:forProcessToken:andReply:]_block_invoke::4276:PeerDiagnostics: Triggering Reassoc for symptoms-dps
2025-02-04 14:16:31.219741+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[WAEngine gatherConsecutiveDatapathReadings:forProcessToken:andReply:]_block_invoke::4277:SDNS: Recommendation - kSymptomsdDPSReassoc, triggering reassoc wiith reason ReassociateOnDNSSymptoms
2025-02-04 14:16:31.220001+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: (IO80211) Apple80211SetWithIOCTL:11858 Processing APPLE80211_IOC_REASSOCIATE_WITH_CORECAPTURE
2025-02-04 14:16:31.387985+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: (IO80211) Apple80211SetWithIOCTL: Processed APPLE80211_IOC_REASSOCIATE_WITH_CORECAPTURE Ioctl error:0
WAEngine and DPSQuickRecoveryRecommendationEngine functionalities (?) play significant role in here recommending Reassociation
We can see that reassociation is being triggered because of DNS symptoms - why and where can I find them?
Recommendation for DNS Symptoms Recovery: Reassoc
Hi, I am working on a case in our organisation where hundreds if not a thousand wireless network clients are affected by regular, usually 30 sometimes 60 minute sometime they are unnoticeable but often people having meetings notice that a lot.
We excluded wireless network configuration issue since disconnections happens to clients both connected to Cisco and Ubiquiti Access Points.
WLC logs mostly show EAP timeout errors - clients are getting disauthenticated and authenticated back - usually without any action needed - but the meeting is being interrupted.
What I found in Macbook logs with sudo log show [options] is the main reason of network disconnection:
2025-02-04 14:16:31.219192+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine updateTimeSincePreviousTriggerForStudy:msgKey:dictKey:]::913:msgkey:WFAAWDWASDS_symptomsDnsTimeSincePreviousTriggerMinutes dictKey:dps_lastSymptomsDpsTrigger previous_TS:(null) current_TS:Tue Feb 4 14:16:31 2025 difference:0
2025-02-04 14:16:31.219704+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine updateScreenState]::198:DPS Fast Reset Recommendation Engine: (screenON & foreGrnd traffic) is DETECTED
2025-02-04 14:16:31.219713+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine recommendSymptomsDpsRecovery:symptomsDnsStats:awdlState:currentSymptomsCondition:isLANPingSuccessful:appUsage:averageCCA:]::966:PeerDiagnostics: Data not received from peerDiagnostics
2025-02-04 14:16:31.219714+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine checkForPriorityNetwork]::256:Priority Network Check Disabled: NO IsPriorityNetwork: YES
2025-02-04 14:16:31.219732+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine isResetAllowedForKey:forPrefSelector:]::330:key:symptomsDps_lastScreenOnRecoveryWD previousWD_TS:(null) currentWD_TS:Tue Feb 4 14:16:31 2025 recommendation:YES
2025-02-04 14:16:31.219735+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine updateSymptomsDPSRecoveryWDStatsForKey:]::210:Added key: symptomsDps_numRecommendedScreenOnRecoveryWD value:1 dict:(null)
2025-02-04 14:16:31.219737+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[DPSQuickRecoveryRecommendationEngine recommendSymptomsDpsRecovery:symptomsDnsStats:awdlState:currentSymptomsCondition:isLANPingSuccessful:appUsage:averageCCA:]::1023:PeerDiagnostics: Recommendation for DNS Symptoms Recovery: Reassoc
Do you guys have any idea where can I see that DNS symptoms?
I can also see some reading like:
2025-02-04 14:16:31.219169+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[WAEngine gatherConsecutiveDatapathReadings:forProcessToken:andReply:]_block_invoke::4235:DNS Symptoms pre-decision check:: Associated:YES Primary:YES isCaptive:NO isValidDnsConfig:YES
2025-02-04 14:16:31.219169+0100 0xc01342 Default 0x0 86459 0 wifianalyticsd: [com.apple.wifi.analytics:Default] -[WAEngine gatherConsecutiveDatapathReadings:forProcessToken:andReply:]_block_invoke::4238:SDNS: WiFi Not Primary - setting suppressedReason kSymptomsDnsWiFiInterfaceNotPrimary
WiFi Not Primary - how if this is my only interface? - I removed all other
Killing and disabling wifianalyticsd does not help - the process is being spawned by launchd on airportd request:
2025-02-04 08:54:11.903825+0100 0xb85274 Default 0x0 627 0 airportd: (WiFiAnalytics) [com.apple.wifi.analytics:Default] -[WAClient _establishDaemonConnection]_block_invoke::1057:XPC: establishing connection to daemon with token ending in: <private>...
2025-02-04 08:54:11.907779+0100 0xb8504a Default 0x0 627 0 airportd: (IO80211) [com.apple.WiFiManager:] Info: <airport[627]> -[dpsManager submitDpsSymptom:isCriticalApp:]_block_invoke:
2025-02-04 08:54:11.907943+0100 0xb8504a Default 0x0 627 0 airportd: (IO80211) -[dpsManager submitDpsSymptom:isCriticalApp:]_block_invoke: Error preparing DPSNotification for submission: Error Domain=com.apple.wifi.analytics.errordomain Code=9014 "WAErrorCodeDaemonContactTimeout" UserInfo={NSLocalizedFailureReason=WAErrorCodeDaemonContactTimeout}, or null WAMessageAWD
2025-02-04 08:54:11.908055+0100 0xb8504a Default 0x0 627 0 airportd: (IO80211) [com.apple.WiFiManager:] <airport[627]> -[dpsManager submitDpsSymptom:isCriticalApp:]_block_invoke: Error preparing DPSNotification for submission: Error Domain=com.apple.wifi.analytics.errordomain Code=9014 "WAErrorCodeDaemonContactTimeout" UserInfo={NSLocalizedFailureReason=WAErrorCodeDaemonContactTimeout}, or null WAMessageAWD
2025-02-04 08:54:11.910453+0100 0xb85274 Default 0x0 627 0 airportd: (libxpc.dylib) [com.apple.xpc:connection] [0x80fe64640] activating connection: mach=true listener=false peer=false name=com.apple.wifianalyticsd
2025-02-04 08:54:11.911105+0100 0xb85382 Default 0x0 1 0 launchd: [system/com.apple.wifianalyticsd:] internal event: WILL_SPAWN, code = 0
2025-02-04 08:54:11.911229+0100 0xb85382 Default 0x0 1 0 launchd: [system/com.apple.wifianalyticsd:] service state: spawn scheduled
2025-02-04 08:54:11.911233+0100 0xb85382 Default 0x0 1 0 launchd: [system/com.apple.wifianalyticsd:] service state: spawning
2025-02-04 08:54:11.911384+0100 0xb85382 Default 0x0 1 0 launchd: [system/com.apple.wifianalyticsd:] launching: ipc (mach)
2025-02-04 08:54:11.920272+0100 0xb85382 Default 0x0 1 0 launchd: [system/com.apple.wifianalyticsd [86459]:] xpcproxy spawned with pid 86459
Do you guys have any idea what is the cause of this behaviour?
Or how to disable wifianalyticsd process for good?
Topic:
App & System Services
SubTopic:
Networking
I am currently developing a custom-protocol VPN application for iOS using PacketTunnelProvider. I have also integrated an HTTP proxy service, which is launched via a dylib.
The overall flow is as follows:
App -> VPN TUN -> Local HTTP Proxy -> External Network
I have a question:
I am capturing all traffic, and normally, requests sent out by the HTTP proxy are also captured again by the VPN. However, when I send requests using createUdpSession in my code, they are not being captured by the virtual interface (TUN).
What could be the reason for this?
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
let tunnelNetworkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "192.168.18.0")
tunnelNetworkSettings.mtu=1400
let ipv4Settings = NEIPv4Settings(addresses: ["192.169.10.10"], subnetMasks: ["255.255.255.0"])
ipv4Settings.includedRoutes=[NEIPv4Route.default()]
ipv4Settings.excludedRoutes = [NEIPv4Route(destinationAddress: "10.0.0.0", subnetMask: "255.0.0.0"),
NEIPv4Route(destinationAddress: "172.16.0.0", subnetMask: "255.240.0.0"),
NEIPv4Route(destinationAddress: "192.168.0.0", subnetMask: "255.255.0.0"),
NEIPv4Route(destinationAddress:"127.0.0.0", subnetMask: "255.0.0.0"),
]
tunnelNetworkSettings.ipv4Settings = ipv4Settings
// Configure proxy settings
let proxySettings = NEProxySettings()
proxySettings.httpEnabled = true
proxySettings.httpServer = NEProxyServer(address: "127.0.0.1", port: 7890)
proxySettings.httpsEnabled = true
proxySettings.httpsServer = NEProxyServer(address: "127.0.0.1", port: 7890)
proxySettings.excludeSimpleHostnames = true
proxySettings.exceptionList=["localhost","127.0.0.1"]
tunnelNetworkSettings.proxySettings = proxySettings
setTunnelNetworkSettings(tunnelNetworkSettings) { [weak self] error in
if error != nil {
completionHandler(error)
return
}
completionHandler(nil)
let stack = TUNInterface(packetFlow: self!.packetFlow)
RawScoketFactory.TunnelProvider=self
stack.register(stack: UDPDirectStack())
stack.register(stack: TCPDirectStack())
stack.start()
}
}
NWUdpSession.swift
//
// NWUDPSocket.swift
// supervpn
//
// Created by TobbyQuinn on 2025/2/3.
//
import Foundation
import NetworkExtension
import CocoaLumberjack
public protocol NWUDPSocketDelegate: AnyObject{
func didReceive(data:Data,from:NWUDPSocket)
func didCancel(socket:NWUDPSocket)
}
public class NWUDPSocket:NSObject{
private let session:NWUDPSession
private let timeout:Int
private var pendingWriteData: [Data] = []
private var writing = false
private let queue:DispatchQueue=QueueFactory.getQueue()
public weak var delegate:NWUDPSocketDelegate?
public init?(host:String,port:UInt16,timeout:Int=Opt.UDPSocketActiveTimeout){
guard let udpSession = RawScoketFactory.TunnelProvider?.createUDPSession(to: NWHostEndpoint(hostname: host, port: "\(port)"), from: nil) else{
return nil
}
session = udpSession
self.timeout=timeout
super.init()
session.addObserver(self, forKeyPath: #keyPath(NWUDPSession.state),options: [.new], context: nil)
session.setReadHandler({ dataArray, error in
self.queueCall{
guard error == nil, let dataArray = dataArray else {
print("Error when reading from remote server or connection reset")
return
}
for data in dataArray{
self.delegate?.didReceive(data: data, from: self)
}
}
}, maxDatagrams: 32)
}
/**
Send data to remote.
- parameter data: The data to send.
*/
public func write(data: Data) {
pendingWriteData.append(data)
checkWrite()
}
public func disconnect() {
session.cancel()
}
public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard keyPath == "state" else {
return
}
switch session.state {
case .cancelled:
queueCall {
self.delegate?.didCancel(socket: self)
}
case .ready:
checkWrite()
default:
break
}
}
private func checkWrite() {
guard session.state == .ready else {
return
}
guard !writing else {
return
}
guard pendingWriteData.count > 0 else {
return
}
writing = true
session.writeMultipleDatagrams(self.pendingWriteData) {_ in
self.queueCall {
self.writing = false
self.checkWrite()
}
}
self.pendingWriteData.removeAll(keepingCapacity: true)
}
private func queueCall(block:@escaping ()->Void){
queue.async {
block()
}
}
deinit{
session.removeObserver(self, forKeyPath: #keyPath(NWUDPSession.state))
}
}
Crashed: com.apple.libcache.memorypressure
0 libsystem_platform.dylib 0x4ce4 _os_unfair_lock_recursive_abort + 36
1 libsystem_platform.dylib 0x1e1c _os_unfair_lock_lock_slow + 308
2 libcache.dylib 0x3a50 cache_remove_all + 56
3 CoreFoundation 0xd8d18 -[NSCache dealloc] + 84
4 Photos 0x505e4 -[PHSafeNSCacheDelegateReflector cache:willEvictObject:] + 216
5 CoreFoundation 0xbe524 __NSCacheCallDelegateWillEvictObjectCallbackWithValue + 76
6 CoreFoundation 0xbe43c __NSCacheValueRelease + 104
7 libcache.dylib 0x3998 _value_entry_remove + 120
8 libcache.dylib 0x3898 _entry_evict + 188
9 libcache.dylib 0x37c8 _evict_last + 108
10 libcache.dylib 0x3108 _cache_enforce_limits + 104
11 libcache.dylib 0x16f4 ___cache_handle_memory_pressure_event_block_invoke + 92
12 libdispatch.dylib 0x13394 _dispatch_block_async_invoke2 + 148
13 libdispatch.dylib 0x3fa8 _dispatch_client_callout + 20
14 libdispatch.dylib 0xd76c _dispatch_workloop_invoke + 2172
15 libdispatch.dylib 0x1738c _dispatch_root_queue_drain_deferred_wlh + 288
16 libdispatch.dylib 0x16bd8 _dispatch_workloop_worker_thread + 540
17 libsystem_pthread.dylib 0x3680 _pthread_wqthread + 288
18 libsystem_pthread.dylib 0x1474 start_wqthread + 8
Topic:
App & System Services
SubTopic:
Core OS
Hi all,
Our company has an application that runs on several machines, this app is launched via a deamon that keeps it alive.
One of the feature of this app, is to start a headless electron application to run some tests. When spawning this electron application with the new arm64 OS, we are getting this issue:
Silent Test Agent Worker exited with code: 133
[ERROR] [75873:0205/135842.347044:ERROR:mach_port_rendezvous.cc(384)] bootstrap_look_up com.hivestreaming.silenttestagent.MachPortRendezvousServer.1: Permission denied (1100)
[ERROR] [75873:0205/135842.347417:ERROR:shared_memory_switch.cc(237)] No rendezvous client, terminating process (parent died?)
[ERROR] [75872:0205/135842.347634:ERROR:mach_port_rendezvous.cc(384)] bootstrap_look_up com.hivestreaming.silenttestagent.MachPortRendezvousServer.1: Permission denied (1100)
[ERROR] [75872:0205/135842.347976:ERROR:shared_memory_switch.cc(237)] No rendezvous client, terminating process (parent died?)
Both application (main app and electron one) are signed and notarized, but it seems that there is some other permission issue.
If we run the electron application manually, all runs as expected.
I added the crash report as attachment
CrashReport.log
I have a home widget with buttons (new in iOS 17).
In order to prevent taking action if the user taps on the widget buttons accidentally, I want to ask the user for confirmation.
It appeared that requestConfirmation be exactly what I needed, but no confirmation view shows up when I invoke this method in the perform function.
I have tried the following:
try await requestConfirmation(result: .result(dialog: "Are you sure you want to do this?") {
Image(.mdlsWhite)
})
and this alternative:
let confirmed: Bool = try await $name.requestConfirmation(for: self.name,
dialog: IntentDialog(stringLiteral: msg))
Neither option work.
I am starting to think that the requestConfirmation is not to be used with Home Widgets.
Is there a better way to handle confirmations for buttons included in a Home Widget?
Hi, I'm developer in fintech company, we have setup process for onboarding merchants for our partner and processing payments with usage of Apple Pay API. Daily system is processing ca. 10k payments but every day ca. 100 of transactions are declined because of merchant validation error:
request to https://apple-pay-gateway.apple.com/paymentservices/paymentSession (with all required parameters in body)
is returning response with status code 417
"statusMessage": "Payment Services Exception
merchantId={root merchant id}
unauthorized to process transactions on behalf of
merchantId={merchant id hash}
reason={merchant id hash} is
not a registered merchant in WWDR and isn't properly authorized via Mass
Enablement, either."
Issue impacts recurring merchants, most of their transactions are processed successfully but randomly some of them are failing with such reason. All prerequisites are met: merchant have deployed 'apple-developer-merchantid-domain-association' certificate, certificates are valid and not expired. Apple Support is not able to provide any information based on provided requests timestamps. We would to know what may be the reason just part of the requests are failing and what 417 error code means.
Topic:
App & System Services
SubTopic:
Apple Pay
Hello Everyone,
I have some questions regarding the Apple notification alert update received in October 2024 for the APNs server certificate update.
We are using Azure Notification Hub to receive push notifications. I confirmed with the Azure team, and they have already implemented the required changes. However, push notifications are still not working in the sandbox environment.
Could you please provide any insights on this?
Thanks.
Hello,
I am working on application which licenses depends on number of user sessions which logged in.
The problem is the application "Migration Assistant" creates new session for "Setup User" and it leads to licenses leak.
# cat /etc/passwd | grep Setup
_mbsetupuser:*:248:248:Setup User:/var/setup:/bin/bash
Are there any difference between _mbsetupuser and users which is created by administrator via "System Settings" or dscl?
(e.g. specific user id range which using is restricted by system).
Are there any way to detect _mbsetupuser and be sure this user is predefined during system install?
Thank you in advance,
Pavel
Topic:
App & System Services
SubTopic:
Core OS
Is there a way to distinguish physical mouse/keyboard input from remote control mouse/keyboard input on Mac? Or even better, is there a way to detect if my Mac is being remotely controlled?
I have a strange situation and I'm not sure where else to post this. Our app's domain (or at least its API hostname in the domain) resolves to something different only inside of Apple's network.
I was able to get an Apple employee to verify this by resolving the API hostname while on Apple's corporate network and it resolves to an IP that is in Apple's 17.0.0.0/8 network, but everywhere else resolves to the normal IPs. Our domain's DNS is provided by Cloudflare and they are not doing anything special for Apple's network.
This is causing problems during App Review because the app is trying to reach our API to log in and instead is being routed to an IP in Apple's network, so it fails SSL validation and presents an error dialog. App Review is then claiming our app doesn't work and rejecting it. This is an app that has been in the App Store for over a decade and gone through countless app reviews.
App Review was of no help resolving this and I don't know where else to turn. How can I find out why our domain is being rerouted inside of Apple and get this fixed?
Topic:
App & System Services
SubTopic:
Health & Fitness