diff --git a/Sources/MasKit/Controllers/StoreSearch.swift b/Sources/MasKit/Controllers/StoreSearch.swift index 5dc097ed8..4fcb5a217 100644 --- a/Sources/MasKit/Controllers/StoreSearch.swift +++ b/Sources/MasKit/Controllers/StoreSearch.swift @@ -31,6 +31,11 @@ extension StoreSearch { URLQueryItem(name: "entity", value: "macSoftware"), URLQueryItem(name: "term", value: appName), ] + + if let country = country { + components.queryItems!.append(country) + } + return components.url } @@ -44,6 +49,24 @@ extension StoreSearch { } components.queryItems = [URLQueryItem(name: "id", value: "\(appId)")] + + if let country = country { + components.queryItems!.append(country) + } + return components.url } + + private var country: URLQueryItem? { + // CommerceKit and StoreFoundation don't seem to expose the region of the Apple ID signed + // into the App Store. Instead, we'll make an educated guess that it matches the currently + // selected locale in macOS. This obviously isn't always going to match, but it's probably + // better than passing no "country" at all to the iTunes Search API. + // https://affiliate.itunes.apple.com/resources/documentation/itunes-store-web-service-search-api/ + guard let region = Locale.autoupdatingCurrent.regionCode else { + return nil + } + + return URLQueryItem(name: "country", value: region) + } } diff --git a/Tests/MasKitTests/Controllers/StoreSearchSpec.swift b/Tests/MasKitTests/Controllers/StoreSearchSpec.swift index b391e0827..c0cb6d198 100644 --- a/Tests/MasKitTests/Controllers/StoreSearchSpec.swift +++ b/Tests/MasKitTests/Controllers/StoreSearchSpec.swift @@ -6,6 +6,7 @@ // Copyright © 2019 mas-cli. All rights reserved. // +import Foundation import Nimble import PromiseKit import Quick @@ -26,19 +27,21 @@ struct StoreSearchForTesting: StoreSearch { public class StoreSearchSpec: QuickSpec { override public func spec() { let storeSearch = StoreSearchForTesting() + let region = Locale.autoupdatingCurrent.regionCode! describe("url string") { it("contains the app name") { let appName = "myapp" let urlString = storeSearch.searchURL(for: appName)?.absoluteString - expect(urlString) == "https://itunes.apple.com/search?media=software&entity=macSoftware&term=\(appName)" + expect(urlString) == "https://itunes.apple.com/search?" + + "media=software&entity=macSoftware&term=\(appName)&country=\(region)" } it("contains the encoded app name") { let appName = "My App" let appNameEncoded = "My%20App" let urlString = storeSearch.searchURL(for: appName)?.absoluteString - expect(urlString) - == "https://itunes.apple.com/search?media=software&entity=macSoftware&term=\(appNameEncoded)" + expect(urlString) == "https://itunes.apple.com/search?" + + "media=software&entity=macSoftware&term=\(appNameEncoded)&country=\(region)" } // Find a character that causes addingPercentEncoding(withAllowedCharacters to return nil xit("is nil when app name cannot be url encoded") {