Hi all,
My application requires to create a WebSocket server on an iOS application for other devices can connect and transfer data with my application.
I used Vapor library to create a socket server and it works well when the application is in the foreground.
I am trying to keep the server alive when my app moves to the background or the suspended state so that my app and other devices can continue to communicate with each other.
Is there any ways to achieve that?
I tried to turn on a mode: "Audio, Airplay, and Picture in Picture" in background modes section in Signing & Capabilities and then my application can still communicate with clients when it is background mode.
But my application is an application for user can edit image and send it to other devices through sockets and it does not have audio, airplay,.. feature.
Is it ok to publish the app to the app store in the future?
Thank you!
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
After numerous trials and errors, we finally succeeded in implementing VR180.
However, there is a problem.
Videos played via a URL (Internet) connection experience significant lag. Initially, I thought it was a bitrate issue.
But after various tests, I began to suspect that the problem might be with the internet connection processing..itself
I tested the same video through both file opening (set up as a network drive) and URL (AWS) connections. Since AWS provides stable speeds, I concluded there is no issue there.
The video files are 8K. The bitrate is between 80-90 Mbps. The conditions for decoding and implementing 8K are the same. Also, when I mirrored the video, there was significant lag. Both AFP and URL use the same wireless conditions. I assume the conditions for implementing 8K are the same. When mirroring, the AFP connection had no lag at all.
Could it be that VisionOS's URL (Internet connection) is causing a high system load? I noticed that an app called AmazeVR allows videos to be downloaded before playing. Could this be because of the URL issue?
If anyone knows, please respond.
Hello,
I have an app that receives critical alarms. This is usually done through remote push notifications from the server, but to add redundancy I'd like to add a MQTT connection as well. There are scenarios where internet connection might be missing (but there is a local WiFi connection to the server) hence I'd like to deliver the alarms directly from server to client without going out via the Internet.
The problem is that according to all restrictions on iOS, the MQTT connection will not be maintained in the background and disconnect occurs within 20-30 sec after going in the background and shutting the screen.
I'm aware of all the background modes that iOS allows but none fall within this scenario.
Is there a way to maintain a MQTT connection (or some other type of network connection) in the background on iOS?
Issue
When using the nio-ssh library to execute ssh commands in a daemonized context (built executable launched using launchctl with a config in /Library/LaunchDaemons) a ChannelError (operationUnsupported) is thrown.
I'm unsure if this is a problem just with nio-ssh or nio in general. Could it be that certain network operations aren't permitted from within a daemon?
Any information/help on this matter is greatly appreciated!
Related issue in the nio-ssh repository: https://github.com/apple/swift-nio-ssh/issues/166
Unfortunately there are no specific tags for these libraries (nio, nio-ssh) or for daemons, so I have used the Network tag instead.
Reproduction
Reproduction can be found here: https://github.com/eliaSchenker/nio-ssh-daemon-issue/tree/main
To run the reproduction follow these steps:
Build using Xcode (Product > Build)
Find the executable in the build folder (Product > Show Build Folder in Finder)
Move the executable to /Library/PrivilegedHelperTools
Create a daemon configuration in /Library/LaunchDaemons/nio-ssh-daemon.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>nio-ssh-daemon</string>
<key>ProgramArguments</key>
<array>
<string>/Library/PrivilegedHelperTools/nio-ssh-daemon</string>
<string>username:password@host</string>
<string>ls -la</string>
</array>
<key>KeepAlive</key>
<true/>
<key>ProcessType</key>
<string>Interactive</string>
<key>StandardOutPath</key>
<string>/Library/Logs/nio-ssh-daemon.out.log</string>
<key>StandardErrorPath</key>
<string>/Library/Logs/nio-ssh-daemon.err.log</string>
</dict>
</plist>
making sure to adjust the program arguments to include an host with username and password.
Load the daemon using
sudo launchctl load nio-ssh-daemon.plist
When opening Console.app, navigating to Log Reports and opening nio-ssh-daemon.out.log the logged error will be shown:
Creating bootstrap
Connecting channel
Creating child channel
Waiting for connection to close
Error in pipeline: operationUnsupported
An error occurred: commandExecFailed
If the executable is run manually without a daemon it will work correctly:
./nio.ssh-daemon username:password@host
The reproduction is a copy of the example in the repository (https://github.com/apple/swift-nio-ssh/tree/main/Sources/NIOSSHClient) with slight modifications to log errors instead of using try!.
I'm following the approach in https://developer.apple.com/forums/thread/703234 section "Doing Even Better: Proper Security".
My question is: does it work if the accessory is not in the local network (i.e. out there on the Internet with an IP address) ?
I tried and: SecTrustEvaluateWithError(trust, nil) returns true, but TLS still fails:
ATS failed system trust
Connection 1: system TLS Trust evaluation failed(-9802)
<snip>
Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?,
Here is my code :
var err = SecTrustSetPolicies(trust, SecPolicyCreateBasicX509())
os_log("SecTrustSetPolicies returns \(err)")
err = SecTrustSetAnchorCertificates(trust, [self.myCA] as NSArray)
os_log("SecTrustSetAnchorCertificates returns \(err)")
err = SecTrustSetAnchorCertificatesOnly(trust, true)
os_log("SecTrustSetAnchorCertificatesOnly returns \(err)")
// check the trust object
let evalResult = SecTrustEvaluateWithError(trust, nil)
os_log("SecTrust eval result: \(evalResult)")
// create a credential with accepted server trust.
let credential = URLCredential(trust: trust)
completionHandler(.useCredential, credential)
the logs are:
SecTrustSetPolicies returns 0
SecTrustSetAnchorCertificates returns 0
SecTrustSetAnchorCertificatesOnly returns 0
SecTrust eval result: true
Did I do anything wrong? or is it not supported outside the local network?
Thanks.
I am trying to set up a secure local websocket server on a mac using swift. I think I am able to get a non-secure server running (still untested). But I am unable to find any documentation that points to how to set up a secure connection (say uses TLS 1.2) if I have an ssl cert, an intermediate cert (both pem files) and the private key for that cert.
Any insight would be great.
Any code samples that show setting up a local secure websocket server that makes use of certificates and private keys would be even better.
Hello,
context :
2 Institutions being part of the eduroam Federation :
they both offer the ssid eduroam
the 2 institutions are physically closed to each other (on the same campus)
A client from Institution_A authenticate 802.1x to ssid eduroam of its institution :
after successfull authentication, the client gets a new ip address from the dhcp server of Institution_A
The same client walks towards Institution_B :
the client associate with ssid eduroam of Institution_B
the client authenticate through the federation against its Institution_A authentication server
after successfull authentication, the client starts the process of getting an ip address
At that point here is what is observed on all iPhone/iPad :
the client asks for its previously obtanined ip address from Institution_A (DHCPREQUEST)
the dhcp server of Institution_B issues a DHCPNAK to the client because the ip address asked is not part of its subnets
the client continuosly repeat the process of asking its former ip address, the process can last for minutes/hours (maybe till the end of lease ?)
As a result the client has no wifi working, till the client decide to issue a DHCPDISCOVER and then get a valid new ip address
Even after a shutdown, the client keeps on asking the same ip address (to be confirmed, but so far this what has been seen).
It is devastating for all our Apple clients.
Regards
I am having crash on com.apple.network.connections randomly. I couldn't reproduce in my local, but I keep seen in my Firebase.
Thanks in advance.
stacktrace_0.txt
stacktrace_1.txt
Hi there,
I think I may have caught a bug in the iOS system. Please confirm.
Problem
Newly installed Watch-Only and Independent apps on the Apple Watch do not have a network connection when paired with an iPhone until the iPhone is rebooted.
Please see the attached screenshot; the iPhone indicates 'WiFi and Cellular policy: kDeny'.
Use Case
For our end-users, they will install the Watch-Only app directly from the App Store on the Apple Watch, and of course, their watch is paired with their iPhone. In this case, the Watch-Only app has no network connection at all after installation. The user has to reboot the iPhone once, and then the Watch-Only app can access the network. It is unacceptable for the end-users.
System Info
WatchOS: 10.1.1
Watch Model: A2770, Apple Watch Series 8 (GPS only)
iOS Version: 17.4.1
iPhone Model: iPhone 15
XCode: 15.3
How to reproduce
Please download the very simple sample code attached. It features the official URLSession Demo Code, which initiates a default URLSession to access https://www.example.com.
ContentView.swift
Prepare an iPhone and an Apple Watch, then connect the watch to the iPhone and ensure they are paired correctly.
Ensure that your iPhone properly connects to a working WiFi network.
Now, connect both your Apple Watch and iPhone to Xcode and run the code on the watch. Xcode will then install the Watch-Only app on your watch.
After installation, click the 'Click' button on the watch app, and you will receive an error message stating 'The Internet connection appears to be offline...'
Now, check the Console output of your iPhone and filter by 'wifi policy'. You will see logs stating 'Adding CU Policy: Bundle IDs: (the-bundle-id) Wifi policy: kDeny Cellular policy: kDeny'.
Now, reboot your iPhone and wait for it to reconnect to the WiFi network.
Check the Control Center on your watch to ensure the little green iPhone icon is displayed, indicating that your watch is now paired correctly with the iPhone. Click the 'Click' button again on the watch app, and this time it will work perfectly.
To repeat the process, simply uninstall the watch app from your watch, and run the sample code again. Xcode will reinstall the app onto the watch. This time, the app will not work until you reboot the iPhone again.
References
Proxy Through iPhone
https://developer.apple.com/documentation/watchos-apps/keeping-your-watchos-app-s-content-up-to-date#Test-your-update-code-with-different-configurations
Sample Code
struct ContentView: View {
@State var txt = "Hello World!"
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text(txt)
Button("Click") {
startLoad()
}
}.padding()
}
func startLoad() {
let config = URLSessionConfiguration.default
config.waitsForConnectivity = false
config.allowsCellularAccess = true
config.allowsExpensiveNetworkAccess = true
config.allowsConstrainedNetworkAccess = true
let sesh = URLSession(configuration: config)
let url = URL(string: "https://www.example.com")!
sesh.dataTask(with: url) { data, response, error in
if let error = error {
self.txt = error.localizedDescription
// self.handleClientError(error)
return
}
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
self.txt = response.debugDescription
// self.handleServerError(response)
return
}
if let mimeType = httpResponse.mimeType, mimeType == "text/html",
let data = data,
let string = String(data: data, encoding: .utf8) {
DispatchQueue.main.async {
self.txt = string
// self.webView.loadHTMLString(string, baseURL: url)
}
}
}.resume()
}
}
#Preview {
ContentView()
}
We have been using the BGTask (specifically a BGProcessingTask) reliably for the last couple of years for our app. Up until now they wake up automatically while the screen is off, the iPad is plugged in, and the app is running (that is, in the background), but never while the screen is on (that is, never when the scenePhase == .active).
For the last month or so, I've noticed that they are triggering now while the screen is displayed. How is this possible??? Did something change with a recent version of iOS?
It's violating Apple's own documentation, which describes the BGProcessingTask as:
"A time-consuming processing task that runs while the app is in the background."
Hello,
I develop an iOS game with Unreal Engine 5. My game works perfectly well in the Editor on my mac and on Android, but on iOS somehow once the app in installed, it cannot connect to our game server through WebSocket with a wss URL.
wss being a secured connection I don't see what the issue is, but it looks like it's being blocked by Apple ? No issue communicating with Rest API with our server thought. I have done that so far :
In App ID profile I enabled Custom Networks and Push Notification, set up a SSL certificate. Here is my change in the .plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>MyApp</string>
</array>
</dict>
</array>
<key>NSCameraUsageDescription</key>
<string>We don't and cannot use the Camera at all but UnrealEngine integrates SDK for games using camera</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsForMedia</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSAllowsLocalNetworking</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>myapp.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.2</string>
<key>NSExceptionRequiresForwardSecrecy</key>
<true/>
<key>NSRequiresCertificateTransparency</key>
<true/>
</dict>
</dict>
</dict>
Thanks in advance,
I'm wondering if there's a way to capture the SSL/TLS key log / ephemeral keys from Safari for troubleshooting like there is for Firefox & Chrome by setting the SSLKEYLOGFILE environment variable.
I'm troubleshooting an issue where Safari doesn't load certain CSS and JPEG elements on the first load, but when hitting refresh, those same elements load fine. Clearing the cache or using "disable caches" in the network tab of the inspector will cause the elements to fail to load again. Safari shows that it received a header, but no content. Wireshark shows four TCP/RST packets coming from the client / Safari. The same site loads without issue every time using Firefox or Chromium.
I'm hoping that someone knows how to capture the TLS session keys from Safari so I can look deeper into the packet capture and figure out if Safari is incorrectly parsing the server's response or if there is some subtle corruption in the response that Safari rejects, but other browsers accept.
So, does anyone know how to capture the raw data transfer or TLS session keys from Safari?
Thank you!
I am encountering an issue while using the SystemConfiguration framework to detect IPv4 address changes and active interfaces on macOS. Specifically, I'm facing difficulties when the interface switches from one network to another.
When connected to a network with a Captive Portal enabled, I'm unable to retrieve the active interface using the stored key State:/Network/Global/IPv4. The output I receive is:
No such key
However, when I attempt to retrieve interface information using scutil --nwi, the output is as follows:
IPv4 network interface information
No IPv4 states found
REACH : flags 0x00000000 (Not Reachable)
IPv6 network interface information
No IPv6 states found
REACH : flags 0x00000000 (Not Reachable)
Network interfaces: en0
Despite this output, the interface en0 is active and has a valid IPv4 address:
when checking through ifconfig:
en0:flags=8b63<UP,BROADCAST,SMART,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
options=6460<TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
ether bc:d0:74:07:2a:33
inet6 fe80::412:ec:40df:4211%en0 prefixlen 64 secured scopeid 0x12
inet 10.42.0.5 netmask 0xffffff00 broadcast 10.42.0.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
It's evident that the interface is active and has a valid IPv4 address, but the retrieval methods using SystemConfiguration framework are not providing the expected output. I'm seeking assistance in resolving this discrepancy and accurately detecting active interfaces on macOS. Any insights or suggestions would be greatly appreciated. Thank you.
I'm creating an app that uses broadcasts using sockets.
But there's something strange about it.
It is possible to send packets from other platforms like mac and windows and receive them in iOS, but it's impossible to receive packets from iOS in other platforms.
iOS -> Other (OK)
Other -> iOS (Not OK)
If ios app send packet, it can't receive any bytes in other platforms.
Communication between iOS devices is no problem, and there is no problem between other platforms too.
For example, iPhone apps and iPad apps can communicate, and Macbook and Windows can communicate in the same way.
However, iPhone and mac cannot communicate.
I use UDP, ipv6, Broadcast, address: ff02::1, port: 14001
What is wrong with sending from the ios to another platform?
Why is it normal to use IJKPlayer to play rtsp real-time stream preview black screen when opening mobile traffic on some mobile phones, and cut into flight mode?
Whether mobile traffic affects local network access?
Folks,
I’m trying (for tests of third party hardware) to set up a very simple ‘UDP parrot’. It receives a packet, and returns it to the source with a '*' prefixed.
Can’t get it work. The following code works like a charm on FreeBSD, but won’t work on MacOS:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/errno.h>
#include <string.h>
int main(int argc, const char * argv[]) {
struct sockaddr_in myAddr;
struct sockaddr_in rmtAddr;
socklen_t rmtAddrLength;
char buffer [2048];
char src [256];
printf ("Opening socket…\n");
int sock;
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
printf("Cannot open UDP socket. Bailing!\n");
return -1;
}
int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
myAddr.sin_family = AF_INET;
myAddr.sin_addr.s_addr = INADDR_ANY;
myAddr.sin_port = htons(5522);
if (bind(sock, (struct sockaddr *) &myAddr, sizeof(myAddr))) {
printf ("Error binding socket -> %d\n", errno);
return -1;
}
printf ("Listening…\n");
while (1) {
ssize_t dataLength = recvfrom(sock, buffer + 1, sizeof(buffer) - 1,
0, (struct sockaddr *)& rmtAddr, & rmtAddrLength);
printf ("Received %zd bytes: %s\n", dataLength, buffer);
printf ("addrLength: %d\n", rmtAddrLength);
inet_ntop(AF_INET, & rmtAddr.sin_addr, src, sizeof(src));
printf("From %s port %d\n", src, ntohs (rmtAddr.sin_port));
if (! strncmp (buffer + 1, "STOP", 4)) {
sendto (sock, "Terminated\n", 11, 0,
(struct sockaddr *)& rmtAddr, sizeof(rmtAddr));
break;}
buffer [0] = '*';
dataLength = sendto(sock, buffer, dataLength + 1, 0,
(struct sockaddr *)& rmtAddr, sizeof(rmtAddr));
}
return 0;
}
The problem is, the rmtAddr structure, which is supposed to contain the IP address of the remote sender, well, does not. I always get 1.0.0.0 instead. As I said before, I have no such problem with the exact same code on FreeBSD. Also, rmtAddrLength, which is 8 on FreeBSD, is 16 on MacOS apparently.
I've dumped the memory starting at &rmtAddr and did not see a hint of a possible IP address.
Any idea what could be wrong?
Thanks !
V.
I can't seem to find the answer anywhere online and through vendor support channels. Is it possible to trigger per-app VPN on unmanaged apps by leveraging the safari/browser domain whitelist on a user enrolment type device?
According to this document from Apple, it seems like it's possible. https://developer.apple.com/documentation/devicemanagement/applayervpn?changes=latest_minor
However it is missing the context as to which enrolment type is available on.
Hi everyone,
I'm currently working on a project that involves using the Network framework on macOS 10.15 and iOS 12. While implementing error handling for my network connections, I encountered a warning about the conformance of 'NWError' to 'CustomNSError', which is only available in macOS 13.3 or newer.
Here's the warning message I received while compiling the code:
Warning: conformance of 'NWError' to 'CustomNSError' is only available in macOS 13.3 or newer
self.vConnection = try NWConnection (to: self.vBaseSocketProperties!.uEndpoint!, using: self.vBaseSocketProperties!.uParamters!)
self.vConnection?.stateUpdateHandler = { connectionState in
switch connectionState {
case .failed(let err):
error_code = err.errorCode
//Below all the other cases are also handled.
}
With SCNetworkReachabilityCreateWithAddress now depreciated I'm having to use NWPathMonitor to determine if I have a good connection to access some HTML and JSON files. I have this working just fine if the network connection is down but if the network connection comes back up it detects an event but still shows the status as unsatisfied. I can't seem to capture or pickup that when I've got a good connection again so I can proceed with the right status. Here is my current code. Any suggestions would be appreciated:
import Network
import Combine
class NetworkStatus: ObservableObject {
static let shared = NetworkStatus()
private var monitor: NWPathMonitor?
private var queue = DispatchQueue(label: "NetworkMonitor")
@Published var isConnected: Bool = false
private init() {
monitor = NWPathMonitor()
startMonitoring()
}
deinit {
stopMonitoring()
}
func startMonitoring() {
monitor?.pathUpdateHandler = { [weak self] path in
DispatchQueue.main.async {
let status = path.status == .satisfied
self?.isConnected = status
print(">>> \(path.status)")
}
}
monitor?.start(queue: queue)
}
func stopMonitoring() {
monitor?.cancel()
monitor = nil
}
}
Hello fellow developers and Apple support,
I'm experiencing a challenging issue with NWConnection when sending data via QUIC udp datagrams to multiple devices. I have a setup where I use NWListener to send data every 10 milliseconds to 10 or even 15 clients, which works flawlessly. However, when I switch to using NWConnection to send data every 20 milliseconds, I encounter significant packet loss, and the following error messages appear in the console:
nw_connection_create_with_connection_internal [C19] Original connection not yet connected
nw_connection_group_create_connection_for_endpoint_and_parameters [G2] failed to create connection with parameters QUIC, traffic class: 300, local: 0.0.0.0:9000, attribution: developer, attach protocol listener
This issue is mitigated when a second NWConnection is connected to the same NWListener, reducing the frequency of errors. By adding a third connection, the errors almost disappear, which suggests that the problem might be related to how a single NWConnection handles rapid data transmissions. This observation leads me to believe that the issue could be linked to the capacity or the management of connections under high throughput scenarios (200kb every 20ms).
I've thoroughly reviewed the documentation for NWConnection and NWListener, focusing on their QUIC protocols handling, without finding a clear cause or solution for this issue. I've also searched through forums and developer communities for similar problems but haven't found anything that matches my situation closely.
Thank you in advance for your time and help!