My application advertises service uuid FC66 and 00410b66-2553-48d7-cf18-000000002154 in advertising data, and "loading" as local name in response data in foreground.
But iOS cut local name to "loadi" and add Hashed UUID data 0100000000000000000000000600000000 to response data.
Why iOS add hashed uuid data? Is it because my 128-bit uuid format is wrong?
We want to advertise the complete local name data.
How to avoid this problem?
Networking
RSS for tagExplore the networking protocols and technologies used by the device to connect to Wi-Fi networks, Bluetooth devices, and cellular data services.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi, after upgrading to MacOS Sequoia, my connection to my local IP address does not work. The issue is with the PF (MacOS advanced firewall), as I confirmed that my local application works disabling it temporarily.
Does anyone know how can I do to solve this problem? As APP developer, this is a big problem for me.
Thanks in advance.
1、已经检查过手机的存储空间,还有一百多G的空间。app端进行网络接口情况的时候报错了,报错信息如下:
Error : Error Domain=NSPOSIXErrorDomain Code=28 "No space left on device" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <7DB1CBFD-B9BE-422D-9C9A-78D8FC04DC1B>.<76>, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=28, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <7DB1CBFD-B9BE-422D-9C9A-78D8FC04DC1B>.<76>"
), _NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: pdp_ip0[lte], ipv4, ipv6, dns, expensive, estimated upload: 65536Bps, uses cell}
2、手机型号是iPhone 15 Plus,iOS 17.6.1
Topic:
App & System Services
SubTopic:
Networking
I'm looking for help with a network extension filtering issue. Specifically, we have a subclass of NEFilterDataProvider that is used to filter flows based upon a set of rules, including source IP and destination IP. We've run into an issue where the source IP is frequently 0.0.0.0 (or the IPv6 equivalent) on outgoing flows. This has made it so rules based upon source IP don't work. This is also an issue as we report these connections, but we're lacking critical data. We were able to work around the issue somewhat by keeping a list of flows that we allow that we periodically check to see if the source IP is available, and then report after it becomes available.
We also considered doing a "peekBytes" to allow a bit of data to flow and then recheck the flow, but we don't want to allow data leakage on connections that should be blocked because of the source IP.
Is there a way to force the operating system or network extension frameworks to determine the source IP for an outbound flow without allowing any bytes to flow to the network?
STEPS TO REPRODUCE
Create a network filtering extension for filtering flows using NEFilterDataProvider
See that when handleNewFlow: is called, the outgoing flow lacks the source IP (is 0.0.0.0) in most cases
There is this post that is discussing a similar question, though for a slightly different reason. I imagine the answer to this and the other post will be related, at least as far as NEFilterDataProvider:handleNewFlow not having source IP is considered.
Thanks!
We put the apple-app-site-association file at https://ourdomain.com.tr/.well-known/apple-app-site-association.
When we send a request to url, we get 200 response code every time and we can see the file. But sometimes when we try to access https://app-site-association.cdn-apple.com/a/v1/ourdomain.com.tr url with browser or CMD tool, we are facing with 404 response code.
There isn't any ip adress filter in our systems and we tried using vpn for sending same request from different locations(america and europe) but nothing changed.
In addition, can anyone provide the ip list of apple cdn servers to check the F5 Load balancer WAF logs?
CMD output:
C:\Users\Name>curl -Lv https://app-site-association.cdn-apple.com/a/v1/ourdomain.com.tr
Host app-site-association.cdn-apple.com:443 was resolved.
IPv6: (none)
IPv4: 17.253.122.197, 17.253.15.210, 17.253.122.196, 17.253.107.201, 17.253.57.203, 17.253.15.198, 17.253.57.200
Trying 17.253.122.197:443...
Connected to app-site-association.cdn-apple.com (17.253.122.197) port 443
schannel: disabled automatic use of client certificate
ALPN: curl offers http/1.1
ALPN: server accepted http/1.1
using HTTP/1.x
GET /a/v1/ourdomain.com HTTP/1.1
Host: app-site-association.cdn-apple.com
User-Agent: curl/8.9.1
Accept: /
Request completely sent off
schannel: remote party requests renegotiation
schannel: renegotiating SSL/TLS connection
schannel: SSL/TLS connection renegotiated
< HTTP/1.1 404 Not Found
< Apple-Failure-Details: {"cause":"context deadline exceeded (Client.Timeout exceeded while awaiting headers)"}
< Apple-Failure-Reason: SWCERR00301 Timeout
< Apple-From: https://ourdomain.com.tr/.well-known/apple-app-site-association
< Apple-Try-Direct: true
< Cache-Control: max-age=3600,public
< Content-Length: 10
< Content-Type: text/plain; charset=utf-8
< Date: Mon, 14 Apr 2025 12:52:04 GMT
< Expires: Mon, 14 Apr 2025 12:52:14 GMT
< Age: 1770
< Via: http/1.1 uklon5-vp-vst-004.ts.apple.com (acdn/268.14469), https/1.1 uklon5-vp-vfe-002.ts.apple.com (acdn/268.14469), http/1.1 frmrs1-edge-mx-008.ts.apple.com (acdn/268.14469), http/1.1 frmrs1-edge-fx-005.ts.apple.com (acdn/268.14469)
< X-Cache: hit-fresh, hit-stale, hit-fresh, hit-fresh
< CDNUUID: 9e72cf99-1503-4644-9ea3-173328a25c94-31496306226
< Connection: keep-alive
<
Not Found
Connection #0 to host app-site-association.cdn-apple.com left intact
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"
On Host Names
I commonly see questions like How do I get the device’s host name? This question doesn’t make sense without more context. Apple systems have a variety of things that you might consider to be the host name:
The user-assigned device name — This is a user-visible value, for example, Guy Smiley. People set this in Settings > General > About > Name.
The local host name — This is a DNS name used by Bonjour, for example, guy-smiley.local. By default this is algorithmically derived from the user-assigned device name. On macOS, people can override this in Settings > General > Sharing > Local hostname.
The reverse DNS name associated with the various IP addresses assigned to the device’s various network interfaces
That last one is pretty much useless. You can’t get a single host name because there isn’t a single IP address. For more on that, see Don’t Try to Get the Device’s IP Address.
The other two have well-defined answers, although those answers vary by platform. I’ll talk more about that below.
Before getting to that, however, let’s look at the big picture.
Big Picture
The use cases for the user-assigned device name are pretty clear. I rarely see folks confused about that.
Another use case for this stuff is that you’ve started a server and you want to tell the user how to connect to it. I discuss this in detail in Showing Connection Information in an iOS Server.
However, most folks who run into problems like this do so because they’re suffering from one of the following misconceptions:
The device has a DNS name.
Its DNS name is unique.
Its DNS name doesn’t change.
Its DNS name is in some way useful for networking.
Some of these may be true in some specific circumstances, but none of them are true in all circumstances.
These issues are not unique to Apple platforms — if you look at the Posix spec for gethostname, it says nothing about DNS! — but folks tend to notice these problems more on Apple platforms because Apple devices are often deployed to highly dynamic network environments.
So, before you start using the APIs discussed in this post, think carefully about your assumptions.
And if you actually do want to work with DNS, there are two cases to consider:
If you’re looking for the local host name, use the APIs discussed above.
In other cases, it’s likely that the APIs in this post will not be helpful and you’d be better off focusing on DNS APIs [1].
[1] The API I recommend for this is DNS-SD. See the DNS section in TN3151 Choosing the right networking API.
macOS
To get the user-assigned device name, call the SCDynamicStoreCopyComputerName(_:_:) function. For example:
let userAssignedDeviceName = SCDynamicStoreCopyComputerName(nil, nil) as String?
To get the local host name, call the SCDynamicStoreCopyLocalHostName(_:) function. For example:
let localHostName = SCDynamicStoreCopyLocalHostName(nil) as String?
IMPORTANT This returns just the name label. To form a local host name, append .local..
Both routines return an optional result; code defensively!
If you’re displaying these values to the user, use the System Configuration framework dynamic store notification mechanism to keep your UI up to date.
iOS and Friends
On iOS, iPadOS, tvOS, and visionOS, get the user-assigned device name from the name property on UIDevice.
IMPORTANT Access to this is now restricted. For more on that, see the documentation for the com.apple.developer.device-information.user-assigned-device-name entitlement.
There is no direct mechanism to get the local host name.
Other APIs
There are a wide variety of other APIs that purport to return the host name. These include:
gethostname
The name property on NSHost [1]
The hostName property on NSProcessInfo (ProcessInfo in Swift)
These are problematic for a number of reasons:
They have a complex implementation that makes it hard to predict what value you’ll get back.
They might end up trying to infer the host name from the network environment.
The existing behaviour is hard to change due to compatibility concerns.
Some of them are marked as to-be-deprecated.
IMPORTANT The second issue is particularly problematic, because it involves synchronous DNS requests [2]. That’s slow in general. Worse yet, if the network environment is restricted in some way, these calls can be very slow, taking about 30 seconds to time out.
Given these problems, it’s generally best to avoid calling these routines at all.
[1] It also has a names property, which is a little closer to reality but still not particularly useful.
[2] Actually, that’s not true for gethostname. Rather, that call just returns whatever was last set by sethostname. This is always fast. The System Configuration framework infrastructure calls sethostname to update the host name as the system state changes.
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"
Don’t Try to Get the Device’s IP Address
I regularly see questions like:
How do I find the IP address of the device?
How do I find the IP address of the Wi-Fi interface?
How do I identify the Wi-Fi interface?
I also see a lot of really bad answers to these questions. That’s understandable, because the questions themselves don’t make sense. Networking on Apple platforms is complicated and many of the things that are ‘obviously’ true are, in fact, not true at all. For example:
There’s no single IP address that represents the device, or an interface. A device can have 0 or more interfaces, each of which can have 0 or more IP addresses, each of which can be IPv4 and IPv6.
A device can have multiple interfaces of a given type. It’s common for iPhones to have multiple WWAN interfaces, for example.
It’s not possible to give a simple answer to any of these questions, because the correct answer depends on the context. Why do you need this particular information? What are you planning to do with it?
This post describes the scenarios I most commonly encounter, with my advice on how to handle each scenario.
IMPORTANT BSD interface names, like en0, are not considered API. There’s no guarantee, for example, that an iPhone’s Wi-Fi interface is en0. If you write code that relies on a hard-coded interface name, it will fail in some situations.
Service Discovery
Some folks want to identify the Wi-Fi interface so that they can run a custom service discovery protocol over it. Before you do that, I strongly recommend that you look at Bonjour. This has a bunch of advantages:
It’s an industry standard [1].
It’s going to be more efficient on the ‘wire’.
You don’t have to implement it yourself, you can just call an API [2].
For information about the APIs available, see TN3151 Choosing the right networking API.
If you must implement your own service discovery protocol, don’t think in terms of finding the Wi-Fi interface. Rather, write your code to work with all Wi-Fi interfaces, or perhaps even all Ethernet-like interfaces. That’s what Apple’s Bonjour implementation does, and it means that things will work in odd situations [3].
To find all Wi-Fi interfaces, get the interface list and filter it for ones with the Wi-Fi functional type. To find all broadcast-capable interfaces, get the interface list and filter it for interfaces with the IFF_BROADCAST flag set. If the service you’re trying to discover only supports IPv4, filter out any IPv6-only interfaces.
For advice on how to do this, see Interface List and Network Interface Type in Network Interface APIs.
When working with multiple interfaces, it’s generally a good idea to create a socket per interface and then bind that socket to the interface. That ensures that, when you send a packet, it’ll definitely go out the interface you expect.
For more information on how to implement broadcasts correctly, see Broadcasts and Multicasts, Hints and Tips.
[1] Bonjour is an Apple term for:
RFC 3927 Dynamic Configuration of IPv4 Link-Local Addresses
RFC 6762 Multicast DNS
RFC 6763 DNS-Based Service Discovery
[2] That’s true even on non-Apple platforms. It’s even true on most embedded platforms. If you’re talking to a Wi-Fi accessory, see Working with a Wi-Fi Accessory.
[3] Even if the service you’re trying to discover can only be found on Wi-Fi, it’s possible for a user to have their iPhone on an Ethernet that’s bridged to a Wi-Fi. Why on earth would they do that? Well, security, of course. Some organisations forbid their staff from using Wi-Fi.
Logging and Diagnostics
Some folks want to log the IP address of the Wi-Fi interface, or the WWAN, or both for diagnostic purposes. This is quite feasible, with the only caveat being there may be multiple interfaces of each type.
To find all interfaces of a particular type, get the interface list and filter it for interfaces with that functional type. See Interface List and Network Interface Type in Network Interface APIs.
Interface for an Outgoing Connection
There are situations where you need to get the interface used by a particular connection. A classic example of that is FTP. When you set up a transfer in FTP, you start with a control connection to the FTP server. You then open a listener and send its IP address and port to the FTP server over your control connection. What IP address should you use?
There’s an easy answer here: Use the local IP address for the control connection. That’s the one that the server is most likely to be able to connect to.
To get the local address of a connection:
In Network framework, first get the currentPath property and then get its localEndpoint property.
In BSD Sockets, use getsockname. See its man page for details.
Now, this isn’t a particularly realistic example. Most folks don’t use FTP these days [1] but, even if they do, they use FTP passive mode, which avoids the need for this technique. However, this sort of thing still does come up in practice. I recently encountered two different variants of the same problem:
One developer was implementing VoIP software and needed to pass the devices IP address to their VoIP stack. The best IP address to use was the local IP address of their control connection to the VoIP server.
A different developer was upgrading the firmware of an accessory. They do this by starting a server within their app and sending a command to the accessory to download the firmware from that server. Again, the best IP address to use is the local address of the control connection.
[1] See the discussion in TN3151 Choosing the right networking API.
Listening for Connections
If you’re listening for incoming network connections, you don’t need to bind to a specific address. Rather, listen on all local addresses. In Network framework, this is the default for NWListener. In BSD Sockets, set the address to INADDR_ANY (IPv4) or in6addr_any (IPv6).
If you only want to listen on a specific interface, don’t try to bind to that interface’s IP address. If you do that, things will go wrong if the interface’s IP address changes. Rather, bind to the interface itself:
In Network framework, set either the requiredInterfaceType property or the requiredInterface property on the NWParameters you use to create your NWListener.
In BSD Sockets, set the IP_BOUND_IF (IPv4) or IPV6_BOUND_IF (IPv6) socket option.
How do you work out what interface to use? The standard technique is to get the interface list and filter it for interfaces with the desired functional type. See Interface List and Network Interface Type in Network Interface APIs. Remember that their may be multiple interfaces of a given type. If you’re using BSD Sockets, where you can only bind to a single interface, you’ll need to create multiple listeners, one for each interface.
Listener UI
Some apps have an embedded network server and they want to populate a UI with information on how to connect to that server. This is a surprisingly tricky task to do correctly. For the details, see Showing Connection Information for a Local Server.
Outgoing Connections
In some situations you might want to force an outgoing connection to run over a specific interface. There are four common cases here:
Set the local address of a connection [1].
Force a connection to run over a specific interface.
Force a connection to run over a type of interface.
Force a connection to run over an interface with specific characteristics. For example, you want to download some large resource without exhausting the user’s cellular data allowance.
The last case should be the most common — see the Constraints section of Network Interface Techniques — but all four are useful in specific circumstances.
The following sections explain how to tackle these tasks in the most common networking APIs.
[1] This implicitly forces the connection to use the interface with that address. For an explanation as to why, see the discussion of scoped routing in Network Interface Techniques.
Network Framework
Network framework has good support for all of these cases. Set one or more of the following properties on the NWParameters object you use to create your NWConnection:
requiredLocalEndpoint property
requiredInterface property
prohibitedInterfaces property
requiredInterfaceType property
prohibitedInterfaceTypes property
prohibitConstrainedPaths property
prohibitExpensivePaths property
Foundation URL Loading System
URLSession has fewer options than Network framework but they work in a similar way: Set one or more of the following properties on the URLSessionConfiguration object you use to create your session:
allowsCellularAccess property
allowsConstrainedNetworkAccess property
allowsExpensiveNetworkAccess property
Note While these session configuration properties are also available on URLRequest, it’s better to configure this on the session.
There’s no option that forces a connection to run over a specific interface. In most cases you don’t need this — it’s better to use the allowsConstrainedNetworkAccess and allowsExpensiveNetworkAccess properties — but there are some situations where that’s necessary. For advice on this front, see Running an HTTP Request over WWAN.
BSD Sockets
BSD Sockets has very few options in this space. One thing that’s easy and obvious is setting the local address of a connection: Do that by passing the address to bind.
Alternatively, to force a connection to run over a specific interface, set the IP_BOUND_IF (IPv4) or IPV6_BOUND_IF (IPv6) socket options.
Revision History
2025-01-21 Added a link to Broadcasts and Multicasts, Hints and Tips. Made other minor editorial changes.
2023-07-18 First posted.
plateform: iPadOS 16.3.1
xcode:15.2
code:
self.queue = Queue()
self.monitor = NWPathMonitor()
self.monitor.pathUpdateHandler = { [weak self] path in
queue.async {
}
}
Topic:
App & System Services
SubTopic:
Networking
Hello,
Title states it basically. I have a java program (launched via shell script) running as a service using launchd which is running as a user (not root) and it does not request Local Network permissions ever.
I feel like i'm missing something here. I combed through all of the Local Network FAQs and don't really see this use case addressed.
I do see that there is an open ticket for an API to trigger the request, but no update on that and the ticket is not visible publicly.
Is there is a way to accomplish this for java or other programs running via launchd with a user other than root? something like an entitlement or an API to seed the permission of Local Network when installing the service via launchctl etc?
I am developing an App based on Network Extension that lets all network requests on device access the Internet through a private Relay.
I created an empty iOS App and only the entitlements file and ViewController.swift(Main.storyboard) file have been modified. The code was copied from the official video https://developer.apple.com/videos/play/wwdc2023/10002/
But, running the App on iPhone, the saveToPreferences API reported Error Domain=NERelayErrorDomain Code=3 "(null)" and the App doesn't look like it's changed at all (it doesn't jump to the Settings - VPN&Relay). Does anyone know why?Any reply would be greatly appreciated.
The contents of the entitlements file:
<?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>com.apple.developer.networking.networkextension</key>
<array>
<string>relay</string>
</array>
</dict>
</plist>
ViewController.swift:
import UIKit
import NetworkExtension
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func tap(_ sender: Any) {
let newRelay = NERelay()
let relayURL = URL(string: "https://relay.example.com:443/")
newRelay.http3RelayURL = relayURL
newRelay.http2RelayURL = relayURL
newRelay.additionalHTTPHeaderFields = ["Authorization" : "PrivateToken=123"]
let manager = NERelayManager.shared()
manager.relays = [newRelay]
manager.matchDomains = ["internal.example.com"]
manager.isEnabled = false
manager.saveToPreferences { err in
print(err)
}
}
}
We are migrating our iOS app to macOS. On iOS, it works fine. But when I try and run on macOS and connect to the VPN, I am getting an error like failed to fetch /Users/stuart/Library/Developer/Xcode/DerivedData/app-byzvshkqegwzqxgervfswmsughkm/Build/Products/Debug/<app_name>.app/Contents/PlugIns/<network_extension_name>.appex/Contents/_CodeSignature/CodeRequirements-1 error=-10.
If I have Settings -> VPN open, it rapidly is connecting and disconnecting. Is there anything I need to do specific to macOS to make this work? Or is this related to a broken code signature? Thanks in advance!
I'm working on a game that uses NWBrowser and NWListener to create a connection between an iOS and tvOS app.
I've got the initial networking up and running and it works perfectly when running in the simulator(s). However, when I run on-device(s), I've found that browseResultsChangedHandler gets called multiple times for what is ostensibly the same service.
My browser handler (which runs on iOS) looks like this:
browser.browseResultsChangedHandler = { [weak self] results, changes in
if let result = browser.browseResults.first {
self?.onPeerConnected?(PeerConnection(endpoint: result.endpoint))
}
}
The first time it gets called, the interface in the NWBrowser.Result is en0, but the 2nd time it gets called, it is en0 AND awdl0.
Because my current handling is so naive, this re-invocation ends up with two connections being made to the remote server (the Apple TV).
Now, I know that this handler, by its very name, is designed to be called multiple times as things change, so I'm curious as to what strategies I might employ here.
Is there any value in tearing down any previous connections and re-connecting using the latest one? Should I just kill the browser as soon as I handle the first one? Just ignore subsequent ones?
I'm sure that, to a degree, the answer is probably "it depends"... but I'm curious to see if there might be at least some high-level strategies like "whatever you do, don't do xxxx" or "most apps do yyyy" :-)
Thanks.
Hi,
I've created a packet tunnel but my packetFlow object isn't get called with any packets. Do I need to do something else to configure the packetFlow? Maybe I have to link it to a NWUDPSession?
Thanks,
Dave
class PacketTunnelProvider: NEPacketTunnelProvider {
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: tunnelRemoteAddress)
settings.ipv4Settings = NEIPv4Settings(addresses: [tunnelRemoteAddress], subnetMasks: ["255.255.255.255"])
settings.ipv4Settings?.includedRoutes = [NEIPv4Route.default()]
setTunnelNetworkSettings(settings) { error in
completionHandler(error)
self.readPacketObjects()
}
}
private func readPacketObjects() {
self.packetFlow.readPacketObjects() { packets in
// It never gets here.
self.logMessage("Got '\(packets.count)' packet(s)")
self.packetFlow.writePacketObjects(packets)
self.readPacketObjects()
}
}
}
Hello, I'm developing a Transparent Proxy and I noticed that the Network Extension Framework logs in the Unified Logging System when my profile receives a flow, its source application, its destination endpoint, and my profile's decision regarding that flow.
I worry that this may compromise the user's privacy. So is there a way that I can turn off these logs at least in Distribution Configurations?
1、Does Captive Portal documentation for IOS exist for developers?
If so, please provide a link.
I am adopting Swift Concurrency in my network extension app to use Swift 6 protections.
In the UI app I ended up with most of the app marked as MainActor, so that pieces of my app can keep seamless access to each other and at the same time have thread safe access.
When it comes to my network extension, does it make sense to also mark most of the code as MainActor for the purposes of thread safety and seamless access of most classes to each other? I have doubts, because MainActor sounds like it should be a UI think, but network extension has no UI
Of course any long or blocking operations would not be MainActor
We are developers of an app, we found that there's no LN prompt for users to install the app for the 1st time on ios18.
We used the following method to prompt the "allow/not allow" alert:
// Attempts to trigger the local network privacy alert.
///
/// This builds a list of link-local IPv6 addresses and then creates a connected
/// UDP socket to each in turn. Connecting a UDP socket triggers the local
/// network alert without actually sending any traffic.
///
/// This is a ‘best effort’ approach, and it handles errors by ignoring them.
/// There’s no guarantee that it’ll actually trigger the alert (FB8711182).
func triggerLocalNetworkPrivacyAlert() {
let addresses = selectedLinkLocalIPv6Addresses()
for address in addresses {
let sock6 = socket(AF_INET6, SOCK_DGRAM, 0)
guard sock6 >= 0 else { return }
defer { close(sock6) }
withUnsafePointer(to: address) { sa6 in
sa6.withMemoryRebound(to: sockaddr.self, capacity: 1) { sa in
_ = connect(sock6, sa, socklen_t(sa.pointee.sa_len)) >= 0
}
}
}
}
Topic:
App & System Services
SubTopic:
Networking
We have product for network monitoring and we are't able to add support auto-instrumenting the networking requests for URLSession async/wait methods as these methods are't exposed to dynamic environment or not exposed to ObjC and we con't use any of the run-time functionality and we con't override these methods as these methods are't public.
looking for a way to add some kind of logic so that when customers use our product they don't have to add any code from there end to monitor this system.
We found that when we only set one App Category and one Traffic Category in Xcode entitlements, the built application will contain all App Categories and Traffic Categories in the embedded.mobileprovision file, is it expected?
Entitlements file:
<?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>com.apple.developer.networking.slicing.appcategory</key>
<array>
<string>streaming-9001</string>
</array>
<key>com.apple.developer.networking.slicing.trafficcategory</key>
<array>
<string>avstreaming-7</string>
</array>
</dict>
</plist>
embedded.mobileprovision:
<key>Entitlements</key>
<dict>
<key>com.apple.developer.networking.slicing.appcategory</key>
<array>
<string>communication-9000</string>
<string>games-6014</string>
<string>streaming-9001</string>
</array>
<key>com.apple.developer.networking.slicing.trafficcategory</key>
<array>
<string>defaultslice-1</string>
<string>video-2</string>
<string>background-3</string>
<string>voice-4</string>
<string>callsignaling-5</string>
<string>responsivedata-6</string>
<string>avstreaming-7</string>
<string>responsiveav-8</string>
</array>
I'm simply trying to use a proxy to route a http request in Swift to measure the average round trip time of a list of proxies. I've went through multiple Stack Overflow threads on this topic but they are all super old / outdated.
format:host:port:username:password
I also added the info.plist entry:
NSAllowsArbitraryLoads -> NSExceptionDomains
When I call the function below I am prompted with a menu that says
"Proxy authentication required. Enter the password for HTTP proxy ... in settings"
I closed this menu inside my app and tried the function below again and it worked without giving me the menu a second time. However even though the function works without throwing any errors, it does NOT use the proxies to route the request.
Why does the request work (throws no errors) but does not use the proxies? I'm assuming it's because the password isn't entered in the settings as the alert said. My users will want to test proxy speeds for many different Hosts/Ports, it doesn't make sense to enter the password in settings every time. How can I fix this issue?
func averageProxyGroupSpeed(proxies: [String], completion: @escaping (Int, String) -> Void) {
let numProxies = proxies.count
if numProxies == 0 {
completion(0, "No proxies")
return
}
var totalTime: Int64 = 0
var successCount = 0
let group = DispatchGroup()
let queue = DispatchQueue(label: "proxyQueue", attributes: .concurrent)
let lock = NSLock()
let shuffledProxies = proxies.shuffled()
let selectedProxies = Array(shuffledProxies.prefix(25))
for proxy in selectedProxies {
group.enter()
queue.async {
let proxyDetails = proxy.split(separator: ":").map(String.init)
guard proxyDetails.count == 4,
let port = Int(proxyDetails[1]),
let url = URL(string: "http://httpbin.org/get") else {
completion(0, "Invalid proxy format")
group.leave()
return
}
var request = URLRequest(url: url)
request.timeoutInterval = 15
let configuration = URLSessionConfiguration.default
configuration.connectionProxyDictionary = [
AnyHashable("HTTPEnable"): true,
AnyHashable("HTTPProxy"): proxyDetails[0],
AnyHashable("HTTPPort"): port,
AnyHashable("HTTPSEnable"): false,
AnyHashable("HTTPUser"): proxyDetails[2],
AnyHashable("HTTPPassword"): proxyDetails[3]
]
let session = URLSession(configuration: configuration)
let start = Date()
let task = session.dataTask(with: request) { _, _, error in
defer { group.leave() }
if let error = error {
print("Error: \(error.localizedDescription)")
} else {
let duration = Date().timeIntervalSince(start) * 1000
lock.lock()
totalTime += Int64(duration)
successCount += 1
lock.unlock()
}
}
task.resume()
}
}
group.notify(queue: DispatchQueue.main) {
if successCount == 0 {
completion(0, "Proxies Failed")
} else {
let averageTime = Int(Double(totalTime) / Double(successCount))
completion(averageTime, "")
}
}
}