diff options
| author | Jon Petersson <jon.petersson@mullvad.net> | 2025-10-24 08:13:18 +0200 |
|---|---|---|
| committer | Jon Petersson <jon.petersson@mullvad.net> | 2025-10-24 08:13:18 +0200 |
| commit | 3fd0813021ce79818d39996ff089dfb8a5697ad4 (patch) | |
| tree | 289ecb097e4eca02b78bbecfb72d93215c173873 /ios/MullvadREST | |
| parent | 63e9eb92c6e7a1aee6b682ed885d10a6f6fc699c (diff) | |
| parent | e1f357ea3b261265dca2ce0712b265f632079c37 (diff) | |
| download | mullvadvpn-3fd0813021ce79818d39996ff089dfb8a5697ad4.tar.xz mullvadvpn-3fd0813021ce79818d39996ff089dfb8a5697ad4.zip | |
Merge branch 'fetch-current-location-asynchronously-upon-first-start-of-ios-1328'
Diffstat (limited to 'ios/MullvadREST')
| -rw-r--r-- | ios/MullvadREST/ApiHandlers/DefaultLocationService.swift | 49 | ||||
| -rw-r--r-- | ios/MullvadREST/ApiHandlers/RESTDefaults.swift | 3 | ||||
| -rw-r--r-- | ios/MullvadREST/Info.plist | 2 | ||||
| -rw-r--r-- | ios/MullvadREST/Relay/LocationIdentifier.swift | 10 | ||||
| -rw-r--r-- | ios/MullvadREST/Relay/RelaySelector+Wireguard.swift | 9 | ||||
| -rw-r--r-- | ios/MullvadREST/Relay/RelaySelector.swift | 16 |
6 files changed, 66 insertions, 23 deletions
diff --git a/ios/MullvadREST/ApiHandlers/DefaultLocationService.swift b/ios/MullvadREST/ApiHandlers/DefaultLocationService.swift new file mode 100644 index 0000000000..00d0d56c05 --- /dev/null +++ b/ios/MullvadREST/ApiHandlers/DefaultLocationService.swift @@ -0,0 +1,49 @@ +// +// DefaultLocationService.swift +// MullvadVPN +// +// Created by Jon Petersson on 2025-10-13. +// Copyright © 2025 Mullvad VPN AB. All rights reserved. +// + +import CoreLocation +import MullvadLogging +import MullvadTypes + +public struct DefaultLocationService { + private let urlSession: URLSessionProtocol + private let relayCache: CachedRelays + private let logger = Logger(label: "DefaultLocationService") + + public init(urlSession: URLSessionProtocol, relayCache: CachedRelays) { + self.urlSession = urlSession + self.relayCache = relayCache + } + + public func fetchCurrentLocationIdentifier() async throws -> REST.LocationIdentifier? { + // Safe to unwrap since it's a constant. + let url = URL(string: REST.amIMullvadHostname).unsafelyUnwrapped + + let serverLocation: REST.ServerLocation + do { + let data = try await urlSession.data( + for: URLRequest(url: url, timeoutInterval: REST.defaultAPINetworkTimeout.timeInterval)) + serverLocation = try JSONDecoder().decode(REST.ServerLocation.self, from: data.0) + } catch { + logger.log(level: .error, "Could not fetch server location: \(error.localizedDescription)") + return nil + } + + let mappedRelays = RelayWithLocation.locateRelays( + relays: relayCache.relays.wireguard.relays, + locations: relayCache.relays.locations + ) + + let closestRelay = RelaySelector.WireGuard.closestRelay( + to: CLLocationCoordinate2D(latitude: serverLocation.latitude, longitude: serverLocation.longitude), + using: mappedRelays + ) + + return closestRelay?.location + } +} diff --git a/ios/MullvadREST/ApiHandlers/RESTDefaults.swift b/ios/MullvadREST/ApiHandlers/RESTDefaults.swift index 775f61ffd1..b500826fdb 100644 --- a/ios/MullvadREST/ApiHandlers/RESTDefaults.swift +++ b/ios/MullvadREST/ApiHandlers/RESTDefaults.swift @@ -28,4 +28,7 @@ extension REST { /// Default network timeout for API requests. public static let defaultAPINetworkTimeout: Duration = .seconds(10) + + /// am.i.mullvad.net hostname. + public static let amIMullvadHostname = infoDictionary["AmIMullvad"] as! String } diff --git a/ios/MullvadREST/Info.plist b/ios/MullvadREST/Info.plist index 644beb120a..ec177522a4 100644 --- a/ios/MullvadREST/Info.plist +++ b/ios/MullvadREST/Info.plist @@ -2,6 +2,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>AmIMullvad</key> + <string>$(AM_I_JSON_URL)</string> <key>ApiHostName</key> <string>$(API_HOST_NAME)</string> <key>ApiEndpoint</key> diff --git a/ios/MullvadREST/Relay/LocationIdentifier.swift b/ios/MullvadREST/Relay/LocationIdentifier.swift index 53e753277c..cb087c255f 100644 --- a/ios/MullvadREST/Relay/LocationIdentifier.swift +++ b/ios/MullvadREST/Relay/LocationIdentifier.swift @@ -9,19 +9,19 @@ extension REST { // locations are currently always "aa-bbb" for some country code aa and city code bbb. Should this change, this type can be extended. public struct LocationIdentifier: Sendable { - public let country: Substring - public let city: Substring + public let country: String + public let city: String - fileprivate static func parse(_ input: String) -> (Substring, Substring)? { + fileprivate static func parse(_ input: String) -> (String, String)? { let components = input.split(separator: "-") guard components.count == 2 else { return nil } - return (components[0], components[1]) + return (String(components[0]), String(components[1])) } } } extension REST.LocationIdentifier: RawRepresentable { - public var rawValue: String { country.base } + public var rawValue: String { "\(country)-\(city)" } public init?(rawValue: String) { guard let parsed = Self.parse(rawValue) else { return nil } diff --git a/ios/MullvadREST/Relay/RelaySelector+Wireguard.swift b/ios/MullvadREST/Relay/RelaySelector+Wireguard.swift index dbf3030dab..aab6e73d04 100644 --- a/ios/MullvadREST/Relay/RelaySelector+Wireguard.swift +++ b/ios/MullvadREST/Relay/RelaySelector+Wireguard.swift @@ -6,6 +6,7 @@ // Copyright © 2025 Mullvad VPN AB. All rights reserved. // +import CoreLocation import MullvadSettings import MullvadTypes @@ -47,7 +48,11 @@ extension RelaySelector { var relayWithLocation: RelayWithLocation<REST.ServerRelay>? if let referenceLocation { - let relay = closestRelay(to: referenceLocation, using: relayWithLocations) + let relay = closestRelay( + to: CLLocationCoordinate2D( + latitude: referenceLocation.latitude, longitude: referenceLocation.longitude), + using: relayWithLocations + ) relayWithLocation = relayWithLocations.first(where: { $0.relay == relay }) } @@ -61,7 +66,7 @@ extension RelaySelector { } public static func closestRelay( - to location: Location, + to location: CLLocationCoordinate2D, using relayWithLocations: [RelayWithLocation<REST.ServerRelay>] ) -> REST.ServerRelay? { let relaysWithDistance = relayWithLocations.map { diff --git a/ios/MullvadREST/Relay/RelaySelector.swift b/ios/MullvadREST/Relay/RelaySelector.swift index dc74d28568..3b13121056 100644 --- a/ios/MullvadREST/Relay/RelaySelector.swift +++ b/ios/MullvadREST/Relay/RelaySelector.swift @@ -131,22 +131,6 @@ public enum RelaySelector { return nil } - private static func makeRelayWithLocationFrom<T: AnyRelay>( - _ serverLocation: REST.ServerLocation, - relay: T - ) -> RelayWithLocation<T>? { - let location = Location( - country: serverLocation.country, - countryCode: String(relay.location.country), - city: serverLocation.city, - cityCode: String(relay.location.city), - latitude: serverLocation.latitude, - longitude: serverLocation.longitude - ) - - return RelayWithLocation(relay: relay, serverLocation: location) - } - private static func filterByActive<T: AnyRelay>( relays: [RelayWithLocation<T>] ) throws -> [RelayWithLocation<T>] { |
