Does NSURLSession send user-agent automatically when user WatchKit 2.0, iOS 9.0? Is there a way to verify this within the WatchKit app?
3 Answers
Yes, a user agent is automatically provided as part of the default session configuration.
The default NSURLSession
request header User-Agent
field includes the Bundle Name (CFBundleName
) and the Build Number (CFBundleVersion
) of your watchOS app extension:
$(CFBundleName)/$(CFBundleVersion) CFNetwork/808.3 Darwin/16.3.0
Notice that your app's Version Number (CFBundleShortVersionString
) isn't included. (See Technical Note TN2420: Version Numbers and Build Numbers for more info.)
For example, for product "Foo" with the Build Number 1, your user agent would be:
Foo%20WatchKit%20Extension/1 CFNetwork/808.3 Darwin/16.3.0
How to Verify?
I don't think there's a way within your app to examine the default user agent field, as it's nil
(unless you've set it to a custom value).
But, you could use netcat to examine requests sent by the Simulator.
Run
nc -l 5678
in Terminal to have netcat listen to requests sent tolocalhost
on port5678
In your app's
Info.plist
file, add the App Transport Security Settings dictionary with the Allow Arbitrary Loads key set toYES
Add the following code to the start of
application(_:didFinishLaunchingWithOptions:)
let url = URL(string: "http://localhost:5678/")! URLSession.shared.dataTask(with: url) { (data, response, error) in let body = String(data: data!, encoding: .utf8)! print("body: \(body)") }.resume() return true
Run your app in the Simulator and see what netcat outputs in Terminal
If your privacy is of no concern, you could use a service like user-agent.me to test on your device.
Replace
localhost:5678
above withuser-agent.me
Run your app on your device
Examine Xcode's Console output
When you're done verifying, remember to undo all of the changes above.

- 121,420
- 116
- 450
- 651
-
Depending on your App Transport Security Settings, you may need to enable arbitrary loads. See the answer here: https://stackoverflow.com/a/32631185/211292 – ThomasW Aug 30 '22 at 05:34
NSURLSession send User-Agent by default.
default User-Agent style like.
"User-Agent" = "UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0";
We can customize the User-Agent.
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = ["User-Agent": "zgpeace User-Agent"]
I write a demo for URLSession in the below.
func requestUrlSessionAgent() {
print("requestUrlSessionAgent")
let config = URLSessionConfiguration.default
// default User-Agent: "User-Agent" = "UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0";
// custom User-Agent
config.httpAdditionalHeaders = ["User-Agent": "zgpeace User-Agent"]
let session = URLSession(configuration: config)
let url = URL(string: "https://httpbin.org/anything")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
let task = session.dataTask(with: url) { data, response, error in
// ensure there is no error for this HTTP response
guard error == nil else {
print ("error: \(error!)")
return
}
// ensure there is data returned from this HTTP response
guard let content = data else {
print("No data")
return
}
// serialise the data / NSData object into Dictionary [String : Any]
guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String: Any] else {
print("Not containing JSON")
return
}
print("gotten json response dictionary is \n \(json)")
// update UI using the response here
}
// execute the HTTP request
task.resume()
}
By the way, the default User-Agent in WKWebView is different, like
Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X)
You can customize the WKWebView User-Agent
webView.customUserAgent = "zgpeace User-Agent"
I also write a demo for WKWebView:
func requestWebViewAgent() {
print("requestWebViewAgent")
let webView = WKWebView()
webView.evaluateJavaScript("navigator.userAgent") { (userAgent, error) in
if let ua = userAgent {
print("default WebView User-Agent > \(ua)")
}
// customize User-Agent
webView.customUserAgent = "zgpeace User-Agent"
}
}
Warning: "User-Agent" is nil from webView, when webView is released. You can set webView object as property to keep the webView.
NSURLConnection send User-Agent by default.
default User-Agent style like.
"User-Agent" = "UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0";
We can customize the User-Agent.
urlRequest.setValue("URLConnection zgpeace User-Agent", forHTTPHeaderField: "User-Agent")
I write a demo for URLConnection in the below.
func requestUrlConnectionUserAgent() {
print("requestUrlConnectionUserAgent")
let url = URL(string: "https://httpbin.org/anything")!
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "GET"
// default User-Agent: "User-Agent" = "UserAgentDemo/1 CFNetwork/1121.2.1 Darwin/19.2.0";
urlRequest.setValue("URLConnection zgpeace User-Agent", forHTTPHeaderField: "User-Agent")
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: OperationQueue.main) { (response, data, error) in
// ensure there is no error for this HTTP response
guard error == nil else {
print ("error: \(error!)")
return
}
// ensure there is data returned from this HTTP response
guard let content = data else {
print("No data")
return
}
// serialise the data / NSData object into Dictionary [String : Any]
guard let json = (try? JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers)) as? [String: Any] else {
print("Not containing JSON")
return
}
print("gotten json response dictionary is \n \(json)")
// update UI using the response here
}
}
Demo in github:
https://github.com/zgpeace/UserAgentDemo.git

- 3,927
- 33
- 31
Related to your question, note that it is possible to manually set the User-Agent
string for your NSURLSession
in WatchKit, using a NSURLSessionConfiguration
object and setting HTTPAdditionalHeaders.

- 19,972
- 4
- 56
- 93
-
I know I can add it manually :) I asked if it is added automatically. 10x – Yasmin Tiomkin Apr 05 '16 at 05:13