Team-scoped keys introduce the ability to restrict your token authentication keys to either development or production environments. Topic-specific keys in addition to environment isolation allow you to associate each key with a specific Bundle ID streamlining key management.
For detailed instructions on accessing these features, read our updated documentation on establishing a token-based connection to APNs.
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
Im having trouble enabling Live Activities in a new app. The option is not available in Xcode or in the developer portal. Is there something I have to do to activate this option?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Just wanted to clarify some expected behaviors here. It seems that there are two distinct behaviors for Live Activity flows for freshly installed apps.
When you start a Live Activity for the first time and the user hasn't yet clicked on Allow/Don't Allow in the activity interface, there are two different sequences:
Starting a Live Activity locally
Request a Live Activity locally via Swift
Live Activity starts
.pushTokenUpdates is immediately triggered, even if the Allow/Don't Allow buttons appear under the Activity UI
Starting a Live Activity via push-to-start
Send a push-to-start notification to launch a Live Activity
Live Activity starts
.pushTokenUpdates is not triggered, and .pushToken returns nil.
If a user clicks on Allow in the Activity UI, only then is .pushTokenUpdates triggered.
We use call directory extension in one of our applications, we notice that call id is truncated on IOS 18.
Example: "Grady GmbH" instead of "GRADY ARCHIE,
PRICEWATERHOUSECOOPER GMBH"
We notice also if we have calls in the history then the caller id is shown correctly.
Issue only on IOS 18.
Topic:
App & System Services
SubTopic:
General
Is it allowed to use an os_activity_t instance created with os_activity_create from multiple threads?
In particular, would it be allowed to use os_activity_apply/os_activity_scope concurrently from multiple threads to associate separate chunks of work with the same activity?
My use case is an activity where I'm using Task.detached to create a detached unstructured Task, which (as can be expected) prevents inheritance of the current activity.
The bulk of the activity happens in the detached Task so I can just create the activity there but ideally I would like to also associate some of the setup work before spawning the Task with the same activity.
So I'm wondering if it is safe to create the activity, apply it to the setup including spawning the detached Task and then capture and apply the same activity inside the Task as well where it might be applied concurrently with the first use on the thread spawning the Task.
According to the documentation, using Scope(restriction: .none) can expose the extension point to third-party app extensions. Below is my implementation, which ultimately results in an error.
Code for declaring the extension point:
@available(iOS 26.0, *)
extension AppExtensionPoint {
@Definition
static var priceExtension: AppExtensionPoint {
Name("priceExtension")
UserInterface(false)
Scope(restriction: .none)
}
}
Code for locating the extension point:
monitor = try await AppExtensionPoint.Monitor(appExtensionPoint: .priceExtension)
When executing the code to locate the extension point, the following error occurs:
However, in practice, I found that declaring the extension point in this way results in an error when trying to locate it:
Error Domain=com.apple.extensionKit.errorDomain Code=19 "Failed to add observer" UserInfo={NSLocalizedDescription=Failed to add observer}
Hello,
We use the Network API in our macOS ObjectiveC applications to create a small web server. With macOS Sequoia or Tahoe (not with Sonoma), downloading files from another computer using the built-in ethernet port is way too slow.
Steps to reproduce:
Computer A (using macOS Tahoe or Sonoma), run an application using the Network APIs to create a webserver
Make sure that this computer connects to the network using the Ethernet port, there is no issue when using WiFi
On computer B, make an HTTP request to download a 20MB file => it will take about 30 seconds to download => way too slow...
We tested with:
if on computer A you run a web server using the GCD API instead of Network, it takes 0.2 seconds to download the file => no issue
on computer A disable TSO, it improves the results, but that's not a long term solution as it doesn't hold when rebooting
I can provide sample code to demonstrate this if needed.
This is a new issue as it's been a while we use that code, and only noticed it recently, and macOS Sonoma is not impacted.
Thank you for the help you can provide.
Pierre
~5% of our users when downloading the iOS application from the Apple Store for the first time are unable to enrol a Passkey and experience an error saying the application is not associated with [DOMAIN].
The error message thrown by the iOS credentials API is
"The operation couldn't be completed. Application with identifier [APPID] is not associated with domain [DOMAIN]"
We have raised this via the developer support portal with case id: 102315543678
Question:
Why does the AASA file fail to fetch on app install and is there anything that can be done to force the app to fetch the file?
Can this bug be looked at urgently as it is impacting security critical functionality?
Other Debugging Observations
We have confirmed that our AASA file is correctly formatted and hosted on the Apple CDN. Under normal circumstances the association is created on install and Passkey enrolment works as intended.
We have observed that when customers uninstall/reinstall the app this often, but not always, resolves the issue. We also know this issue can resolve itself overtime without any intervention.
We have ruled out network (e.g VPN) issues and have reproduced the issue across a number of different network configurations.
We have ruled out the Keychain provider and have reproduced it across a variety of different providers and combinations of.
We observed this across multiple versions of the iOS operating system and iPhone hardware including the latest hardware and iOS version.
I have an app that connect to specific wifi but the macos always save password while i do not want user to remember the password. Anyway to stop or work around on it?
Hello everyone,
We are migrating our KEXT for a Thunderbolt storage device to a DEXT based on IOUserSCSIParallelInterfaceController.
We've run into a fundamental issue where the driver's behavior splits based on the I/O source: high-level I/O from the file system (e.g., Finder, cp) is mostly functional (with a minor ls -al sorting issue for Traditional Chinese filenames), while low-level I/O directly to the block device (e.g., diskutil) fails or acts unreliably. Basic read/write with dd appears to be mostly functional.
We suspect that our DEXT is failing to correctly register its full device "personality" with the I/O Kit framework, unlike its KEXT counterpart. As a result, low-level I/O requests with special attributes (like cache synchronization) sent by diskutil are not being handled correctly by the IOUserSCSIParallelInterfaceController framework of our DEXT.
Actions Performed & Relevant Logs
1. Discrepancy: diskutil info Shows Different Device Identities for DEXT vs. KEXT
For the exact same hardware, the KEXT and DEXT are identified by the system as two different protocols.
KEXT Environment:
Device Identifier: disk5
Protocol: Fibre Channel Interface
...
Disk Size: 66.0 TB
Device Block Size: 512 Bytes
DEXT Environment:
Device Identifier: disk5
Protocol: SCSI
SCSI Domain ID: 2
SCSI Target ID: 0
...
Disk Size: 66.0 TB
Device Block Size: 512 Bytes
2. Divergent I/O Behavior: Partial Success with Finder/cp vs. Failure with diskutil
High-Level I/O (Partially Successful):
In the DEXT environment, if we operate on an existing volume (e.g., /Volumes/GammaCarry), file copy operations using Finder or cp succeed. Furthermore, the logs we've placed in our single I/O entry point, UserProcessParallelTask_Impl, are triggered.
Side Effect: However, running ls -al on such a volume shows an incorrect sorting order for files with Traditional Chinese names (they appear before . and ..).
Low-Level I/O (Contradictory Behavior):
In the DEXT environment, when we operate directly on the raw block device (/dev/disk5):
diskutil partitionDisk ... -> Fails 100% of the time with the error: Error: -69825: Wiping volume data to prevent future accidental probing failed.
dd command -> Basic read/write operations appear to work correctly (a write can be immediately followed by a read within the same DEXT session, and the data is correct).
3. Evidence of Cache Synchronization Failure (Non-deterministic Behavior)
The success of the dd command is not deterministic. Cross-environment tests prove that its write operations are unreliable:
First Test:
In the DEXT environment, write a file with random data to /dev/disk5 using dd.
Reboot into the KEXT environment.
Read the data back from /dev/disk5 using dd. The result is a file filled with all zeros.
Conclusion: The write operation only went to the hardware cache, and the data was lost upon reboot.
Second Test:
In the DEXT environment, write the same random file to /dev/disk5 using dd.
Key Variable: Immediately after, still within the DEXT environment, read the data back once for verification. The content is correct!
Reboot into the KEXT environment.
Read the data back from /dev/disk5. This time, the content is correct!
Conclusion: The additional read operation in the second test unintentionally triggered a hardware cache flush. This proves that the dd (in our DEXT) write operation by itself does not guarantee synchronization, making its behavior unreliable.
Our Problem
Based on the observations above, we have the conclusion:
High-Level Path (triggered by Finder/cp):
When an I/O request originates from the high-level file system, the framework seems to enter a fully-featured mode. In this mode, all SCSI commands, including READ/WRITE, INQUIRY, and SYNCHRONIZE CACHE, are correctly packaged and dispatched to our UserProcessParallelTask_Impl entry point. Therefore, Finder operations are mostly functional.
Low-Level Path (triggered by dd/diskutil):
When an I/O request originates from the low-level raw block device layer:
The most basic READ/WRITE commands can be dispatched (which is why dd appears to work).
However, critical management commands, such as INQUIRY and SYNCHRONIZE CACHE, are not being correctly dispatched or handled. This leads to the incorrect device identification in diskutil info and the failure of diskutil partitionDisk due to its inability to confirm cache synchronization.
We would greatly appreciate any guidance, suggestions, or insights on how to resolve this discrepancy. Specifically, what is the recommended approach within DriverKit to ensure that a DEXT based on IOUserSCSIParallelInterfaceController can properly declare its capabilities and handle both high-level and low-level I/O requests uniformly?
Thank you.
Charles
My team has an app that uses BTLE heavily, and has been doing so successfully, including no issues continuing to receive data in the background and updating things in the app (for recording workouts).
We have a BTLE write queue that only tries to write when the CBPeripheral.canSendWriteWithoutResponse property is true, or when we get the notification from the system in peripheralIsReady(toSendWriteWithoutResponse:). This is used as a means to rate limit data transfer, as we transfer files, as well as require that packets always arrive in the correct order due to blob encoding.
However, we had a new requirement come in to periodically write data out to a connected peripheral. I noticed that as soon as the app was in the background, despite other delegate callbacks coming in, like didRecieveUpdatedValue:, neither the property canSendWriteWithoutResponse nor the delegate callback were called any longer. This meant our write queue didn't think it had permission to write, and packets would just stack up. The failure to deliver these updates didn't occur immediately after backgrounding, but did within 2-5s of backgrounding.
If, when in the background, I ignore the changing of that property, and instead just write the data to the peripheral, it works!
Can anyone explain why, despite other CBPeripheral callbacks happening when in the background, this one does not?
Hi, I'm new to swift programming and right now writing an app for esp8266-controlled lamp device. My lamp is broadcasting it's own IP through bonjour. So all I want is to discover any lamps in my network (http.tcp) and to read name and value. Is there any example of such implementation? All I found so far is old or a lit bit complicated for such simple question. Thanks in advance!
Hello everyone
I need to present a password to a ST25DV ISO15693 device. From the ST microelectronics datasheet I use the command 0xB3 With customcommandwithrequestflag method with the FLAGs High data rate and Address mode. I have trouble to get it working I receive error code 2 each time I sent the password. The password is composed with int8 area passwor + 8 int8 password. I'd like to know how the customcommand 0xB3 works.
Topic:
App & System Services
SubTopic:
Core OS
Hi There, hopefully someone can help me here, we weren’t aware but our universal links stopped working sometime last year, as they are not used often on the apps, it wasn’t noticed. We checked all the elements and this is the situation:
Our apple-app-site-association file is located at
https://ourdomain.com.au/.well-known/apple-app-site-association
And it is accessible and can be downloaded.
We have Associated Domain services enabled for our app Bundle Id: au.com.identifier.app
The Entitlements.plist in our app contains the list of associated domains - the second is the full url, the portal won't let me write it as such as it's not the real address.
But links for the first two, …ourdomain.com.au domains don’t work
Request https://ourdomain.com.au/.well-known/apple-app-site-association downloads the file and returns status code:403
While checking the availability with
https://app-site-association.cdn-apple.com/a/v1/ourdomain.com.au
we get the error:
ourdomain.com.au: Failed to load resource: the server responded with a status of 404 (Not Found)
Going directly to the hosted website:
https://app-site-association.cdn-apple.com/a/v1/ourdomain-prod-ourdomainwebsite.azurewebsites.net
Returns the json:
{
"activitycontinuation": {
"apps": [
"99ABCD88XXX.au.com.identifier.app",
"99ABCD88XXX.au.com.identifier.server.adhoc",
"99ABCD88XXX.au.com.identifier.server.dev"
]
},
"applinks": {
"apps": [],
"details": [
{
"appID": "99ABCD88XXX.au.com.identifier.app",
"paths": [ "/m/" ]
},
{
"appID": "99ABCD88XXX.au.com.identifier.server.adhoc",
"paths": [ "/mt/" ]
},
{
"appID": "99ABCD88XXX.au.com.identifier.server.dev",
"paths": [ "/md/*" ]
}
]
}
}
It appears to be something in the redirect from the url but debugging shows nothing obvious. Has anyone experienced this before?
Thanks
Topic:
App & System Services
SubTopic:
General
iphone 15 pro max
ios 26
Stuck at the developer mode startup interface and unable to swipe up.
I'm testing my app before releasing to testers, and my app (both macOS and iOS) is crashing when I perform one operation, but only in the production build.
I have data that loads from a remote source, and can be periodically updated. There is an option to delete all of that data from the iCloud data store, unless the user has modified a record. Each table has a flag to indicate that (userEdited). Here's the function that is crashing:
func deleteCommonData<T:PersistentModel & SDBuddyModel>(_ type: T.Type) throws {
try modelContext.delete(model: T.self, where: #Predicate<T> { !$0.userEdited })
}
Here's one of the calls that results in a crash:
try modelManager.deleteCommonData(Link.self)
Here's the error from iOS Console:
SwiftData/DataUtilities.swift:85: Fatal error: Couldn't find \Link.<computed 0x0000000104b9d208 (Bool)> on Link with fields [SwiftData.Schema.PropertyMetadata(name: "id", keypath: \Link.<computed 0x0000000104b09b44 (String)>, defaultValue: Optional("54EC6602-CA7C-4EC7-AC06-16E7F2E22DE7"), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "name", keypath: \Link.<computed 0x0000000104b09b84 (String)>, defaultValue: Optional(""), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "url", keypath: \Link.<computed 0x0000000104b09bc4 (String)>, defaultValue: Optional(""), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "desc", keypath: \Link.<computed 0x0000000104b09c04 (String)>, defaultValue: Optional(""), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "userEdited", keypath: \Link.<computed 0x0000000104b09664 (Bool)>, defaultValue: Optional(false), metadata: nil), SwiftData.Schema.PropertyMetadata(name: "modified", keypath: \Link.<computed 0x0000000104b09c44 (Date)>, defaultVal<…>
Here's a fragment of the crash log:
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000019373222c
Termination Reason: Namespace SIGNAL, Code 5, Trace/BPT trap: 5
Terminating Process: exc handler [80543]
Thread 0 Crashed:
0 libswiftCore.dylib 0x19373222c _assertionFailure(_:_:file:line:flags:) + 176
1 SwiftData 0x22a222160 0x22a1ad000 + 479584
2 SwiftData 0x22a2709c0 0x22a1ad000 + 801216
3 SwiftData 0x22a221b08 0x22a1ad000 + 477960
4 SwiftData 0x22a27b0ec 0x22a1ad000 + 844012
5 SwiftData 0x22a27b084 0x22a1ad000 + 843908
6 SwiftData 0x22a28182c 0x22a1ad000 + 870444
7 SwiftData 0x22a2809e8 0x22a1ad000 + 866792
8 SwiftData 0x22a285204 0x22a1ad000 + 885252
9 SwiftData 0x22a281c7c 0x22a1ad000 + 871548
10 SwiftData 0x22a27cf6c 0x22a1ad000 + 851820
11 SwiftData 0x22a27cc48 0x22a1ad000 + 851016
12 SwiftData 0x22a27a6b0 0x22a1ad000 + 841392
13 SwiftData 0x22a285b2c 0x22a1ad000 + 887596
14 SwiftData 0x22a285a10 0x22a1ad000 + 887312
15 SwiftData 0x22a285bcc 0x22a1ad000 + 887756
16 SwiftData 0x22a27cf6c 0x22a1ad000 + 851820
17 SwiftData 0x22a27cc48 0x22a1ad000 + 851016
18 SwiftData 0x22a27a6b0 0x22a1ad000 + 841392
19 SwiftData 0x22a27c0d8 0x22a1ad000 + 848088
20 SwiftData 0x22a27a654 0x22a1ad000 + 841300
21 SwiftData 0x22a1be548 0x22a1ad000 + 70984
22 SwiftData 0x22a1cfd64 0x22a1ad000 + 142692
23 SwiftData 0x22a1b9618 0x22a1ad000 + 50712
24 SwiftData 0x22a1d2e8c 0x22a1ad000 + 155276
25 CoreData 0x187fbb568 thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 28
26 CoreData 0x187fc2300 partial apply for thunk for @callee_guaranteed () -> (@out A, @error @owned Error) + 24
27 CoreData 0x187fc19c4 closure #1 in closure #1 in NSManagedObjectContext._rethrowsHelper_performAndWait<A>(fn:execute:rescue:) + 192
28 CoreData 0x187fbbda8 thunk for @callee_guaranteed @Sendable () -> () + 28
29 CoreData 0x187fbbdd0 thunk for @escaping @callee_guaranteed @Sendable () -> () + 28
30 CoreData 0x187f663fc developerSubmittedBlockToNSManagedObjectContextPerform + 252
31 libdispatch.dylib 0x180336ac4 _dispatch_client_callout + 16
32 libdispatch.dylib 0x18032c940 _dispatch_lane_barrier_sync_invoke_and_complete + 56
33 CoreData 0x187fd7290 -[NSManagedObjectContext performBlockAndWait:] + 364
34 CoreData 0x187fc1fb8 NSManagedObjectContext.performAndWait<A>(_:) + 544
35 SwiftData 0x22a1b877c 0x22a1ad000 + 46972
36 SwiftData 0x22a1be2a8 0x22a1ad000 + 70312
37 SwiftData 0x22a1c0e34 0x22a1ad000 + 81460
38 SwiftData 0x22a23ea94 0x22a1ad000 + 596628
39 SwiftData 0x22a256828 0x22a1ad000 + 694312
40 Sourdough Buddy 0x104e5dc98 specialized ModelManager.deleteCommonData<A>(_:) + 144 (ModelManager.swift:128) [inlined]
41 Sourdough Buddy 0x104e5dc98 closure #1 in SettingsView.clearStarterData.getter + 876 (SettingsView.swift:243)
It works if I do the following instead:
try modelContext.delete(model: Link.self, where: #Predicate { !$0.userEdited })
Why would the func call work in development, but crash in production? And why does doing the more verbose way work instead?
I think this is a bug.
Thanks
Hello.
How to write this command correctly on a Macbook, in the script editor, so that I can click the "Run script" button and the script will give the result:
if there is no folder, then report that there is no folder,
if there is a folder, then report that the folder exists.
do shell script "test -d 'Users/user/Desktop/New folder'"
Now, if the folder exists, an empty string ("") is returned, if the folder does not exist, the script editor reports that an error has occurred.
In general, my task is to write a script that checks the existence of a folder.
On iOS 26, calling CXCallDirectoryManager.sharedInstance.openSettings() does not navigate to the “Call Blocking & Identification” settings page as documented. Instead, it either opens the main Phone settings page or fails to navigate entirely. This breaks the expected behavior for enabling Call Directory extensions and impacts onboarding flows for apps using CallKit.
Expected:
Settings should open directly to Phone → Call Blocking & Identification.
Actual:
Navigates to the main Phone settings page
This appears to be a regression from previous iOS versions. Documentation still states this API should open the correct page.
I've adopted the new BGContinuedProcessingTask in iOS 26, and it has mostly been working well in internal testing. However, in production I'm getting reports of the tasks failing when the app is put into the background.
A bit of info on what I'm doing: I need to download a large amount of data (around 250 files) and process these files as they come down. The size of the files can vary: for some tasks each file might be around 10MB. For other tasks, the files might be 40MB. The processing is relatively lightweight, but the volume of data means the task can potentially take over an hour on slower internet connections (up to 10GB of data).
I set the totalUnitCount based on the number of files to be downloaded, and I increment completedUnitCount each time a file is completed.
After some experimentation, I've found that smaller tasks (e.g. 3GB, 10MB per file) seem to be okay, but larger tasks (e.g. 10GB, 40MB per file) seem to fail, usually just a few seconds after the task is backgrounded (and without even opening any other apps). I think I've even observed a case where the task expired while the app was foregrounded!
I'm trying to understand what the rules are with BGContinuedProcessingTask and I can see at least four possibilities that might be relevant:
Is it necessary to provide progress updates at some minimum rate? For my larger tasks, where each file is ~40MB, there might be 20 or 30 seconds between progress updates. Does this make it more likely that the task will be expired?
For larger tasks, the total time to complete can be 60–90 mins on slower internet connections. Is there some maximum amount of time the task can run for? Does the system attempt some kind of estimate of the overall time to complete and expire the task on that basis?
The processing on each file is relatively lightweight, so most of the time the async stream is awaiting the next file to come down. Does the OS monitor the intensity of workload and suspend the task if it appears to be idle?
I've noticed that the task UI sometimes displays a message, something along the lines of "Do you want to continue this task?" with a "Continue" and "Stop" option. What happens if the user simply ignores or doesn't see this message? Even if I tap "Continue" the task still seems to fail sometimes.
I've read the docs and watched the WWDC video, but there's not a whole lot of information on the specific issues I mention above. It would be great to get some clarity on this, and I'd also appreciate any advice on alternative ways I could approach my specific use case.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
I am seeking assistance with how to properly handle / save / reuse NWConnections when it comes to the NWBrowser vs NWListener.
Let me give some context surrounding why I am trying to do what I am.
I am building an iOS app that has peer to peer functionality. The design is for a user (for our example the user is Bob) to have N number of devices that have my app installed on it. All these devices are near each other or on the same wifi network. As such I want all the devices to be able to discover each other and automatically connect to each other. For example if Bob had three devices (A, B, C) then A discovers B and C and has a connection to each, B discovers B and C and has a connection to each and finally C discovers A and B and has a connection to each.
In the app there is a concept of a leader and a follower. A leader device issues commands to the follower devices. A follower device just waits for commands. For our example device A is the leader and devices B and C are followers. Any follower device can opt to become a leader. So if Bob taps the “become leader” button on device B - device B sends out a message to all the devices it’s connected to telling them it is becoming the new leader. Device B doesn’t need to do anything but device A needs to set itself as a follower. This detail is to show my need to have everyone connected to everyone.
Please note that I am using .includePeerToPeer = true in my NWParameters. I am using http/3 and QUIC. I am using P12 identity for TLS1.3. I am successfully able to verify certs in sec_protocal_options_set_verify_block. I am able to establish connections - both from the NWBrowser and from NWListener. My issue is that it’s flaky. I found that I have to put a 3 second delay prior to establishing a connection to a peer found by the NWBrowser. I also opted to not save the incoming connection from NWListener. I only save the connection I created from the peer I found in NWBrowser. For this example there is Device X and Device Y. Device X discovers device Y and connects to it and saves the connection. Device Y discovers device X and connects to it and saves the connection. When things work they work great - I am able to send messages back and forth. Device X uses the saved connection to send a message to device Y and device Y uses the saved connection to send a message to device X.
Now here come the questions.
Do I save the connection I create from the peer I discovered from the NWBrowser?
Do I save the connection I get from my NWListener via newConnectionHandler?
And when I save a connection (be it from NWBrowser or NWListener) am I able to reuse it to send data over (ie “i am the new leader command”)?
When my NWBrowser discovers a peer, should I be able to build a connection and connect to it immediately?
I know if I save the connection I create from the peer I discover I am able to send messages with it. I know if I save the connection from NWListener - I am NOT able to send messages with it — but should I be able to?
I have a deterministic algorithm for who makes a connection to who. Each device has an ID - it is a UUID I generate when the app loads - I store it in UserDefaults and the next time I try and fetch it so I’m not generating new UUIDs all the time. I set this deviceID as the name of the NWListener.Service I create. As a result the peer a NWBrowser discovers has the deviceID set as its name. Due to this the NWBrowser is able to determine if it should try and connect to the peer or if it should not because the discovered peer is going to try and connect to it.
So the algorithm above would be great if I could save and use the connection from NWListener to send messages over.
Are the Wifi-Aware's WAEndpoint's discovered ephemeral? I'm trying to understand what's the best way to reconnect a disconnected WifiAware connection - Can I just cache the endpoint and start a new connection with the same endpoint or do I need to browse again and get a new WAEndpoint?
My use case requires both WifiAware connection to another device and the devices also need to be connected to infrastructure wifi most of the time. I'm concerned about the WifiAware's connection having any impact on infrastructure wifi. What is the impact on the infrastructure wifi here in comparison to using the Apple peer to peer wifi(That Multipeer framework or Network framework use)?