Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Commit

Permalink
Fix #2864: Update user agents. (#2865)
Browse files Browse the repository at this point in the history
  • Loading branch information
iccub committed Sep 9, 2020
1 parent 03e5fb7 commit 97bfaa7
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 130 deletions.
94 changes: 28 additions & 66 deletions Shared/UserAgentBuilder.swift
Expand Up @@ -11,10 +11,6 @@ public struct UserAgentBuilder {
private let safariBuildNumber = "604.1"
private let webkitVersion = "605.1.15"

/// If we fail getting proper safari version, this version will be used instead.
/// It is for the 'Safari/13.0.5' part of UA.
private let fallbackSafariVersion = "13.0.5"

private let device: UIDevice
private let os: OperatingSystemVersion

Expand All @@ -37,7 +33,7 @@ public struct UserAgentBuilder {
return """
Mozilla/5.0 (\(cpuInfo)) \
AppleWebKit/\(webkitVersion) (KHTML, like Gecko) \
Version/\(versionNumber) \
Version/\(safariVersion) \
Mobile/\(kernelVersion) \
Safari/\(safariBuildNumber)
"""
Expand All @@ -47,6 +43,15 @@ public struct UserAgentBuilder {
// These are not super precise because each iOS version can have slighly different desktop UA.
// The only differences are with exact `Version/XX` and `MAC OS X 10_XX` numbers.
private var desktopUA: String {
// Taken from Safari 14.0(ios 14 beta 7)
let iOS14DesktopUA =
"""
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) \
AppleWebKit/605.1.15 (KHTML, like Gecko) \
Version/14.0 \
Safari/605.1.15
"""

// Taken from Safari 13.4
let iOS13DesktopUA =
"""
Expand All @@ -68,18 +73,13 @@ public struct UserAgentBuilder {
switch os.majorVersion {
case 12: return iOS12DesktopUA
case 13: return iOS13DesktopUA
case 14: return iOS14DesktopUA
// Fallback to iOS13 UA, next desktop UA will be added once iOS 14 is ready.
default: return iOS13DesktopUA
}
}

private var cpuInfo: String {
var osVersionString = "\(os.majorVersion)_\(os.minorVersion)"

if os.patchVersion > 0 {
osVersionString.append("_\(os.patchVersion)")
}

var currentDevice = device.model
// Only use first part of device name(so "iPod Touch" becomes "iPod")
if let deviceNameFirstPart = currentDevice.split(separator: " ").first {
Expand All @@ -88,66 +88,28 @@ public struct UserAgentBuilder {

let platform = device.userInterfaceIdiom == .pad ? "OS" : "iPhone OS"

return "\(currentDevice); CPU \(platform) \(osVersionString) like Mac OS X"
return "\(currentDevice); CPU \(platform) \(osVersion) like Mac OS X"
}

// 'Version/13.0' part of UA. It seems to be based on Safaris build number.
private var versionNumber: String {
var versionWithDots = "\(os.majorVersion).\(os.minorVersion)"
if os.patchVersion > 0 {
versionWithDots += ".\(os.patchVersion)"
}

return getSafariVersion(for: versionWithDots)
}

private func getSafariVersion(for iOSVersion: String) -> String {
// Safari's versions don't follow iOS versions directly.
// For better coverage of versions, each iOS version has their Safari number set individually.
// Correct Safari numbers were taken from https://user-agents.net/browsers/safari
switch iOSVersion {
case "12.0", "12.0.1", "12.1", "12.1.1", "12.1.2", "12.1.3", "12.1.4":
return "12.0"
case "12.2":
return "12.1"
case "12.3", "12.3.1", "12.3.2":
return "12.1.1"
case "12.4", "12.4.1", "12.4.2", "12.4.3", "12.4.4", "12.4.5":
return "12.1.2"
case "13.0":
return "13.0"
case "13.1", "13.1.1", "13.1.2", "13.1.3":
return "13.0.1"
case "13.2", "13.2.1", "13.2.2", "13.2.3":
return "13.0.3"
case "13.3":
return "13.0.4"
case "13.3.1":
return "13.0.5"
case "13.4":
return "13.1"
default:
// We can't predict what exact safari versions for future iOS releases.
// As a fallback we aim to use as highest Safari version as possible for give iOS major version.
//
// For example if new iOS 13.5 release shows up `highestSafariVersion` will be used.
// This also works for iOS 12, as Apple still releases hotfixes there.
// iOS versions were taken from https://en.wikipedia.org/wiki/IOS_version_history
guard let majorVersion = iOSVersion.components(separatedBy: ".").first else {
assertionFailure("Could not extract major version from \(iOSVersion)")
return fallbackSafariVersion
}

return highestSafariVersion(majorOSVersion: majorVersion)
/// 'Version/13.0' part of UA. It seems to be based on Safaris build number.
private var osVersion: String {
switch os.majorVersion {
case 12: return "12_4_1"
case 13: return "13_6_1"
case 14: return "14_0"
default: return "\(os.majorVersion)_0"

}
}

private func highestSafariVersion(majorOSVersion: String) -> String {
switch majorOSVersion {
case "12": return "12.1.2"
case "13": return "13.1"
default:
return "\(majorOSVersion).0"
/// 'Version/13.0' part of UA. It seems to be based on Safaris build number.
private var safariVersion: String {
switch os.majorVersion {
case 12: return "12.1.2"
case 13: return "13.1.2"
case 14: return "14.0"
default: return "\(os.majorVersion).0"

}
}
}

0 comments on commit 97bfaa7

Please sign in to comment.