General:
TN3151 Choosing the right networking API
Networking Overview document — Despite the fact that this is in the archive, this is still really useful.
TLS for App Developers DevForums post
Choosing a Network Debugging Tool documentation
WWDC 2019 Session 712 Advances in Networking, Part 1 — This explains the concept of constrained networking, which is Apple’s preferred solution to questions like How do I check whether I’m on Wi-Fi?
TN3135 Low-level networking on watchOS
Adapt to changing network conditions tech talk
Foundation networking:
DevForums tags: Foundation, CFNetwork
URL Loading System documentation — NSURLSession, or URLSession in Swift, is the recommended API for HTTP[S] on Apple platforms.
Network framework:
DevForums tag: Network
Network framework documentation — Network framework is the recommended API for TCP, UDP, and QUIC on Apple platforms.
Network Extension (including Wi-Fi on iOS):
See Network Extension Resources
Wi-Fi Fundamentals
Wi-Fi on macOS:
DevForums tag: Core WLAN
Core WLAN framework documentation
Wi-Fi Fundamentals
Secure networking:
DevForums tags: Security
Apple Platform Security support document
Preventing Insecure Network Connections documentation — This is all about App Transport Security (ATS).
Available trusted root certificates for Apple operating systems support article
Requirements for trusted certificates in iOS 13 and macOS 10.15 support article
About upcoming limits on trusted certificates support article
Apple’s Certificate Transparency policy support article
Technote 2232 HTTPS Server Trust Evaluation
Technote 2326 Creating Certificates for TLS Testing
QA1948 HTTPS and Test Servers
Miscellaneous:
More network-related DevForums tags: 5G, QUIC, Bonjour
On FTP DevForums post
Using the Multicast Networking Additional Capability DevForums post
Investigating Network Latency Problems DevForums post
Local Network Privacy FAQ DevForums post
Extra-ordinary Networking DevForums post
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Network
RSS for tagNetwork connections send and receive data using transport and security protocols.
Posts under Network tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hello All,
We are facing weird issue rarely but it continues for few hours or a day.
Observations:
Issue get resolved automatically when we change iOS device network.
We are using sub domain for all network request on iOS/Android App, only iOS Device is logging below mentioned issue.
Both domain has different certificate, where we are using wildcard certificate on subdomain, (*.domain.co.nz )
Main domain don't have subdomain name in subject list (SAN or CN)
we have verified both certificate are valid and supporting TLSv1.3
Also, We have verified instruction given by apple which is also looks good: https://support.apple.com/en-us/103769
you may observer *.wordpress.com is logged in certificate chain validation But We are not calling any of the network request on *.wordpress.com
Our backend server is using only NodeJs and Express.js and as mentioned by out backend team, we don't have any use of main domain/server.
Here is Xcode Error Log
Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “subdomain.maindomain.co.nz” which could put your confidential information at risk." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x11603ae00) s: *.wordpress.com i: Sectigo ECC Domain Validation Secure Server CA>",
"<cert(0x11603b600) s: Sectigo ECC Domain Validation Secure Server CA i: USERTrust ECC Certification Authority>",
"<cert(0x116043400) s: USERTrust ECC Certification Authority i: AAA Certificate Services>"
), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://subdomain.maindomain.co.nz/vider/api/v1/users/login, NSErrorFailingURLStringKey=https://subdomain.maindomain.co.nz/vider/api/v1/users/login, NSUnderlyingError=0x301ec2cd0 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x3021b1360>, kCFNetworkCFStreamSSLErrorOriginalValue=-9843, kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9843, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x11603ae00) s: *.wordpress.com i: Sectigo ECC Domain Validation Secure Server CA>",
"<cert(0x11603b600) s: Sectigo ECC Domain Validation Secure Server CA i: USERTrust ECC Certification Authority>",
"<cert(0x116043400) s: USERTrust ECC Certification Authority i: AAA Certificate Services>"
)}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask .<1>"
), kCFStreamErrorCodeKey=-9843, NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<1>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x3021b1360>, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “subdomain.maindomain.co.nz” which could put your confidential information at risk.}))
URLSessionTask failed with error: The certificate for this server is invalid. You might be connecting to a server that is pretending to be “subdomain.maindomain.co.nz” which could put your confidential information at risk.
"Show: Something went wrong! please try again after sometime!"
"Networking error message: Optional("URLSessionTask failed with error: The certificate for this server is invalid. You might be connecting to a server that is pretending to be “subdomain.maindomain.co.nz” which could put your confidential information at risk.")
End of error Log,
Kindly help us. Thanks in advance.
Hello,
I am trying to apply ProxyConfiguration on the WebKit webview.
I referred to the following sources:
https://forums.developer.apple.com/forums/thread/110312 and
https://developer.apple.com/videos/play/wwdc2023/10002/
import WebKit
class WebKitViewModel: ObservableObject {
let webView: WKWebView
@Published var urlString: String = "https://example.com"
init() {
webView = WKWebView(frame: .zero)
}
func loadUrl() {
guard let url = URL(string: urlString) else {
return
}
var request = URLRequest(url: url)
let endpoint = NWEndpoint.hostPort(host: "127.0.0.1", port: 9077)
let proxyConfig = ProxyConfiguration.init(httpCONNECTProxy: endpoint)
let websiteDataStore = WKWebsiteDataStore.default()
websiteDataStore.proxyConfigurations = [proxyConfig]
webView.configuration.websiteDataStore = websiteDataStore
webView.load(request)
}
}
However, this configuration only works for HTTP proxies. When I try to use an HTTPS proxy, it does not work.
When I use NWConnection to connect to the proxy, it works successfully:
import Foundation
import Network
public class HTTPProxy {
private let proxyHost: NWEndpoint.Host
private let proxyPort: NWEndpoint.Port
private var connection: NWConnection?
public init(proxyHost: String, proxyPort: UInt16) {
self.proxyHost = NWEndpoint.Host(proxyHost)
self.proxyPort = NWEndpoint.Port(rawValue: proxyPort)!
}
public func sendHTTPRequest(completion: @escaping (Result<String, Error>) -> Void) {
let tlsOptions = NWProtocolTLS.Options()
let parameters = NWParameters(tls: tlsOptions)
connection = NWConnection(host: proxyHost, port: proxyPort, using: parameters)
connection?.stateUpdateHandler = { [weak self] state in
switch state {
case .ready:
self?.sendConnectRequest(completion: completion)
case .failed(let error):
completion(.failure(error))
default:
break
}
}
connection?.start(queue: .global())
}
private func sendConnectRequest(completion: @escaping (Result<String, Error>) -> Void) {
guard let connection = connection else {
completion(.failure(NSError(domain: "Connection not available", code: -1, userInfo: nil)))
return
}
let username = "xxxx"
let password = "xxxx"
let credentials = "\(username):\(password)"
guard let credentialsData = credentials.data(using: .utf8) else {
print("Error encoding credentials")
fatalError()
}
let base64Credentials = credentialsData.base64EncodedString()
let proxyAuthorization = "Basic \(base64Credentials)"
let connectString = "CONNECT api.ipify.org:80 HTTP/1.1\r\n" +
"Host: api.ipify.org:80\r\n" +
"Proxy-Authorization: \(proxyAuthorization)\r\n" +
"Connection: keep-alive\r\n" +
"\r\n"
if let connectData = connectString.data(using: .utf8) {
connection.send(content: connectData, completion: .contentProcessed { error in
if let error = error {
completion(.failure(error))
} else {
self.receiveConnectResponse(completion: completion)
}
})
}
}
private func receiveConnectResponse(completion: @escaping (Result<String, Error>) -> Void) {
connection?.receive(minimumIncompleteLength: 1, maximumLength: 65536) { data, context, isComplete, error in
if let data = data, let responseString = String(data: data, encoding: .utf8) {
if responseString.contains("200 OK") {
self.sendRequest(completion: completion)
} else {
completion(.failure(NSError(domain: "Failed to establish connection", code: -1, userInfo: nil)))
}
} else if let error = error {
completion(.failure(error))
}
}
}
private func sendRequest(completion: @escaping (Result<String, Error>) -> Void) {
guard let connection = connection else {
completion(.failure(NSError(domain: "Connection not available", code: -1, userInfo: nil)))
return
}
let requestString = "GET /?format=json HTTP/1.1\r\n" +
"Host: api.ipify.org\r\n" +
// "Proxy-Authorization: Basic xxxxxxxx\r\n" +
"Connection: keep-alive\r\n" +
"\r\n"
print("Sending HTTP request:\n\(requestString)")
if let requestData = requestString.data(using: .utf8) {
connection.send(content: requestData, completion: .contentProcessed { error in
if let error = error {
completion(.failure(error))
} else {
self.receiveResponse(completion: completion)
}
})
}
}
private func receiveResponse(completion: @escaping (Result<String, Error>) -> Void) {
connection?.receive(minimumIncompleteLength: 1, maximumLength: 65536) { data, context, isComplete, error in
if let data = data, !data.isEmpty {
print ("Data: \(data)")
if let responseString = String(data: data, encoding: .utf8) {
print("Received response:\n\(responseString)")
completion(.success(responseString))
} else {
completion(.failure(NSError(domain: "Invalid response data", code: -1, userInfo: nil)))
}
} else if let error = error {
completion(.failure(error))
}
if isComplete {
self.connection?.cancel()
self.connection = nil
} else {
self.receiveResponse(completion: completion)
}
}
}
}
This approach works for connecting to the proxy, but it does not help with configuring the proxy for WebKit.
Could someone please assist me in configuring a proxy for WebKit WebView to work with HTTPS proxies?
Thank you!
There is new porperty introduced in iOS 18 Beta for VPN i.e CellularSliceUUID
But there is no description available for the same. Could you please let us know how this property can impact VPN?
https://developer.apple.com/documentation/devicemanagement/vpn?changes=latest_major&language=objc
Users of my app have reported that they are sometimes unable to receive Voice-over-IP (VoIP) push notifications when using a SIM.
(There is no problem when using WiFi)
VoIP push notifications were not received during the following period.
Could you confirm diagnostic logs and could you please tell me why my app can't receive VoIP push?
[diagnostic logs]
https://drive.google.com/drive/folders/1gSAbr1Fy1SrjlmRXuAzoXqiaxnNbFhj8?usp=sharing
[Problem period]
2024/06/17 05:34:59 - 2024/06/17 09:04:42
Number of times that the push server pushed and it received a normal APNs response: 31
Number of times that iPhone received pushes: 0
2024/06/17 23:05:03 - 2024/06/18 09:02:16
Number of times that the push server pushed and it received a normal APNs response: 192
Number of times that iPhone received pushes: 0
2024/06/15 00:35:56 - 2024/06/15 09:55:57
Number of times that the push server pushed and it received a normal APNs response: 138
Number of times that iPhone received pushes: 0
For important background information, read Extra-ordinary Networking before reading this.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Working with a Wi-Fi Accessory
Building an app that works with a Wi-Fi accessory presents specific challenges. This post discusses those challenges and some recommendations for how to address them.
Note While my focus here is iOS, much of the info in this post applies to all Apple platforms.
IMPORTANT iOS 18, currently in beta, includes AccessorySetupKit, a new framework that can radically simplify the process of setting up an accessory. I’m not fully up to speed on that framework myself, but I encourage you to watch WWDC 2024 Session 10203 Meet AccessorySetupKit and read the framework documentation.
Accessory Categories
I classify Wi-Fi accessories into three different categories.
A bound accessory is ultimately intended to join the user’s Wi-Fi network. It may publish its own Wi-Fi network during the setup process, but the goal of that process is to get the accessory on to the existing network. Once that’s done, your app interacts with the accessory using ordinary networking APIs.
An example of a bound accessory is a Wi-Fi capable printer.
A stand-alone accessory publishes a Wi-Fi network at all times. An iOS device joins that network so that your app can interact with it. The accessory never provides access to the wider Internet.
An example of a stand-alone accessory is a video camera that users take with them into the field. You might want to write an app that joins the camera’s network and downloads footage from it.
A gateway accessory is one that publishes a Wi-Fi network that provides access to the wider Internet. Your app might need to interact with the accessory during the setup process, but after that it’s useful as is.
An example of this is a Wi-Fi to WWAN gateway.
Not all accessories fall neatly into these categories. Indeed, some accessories might fit into multiple categories, or transition between categories. Still, I’ve found these categories to be helpful when discussing various accessory integration challenges.
Do You Control the Firmware?
The key question here is Do you control the accessory’s firmware? If so, you have a bunch of extra options that will make your life easier. If not, you have to adapt to whatever the accessory’s current firmware does.
Simple Improvements
If you do control the firmware, I strongly encourage you to:
Support IPv6
Implement Bonjour [1]
These two things are quite easy to do — most embedded platforms support them directly, so it’s just a question of turning them on — and they will make your life significantly easier:
Link-local addresses are intrinsic to IPv6, and IPv6 is intrinsic to Apple platforms. If your accessory supports IPv6, you’ll always be able to communicate with it, regardless of how messed up the IPv4 configuration gets.
Similarly, if you support Bonjour, you’ll always be able to find your accessory on the network.
[1] Bonjour is an Apple term for three Internet standards:
RFC 3927 Dynamic Configuration of IPv4 Link-Local Addresses
RFC 6762 Multicast DNS
RFC 6763 DNS-Based Service Discovery
WAC
For a bound accessory, support Wireless Accessory Configuration (WAC). This is a relatively big ask — supporting WAC requires you to join the MFi Program — but it has some huge benefits:
You don’t need to write an app to configure your accessory. The user will be able to do it directly from Settings.
If you do write an app, you can use the EAWiFiUnconfiguredAccessoryBrowser class to simplify your configuration process.
HomeKit
For a bound accessory that works in the user’s home, consider supporting HomeKit. This yields the same onboarding benefits as WAC, and many other benefits as well. Also, you can get started with the HomeKit Open Source Accessory Development Kit (ADK).
Bluetooth LE
If your accessory supports Bluetooth LE, think about how you can use that to improve your app’s user experience. For an example of that, see SSID Scanning, below.
Claiming the Default Route, Or Not?
If your accessory publishes a Wi-Fi network, a key design decision is whether to stand up enough infrastructure for an iOS device to make it the default route.
IMPORTANT To learn more about how iOS makes the decision to switch the default route, see The iOS Wi-Fi Lifecycle and Network Interface Concepts.
This decision has significant implications. If the accessory’s network becomes the default route, most network connections from iOS will be routed to your accessory. If it doesn’t provide a path to the wider Internet, those connections will fail. That includes connections made by your own app.
Note It’s possible to get around this by forcing your network connections to run over WWAN. See Binding to an Interface in Network Interface Techniques and Running an HTTP Request over WWAN. Of course, this only works if the user has WWAN. It won’t help most iPad users, for example.
OTOH, if your accessory’s network doesn’t become the default route, you’ll see other issues. iOS will not auto-join such a network so, if the user locks their device, they’ll have to manually join the network again.
In my experience a lot of accessories choose to become the default route in situations where they shouldn’t. For example, a bound accessory is never going to be able to provide a path to the wider Internet so it probably shouldn’t become the default route. However, there are cases where it absolutely makes sense, the most obvious being that of a gateway accessory.
Acting as a Captive Network, or Not?
If your accessory becomes the default route you must then decide whether to act like a captive network or not.
IMPORTANT To learn more about how iOS determines whether a network is captive, see The iOS Wi-Fi Lifecycle.
For bound and stand-alone accessories, becoming a captive network is generally a bad idea. When the user joins your network, the captive network UI comes up and they have to successfully complete it to stay on the network. If they cancel out, iOS will leave the network. That makes it hard for the user to run your app while their iOS device is on your accessory’s network.
In contrast, it’s more reasonable for a gateway accessory to act as a captive network.
SSID Scanning
Many developers think that TN3111 iOS Wi-Fi API overview is lying when it says:
iOS does not have a general-purpose API for Wi-Fi scanning
It is not.
Many developers think that the Hotspot Helper API is a panacea that will fix all their Wi-Fi accessory integration issues, if only they could get the entitlement to use it.
It will not.
Note this comment in the official docs:
NEHotspotHelper is only useful for hotspot integration. There are both technical and business restrictions that prevent it from being used for other tasks, such as accessory integration or Wi-Fi based location.
Even if you had the entitlement you would run into these technical restrictions. The API was specifically designed to support hotspot navigation — in this context hotspots are “Wi-Fi networks where the user must interact with the network to gain access to the wider Internet” — and it does not give you access to on-demand real-time Wi-Fi scan results.
Many developers look at another developer’s app, see that it’s displaying real-time Wi-Fi scan results, and think there’s some special deal with Apple that’ll make that work.
There is not.
In reality, Wi-Fi accessory developers have come up with a variety of creative approaches for this, including:
If you have a bound accessory, you might add WAC support, which makes this whole issue go away.
You might build your accessory with a barcode containing the info required to join its network, and scan that from your app. This is the premise behind the Configuring a Wi-Fi Accessory to Join the User’s Network sample code.
You might configure all your accessories to have a common SSID prefix, and then take advantage of the prefix support in NEHotspotConfigurationManager. See Programmatically Joining a Network, below.
You might have your app talk to your accessory via some other means, like Bluetooth LE, and have the accessory scan for Wi-Fi networks and return the results.
Programmatically Joining a Network
Network Extension framework has an API, NEHotspotConfigurationManager, to programmatically join a network, either temporarily or as a known network that supports auto-join. For the details, see Wi-Fi Configuration.
One feature that’s particularly useful is it’s prefix support, allowing you to create a configuration that’ll join any network with a specific prefix. See the init(ssidPrefix:) initialiser for the details.
For examples of how to use this API, see:
Configuring a Wi-Fi Accessory to Join the User’s Network — It shows all the steps for one approach for getting a non-WAC bound accessory on to the user’s network.
NEHotspotConfiguration Sample — Use this to explore the API in general.
Secure Communication
Users expect all network communication to be done securely. For some ideas on how to set up a secure connection to an accessory, see TLS For Accessory Developers.
Revision History
2024-07-16 Added a preliminary discussion of AccessorySetupKit.
2023-10-11 Added the HomeKit section. Fixed the link in Secure Communication to point to TLS For Accessory Developers.
2023-07-23 First posted.
Hi Team,
There is situation in which I want to implement session Resumption in IOS. I am using Network Framework but I am unable to find a way, how to enable the resumption . It will more beneficial for me if you guys can help me in that.
Regards,
HI, I have Mac Sequoia Beta3. I installed Content Filer network extension which is same as https://developer.apple.com/documentation/networkextension/filtering_network_traffic in my machine.
When I try to connect a machine through "ssh", NEFilterFlow.description in handleNewFlow(_ flow: NEFilterFlow) is showing "sourceAppIdentifier" (process name) as "Terminal" instead of "ssh". But other Mac OS versions, it is showing as "ssh".
Is there any issue with Sequoia Beta3? or Is this expected?
Thanks
We need to do some operations in a login screen, but when the user uses a WPA2-Enterprise network, the authentication to this network is only possible after the login process has already been completed.
Is there a way to change the network on login screen or a way to authenticate on the WPA2-Enterprise network before a completed login?
STEPS TO REPRODUCE
1 - Use a WPA2-Enterprise
2 - Set WPA2-Enterprise as Auto-Join/Principal
3 - Reboot the Machine
4 - On the logon screen it's impossible to authenticate on the enterprise network even then type the username and password.
First of all, I tried MobileVLCKit but there is too much delay
Then I wrote a UDPManager class and I am writing my codes below. I would be very happy if anyone has information and wants to direct me.
Broadcast code
ffmpeg -f avfoundation -video_size 1280x720 -framerate 30 -i "0" -c:v libx264 -preset medium -tune zerolatency -f mpegts "udp://127.0.0.1:6000?pkt_size=1316"
Live View Code (almost 0 delay)
ffplay -fflags nobuffer -flags low_delay -probesize 32 -analyzeduration 1 -strict experimental -framedrop -f mpegts -vf setpts=0 udp://127.0.0.1:6000
OR
mpv udp://127.0.0.1:6000 --no-cache --untimed --no-demuxer-thread --vd-lavc-threads=1
UDPManager
import Foundation
import AVFoundation
import CoreMedia
import VideoDecoder
import SwiftUI
import Network
import Combine
import CocoaAsyncSocket
import VideoToolbox
class UDPManager: NSObject, ObservableObject, GCDAsyncUdpSocketDelegate {
private let host: String
private let port: UInt16
private var socket: GCDAsyncUdpSocket?
@Published var videoOutput: CMSampleBuffer?
init(host: String, port: UInt16) {
self.host = host
self.port = port
}
func connectUDP() {
do {
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: .global())
//try socket?.connect(toHost: host, onPort: port)
try socket?.bind(toPort: port)
try socket?.enableBroadcast(true)
try socket?.enableReusePort(true)
try socket?.beginReceiving()
} catch {
print("UDP soketi oluşturma hatası: \(error)")
}
}
func closeUDP() {
socket?.close()
}
func udpSocket(_ sock: GCDAsyncUdpSocket, didConnectToAddress address: Data) {
print("UDP Bağlandı.")
}
func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) {
print("UDP soketi bağlantı hatası: \(error?.localizedDescription ?? "Bilinmeyen hata")")
}
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
if !data.isEmpty {
DispatchQueue.main.async {
self.videoOutput = self.createSampleBuffer(from: data)
}
}
}
func createSampleBuffer(from data: Data) -> CMSampleBuffer? {
var blockBuffer: CMBlockBuffer?
var status = CMBlockBufferCreateWithMemoryBlock(
allocator: kCFAllocatorDefault,
memoryBlock: UnsafeMutableRawPointer(mutating: (data as NSData).bytes),
blockLength: data.count,
blockAllocator: kCFAllocatorNull,
customBlockSource: nil,
offsetToData: 0,
dataLength: data.count,
flags: 0,
blockBufferOut: &blockBuffer)
if status != noErr {
return nil
}
var sampleBuffer: CMSampleBuffer?
let sampleSizeArray = [data.count]
status = CMSampleBufferCreateReady(
allocator: kCFAllocatorDefault,
dataBuffer: blockBuffer,
formatDescription: nil,
sampleCount: 1,
sampleTimingEntryCount: 0,
sampleTimingArray: nil,
sampleSizeEntryCount: 1,
sampleSizeArray: sampleSizeArray,
sampleBufferOut: &sampleBuffer)
if status != noErr {
return nil
}
return sampleBuffer
}
}
I didn't know how to convert the data object to video, so I searched and found this code and wanted to try it
func createSampleBuffer(from data: Data) -> CMSampleBuffer? {
var blockBuffer: CMBlockBuffer?
var status = CMBlockBufferCreateWithMemoryBlock(
allocator: kCFAllocatorDefault,
memoryBlock: UnsafeMutableRawPointer(mutating: (data as NSData).bytes),
blockLength: data.count,
blockAllocator: kCFAllocatorNull,
customBlockSource: nil,
offsetToData: 0,
dataLength: data.count,
flags: 0,
blockBufferOut: &blockBuffer)
if status != noErr {
return nil
}
var sampleBuffer: CMSampleBuffer?
let sampleSizeArray = [data.count]
status = CMSampleBufferCreateReady(
allocator: kCFAllocatorDefault,
dataBuffer: blockBuffer,
formatDescription: nil,
sampleCount: 1,
sampleTimingEntryCount: 0,
sampleTimingArray: nil,
sampleSizeEntryCount: 1,
sampleSizeArray: sampleSizeArray,
sampleBufferOut: &sampleBuffer)
if status != noErr {
return nil
}
return sampleBuffer
}
And I tried to make CMSampleBuffer a player but it just shows a white screen and doesn't work
struct SampleBufferPlayerView: UIViewRepresentable {
typealias UIViewType = UIView
var sampleBuffer: CMSampleBuffer
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: .zero)
let displayLayer = AVSampleBufferDisplayLayer()
displayLayer.videoGravity = .resizeAspectFill
view.layer.addSublayer(displayLayer)
context.coordinator.displayLayer = displayLayer
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
context.coordinator.sampleBuffer = sampleBuffer
context.coordinator.updateSampleBuffer()
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
class Coordinator {
var displayLayer: AVSampleBufferDisplayLayer?
var sampleBuffer: CMSampleBuffer?
func updateSampleBuffer() {
guard let displayLayer = displayLayer, let sampleBuffer = sampleBuffer else { return }
if displayLayer.isReadyForMoreMediaData {
displayLayer.enqueue(sampleBuffer)
} else {
displayLayer.requestMediaDataWhenReady(on: .main) {
if displayLayer.isReadyForMoreMediaData {
displayLayer.enqueue(sampleBuffer)
print("isReadyForMoreMediaData")
}
}
}
}
}
}
And I tried to use it but I couldn't figure it out, can anyone help me?
struct ContentView: View {
// udp://@127.0.0.1:6000
@ObservedObject var udpManager = UDPManager(host: "127.0.0.1", port: 6000)
var body: some View {
VStack {
if let buffer = udpManager.videoOutput{
SampleBufferDisplayLayerView(sampleBuffer: buffer)
.frame(width: 300, height: 200)
}
}
.onAppear(perform: {
udpManager.connectUDP()
})
}
}
Using NWBrowser and NWListener I'm trying to send a small package of data from the listener/server to the device.
However the device never receives the actual bytes. It either:
gets stuck the preparing state
the connection gets reset
the data is null and is marked as isComplete = true
The only way I can get the device to receive the data is by calling cancel on the NWConnection on the server/NWListener end.
Here is some sample code I am working with:
https://github.com/leogdion/JustBonjour/tree/nwlistener
Is this expected behavior that cancel is required?
I'm very interested in whether it works and, if so, how the system decides to enable or not TFO when working with the network using URLSession.
I didn't find any information in the documentation.
For example, for NWConnection we need to manually add additional option:
/* Allow fast open on the connection parameters */
parameters.allowFastOpen = true
let connection = NWConnection(to: endpoint, using: parameters)
/* Call send with idempotent initial data before starting the connection */
connection.send(content: initialData, completion: .idempotent)
connection.start(queue: myQueue)
I am developing a watchOS-only app, and whenever I attempt to make a network request, it always fails and throws the following error:
Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline."
I noticed that when I turn off Wi-Fi and Bluetooth in the settings of the iPhone paired with the Apple Watch (thus disconnecting the Apple Watch from the iPhone), my app can successfully connect to the network.
Additionally, when the app contains both an iOS app and a watchOS app, after granting network permissions on the iOS app, the watchOS app can access the network normally when connected to the iPhone.
When opening some system apps on the Apple Watch (such as the "Workout" app), the app will display a network permission request similar to that on iOS, but this request does not automatically pop up when my watchOS app attempts to access the network.
Is there a way to request network permissions in a watchOS-only app so that it can access the network while connected to the iPhone?
Hi, I had a Content Filter network extension. It is successfully working until Sonoma. I try to install and activate same network extension on Sequoia beta Intel Mac. But even I haven't got any user consent to activate and allow it. I haven't found any entry in Network settings.
Do we need to make any changes in Sequoia MacOs to make it work?
Thank you.
Hi, I'm using Multipeer Connectivity in my application and when I run it on my physical device, I receive following warning:
NSNetServiceBrowser did not search with error dict [{
NSNetServicesErrorCode = "-72008";
NSNetServicesErrorDomain = 10;
}].
I've found out that this is associated with not having proper permissions in info.plist according to https://developer.apple.com/forums/thread/653316
I've set description for Privacy - Local Network Usage Description, however, I'm not able to find any key for setting my Bonjour Services.
Also, I do not see any popup on my device displaying request to approve local network usage. Could you please provide me an information how can I register my privileges properly?
New crash occur in iOS 17.4.1 and 17.5.1, is there a resolution for this crash ?
Thread 77 name:
Thread 77 Crashed:
0 Network 0x000000018f2218a8 nw_socket_internal_error(nw_socket*, int) + 72 (protocol_socket.cpp:373)
1 Network 0x000000018ec1570c invocation function for block in nw_socket_init_socket_event_source(nw_socket*, unsigned int) + 4000 (protocol_socket.cpp:4351)
2 libdispatch.dylib 0x0000000196405dd4 _dispatch_client_callout + 20 (object.m:576)
3 libdispatch.dylib 0x00000001964092d8 _dispatch_continuation_pop + 600 (queue.c:321)
4 libdispatch.dylib 0x000000019641d1c8 _dispatch_source_latch_and_call + 420 (source.c:596)
5 libdispatch.dylib 0x000000019641bd8c _dispatch_source_invoke + 832 (source.c:961)
6 libdispatch.dylib 0x000000019640f284 _dispatch_workloop_invoke + 1756 (queue.c:4570)
7 libdispatch.dylib 0x0000000196418cb4 _dispatch_root_queue_drain_deferred_wlh + 288 (queue.c:6998)
8 libdispatch.dylib 0x0000000196418528 _dispatch_workloop_worker_thread + 404 (queue.c:6592)
9 libsystem_pthread.dylib 0x00000001eb3b7934 _pthread_wqthread + 288 (pthread.c:2696)
10 libsystem_pthread.dylib 0x00000001eb3b40cc start_wqthread + 8 (:-1)
I am working on an app which is capturing photos and uploading them to a server.
I have followed the URLSession configuration to properly support background transfers. However, I am now noticing that my photos are uploading way slower, even when the user has the app open and is interacting with the app. This is undesirable because the changes need to be reflected in real time to the server when the user is active in the app.
Previously, when I was just using URLSession.shared.uploadTask with a completion handler, the photos uploaded right away in a matter of 1-2 seconds.
Now it is taking 3-4 minutes per photo to upload. The photos are roughly 3mb in size each. I have tried setting the isDiscretionary property explicitly to false to no avail.
Sometimes the users are without internet connection, which is why I wanted to use the background session (so that the uploads can be automatically retried by the system when the user connects back to the internet)
So, in summary, I want the functionality of the background uploading (and to let the system retry when the user transitions from offline to online) however I also need realtime uploading when the user is interacting with the app.
What is the preferred way to solve this problem?
I am updating a universal app for release on iOS 17+ devices using Xcode15.2 and Solar2d v3708. The last release was 7 years ago.
The app connects to the local network and used a custom UDP protocol to connect to and control specific hardware devices. The protocol involves transmitting and receiving both broadcast and unicast messages to/from IPV4 capable proprietary devices on the local network.
When I run the app in the Solar2d simulator and when I run the current version installed from the App store on my iPad, communications work well.
When I build the same code into a new development build and transfer it to my iPad, I found that attempts to send broadcast messages are failing. When I print out the error returned from the socket interface to the console, I see the message is "No Route to Host".
I requested multicast capability from Apple and when it appeared on my development portal I updated the App Id to include the multicast entitlement. I updated the development profile to include our new 6th gen IPad and the updated AppID. I downloaded and installed the development profile. That new profile is what I am selecting / using to sign the app.
I am using lua socket library to send broadcast messages
I created a very basic project with just the basic networking code example and built this for my iPad the results are the same.
local socket = require("socket")
local main, errorMain = socket.udp6()
main:setoption('broadcast', true)
local ack, mError = main:sendto("", "::FFFF:255.255.255.255", 3100)
print("My Debug Message: Main sending - " .. (ack or "nil") .. ", Error : " .. (mError or "None"))
I also tried modifying my code to use udp4 as follows and the results were the same.
local socket = require("socket")
local main, errorMain = socket.udp4()
main:setoption('broadcast', true)
local ack, mError = main:sendto("", "255.255.255.255", 3100)
print("My Debug Message: Main sending - " .. (ack or "nil") .. ", Error : " .. (mError or "None"))
console output:
My Debug Message: Main sending - nil, Error : No route to host
Any help or insight would be greatly appreciated.
Hi,
We are developing react native app, and we are having issue with ATS policy in production build distributed to TestFlight internal testing, requests to https are being killed. The preview build ad-hoc distribution is working fine. (I am testing the app on physical device)
I will described what I've tried and supply you with logs from different tools.
I tried to disable ATS - requests are working
enable ATS (no change to default config) - requests are failing with following error
Task <55618987-64A8-4C04-9B00-2EFF074D796C>.<1> finished with error [-1022] Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection., NSErrorFailingURLStringKey=<private>, NSErrorFailingURLKey=<private>, _NSURLErrorRelatedURLSessionTaskErrorKey=<private>, _NSURLErrorFailingURLSessionTaskErrorKey=<private>, NSUnderlyingError=0x30127bb10 {Error Domain=kCFErrorDomainCFNetwork Code=-1022}}
I tried to check server if it had met ATS requirements and ran ats-diagnostic
./TLSTool s_client -connect api.rankacy.com:443
* input stream did open
* output stream did open
* output stream has space
* protocol: TLS 1.2
* cipher: ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
* trust result: unspecified
* certificate info:
* 0 + ecPublicKey 256 ecdsa-with-SHA384 'api.rankacy.com'
* 1 + ecPublicKey 384 sha256-with-rsa-signature 'E6'
* 2 + rsaEncryption 4096 sha256-with-rsa-signature 'ISRG Root X1'
nscurl https://api.rankacy.com/ --verbose --ats-diagnostics
Starting ATS Diagnostics
Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://api.rankacy.com/.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
================================================================================
Default ATS Secure Connection
---
ATS Default Connection
ATS Dictionary:
{
}
Result : PASS
---
================================================================================
Allowing Arbitrary Loads
---
Allow All Loads
ATS Dictionary:
{
NSAllowsArbitraryLoads = true;
}
Result : PASS
---
================================================================================
Configuring TLS exceptions for api.rankacy.com
---
TLSv1.3
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.3";
};
};
}
Result : PASS
---
---
TLSv1.2
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.2";
};
};
}
Result : PASS
---
---
TLSv1.1
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.1";
};
};
}
Result : PASS
---
---
TLSv1.0
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.0";
};
};
}
Result : PASS
---
================================================================================
Configuring PFS exceptions for api.rankacy.com
---
Disabling Perfect Forward Secrecy
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring PFS exceptions and allowing insecure HTTP for api.rankacy.com
---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring TLS exceptions with PFS disabled for api.rankacy.com
---
TLSv1.3 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.3";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.2 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.2";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.1 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.1";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.0 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.0";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for api.rankacy.com
---
TLSv1.3 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.3";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.2 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.2";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.1 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.1";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"api.rankacy.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.0";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
I am running out of ideas. Also it's hard to test because the preview ad-hoc build is working fine. So only after submitting the app to TestFlight I am having this issue
Looking for your response
Martin
When using Network framework, is it possible to set NWProtocolTLS behave like TLS Server or Client? In CFNetwork there is a kCFStreamSSLIsServer key which I could not find the same thing in Network.
I currently try to implement something like STARTTLS, both client and server side, after connection and some message, the client will behave like a TLS SERVER, and the connection in server(NWListener) will behave like a TLS CLIENT.
That's why i need to set something like kCFStreamSSLIsServer
In Swift-NIO, this can be easily implemented by adding a NIOSSLClientHandler or NIOSSLServerHandler
Below it's what I got currently based on another post in community
// main.swift
import Foundation
import Network
let params = NWParameters.tcp
let framer = STARTTLSFramer.options()
params.defaultProtocolStack.applicationProtocols = [framer]
let connection = NWConnection(
host: .ipv4(IPv4Address("127.0.0.1")!), port: .init(integerLiteral: 8089), using: params)
connection.stateUpdateHandler = { newState in
print("connection newState \(newState)")
}
connection.start(queue: .main)
RunLoop.main.run()
// STARTLSFramer.swift
import Foundation
import Network
final class STARTTLSFramer: NWProtocolFramerImplementation {
static let label: String = "STARTTLSFramer"
init(framer: NWProtocolFramer.Instance) {}
func handleOutput(
framer instance: NWProtocolFramer.Instance, message: NWProtocolFramer.Message,
messageLength: Int, isComplete: Bool
) {
fatalError()
}
func wakeup(framer instance: NWProtocolFramer.Instance) {
fatalError()
}
func stop(framer instance: NWProtocolFramer.Instance) -> Bool { true }
func cleanup(framer instance: NWProtocolFramer.Instance) {}
func start(framer instance: NWProtocolFramer.Instance) -> NWProtocolFramer.StartResult {
instance.writeOutput(data: Data("hello\n".utf8))
return .willMarkReady
}
private var accumulated = Data()
func doUpgrade(instance: NWProtocolFramer.Instance) {
let tlsOptions = NWProtocolTLS.Options()
sec_protocol_options_set_min_tls_protocol_version(tlsOptions.securityProtocolOptions, .TLSv12)
// load identity
let secIdentity = createSecIdentity()!
let identity = sec_identity_create(secIdentity)
sec_protocol_options_set_local_identity(tlsOptions.securityProtocolOptions, identity!)
try! instance.prependApplicationProtocol(options: tlsOptions)
instance.passThroughOutput()
instance.passThroughInput()
instance.markReady()
}
func handleInput(framer instance: NWProtocolFramer.Instance) -> Int {
repeat {
let success = instance.parseInput(minimumIncompleteLength: 1, maximumLength: 2048) {
buffer, _ in
let count = buffer?.count ?? 0
if let buffer {
accumulated.append(contentsOf: buffer)
}
return count
}
if !success { break }
} while true
// some validation
self.accumulated.removeAll()
self.doUpgrade(instance: instance)
return 0
}
static func options() -> NWProtocolFramer.Options {
let startTLSDef = NWProtocolFramer.Definition(implementation: STARTTLSFramer.self)
let result = NWProtocolFramer.Options(definition: startTLSDef)
return result
}
}
Description:
I'm encountering an SSL error (error code: -1200) when trying to establish a secure connection in my app. This issue only occurs when the network signal is low on Airtel. The connection works fine on a normal network signal.
Here are the details:
Device: iPhone 11
iOS Version: 17.2.1
Network Provider: Airtel
Error Message: An SSL error has occurred and a secure connection to the server cannot be made. Error code: -1200
Tried different network settings and Observed the issue only on low network signal.
Any insights or suggestions to resolve this issue would be greatly appreciated. Thank you!