BOM Amazon Affilaite search

This commit is contained in:
Stefan Lange-Hegermann
2025-09-27 14:19:05 +02:00
parent 3fa15b59d7
commit 0a2789dc44
4 changed files with 80 additions and 54 deletions

View File

@@ -305,8 +305,8 @@
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -336,8 +336,8 @@
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",

View File

@@ -0,0 +1,73 @@
import Foundation
enum AmazonAffiliate {
private static let fallbackDomain = "www.amazon.com"
private static let fallbackTag: String? = nil
private static let domainsByCountry: [String: String] = [
"US": "www.amazon.com",
"DE": "www.amazon.de",
"FR": "www.amazon.fr",
"ES": "www.amazon.es",
"IT": "www.amazon.it",
"GB": "www.amazon.co.uk",
"CA": "www.amazon.ca",
"JP": "www.amazon.co.jp",
"AU": "www.amazon.com.au",
"NL": "www.amazon.nl",
"SE": "www.amazon.se",
"PL": "www.amazon.pl",
"MX": "www.amazon.com.mx",
"BR": "www.amazon.com.br",
"IN": "www.amazon.in"
]
// Configure Amazon affiliate tracking IDs by country code.
private static let tagsByCountry: [String: String] = [
"US": "voltplan-20",
"DE": "voltplan-21",
]
private static let countryAliases: [String: String] = [
"UK": "GB"
]
static func searchURL(query: String, countryCode: String?) -> URL? {
guard !query.isEmpty else { return nil }
var components = URLComponents()
components.scheme = "https"
components.host = domain(for: countryCode)
components.path = "/s"
var queryItems = [URLQueryItem(name: "k", value: query)]
if let tag = affiliateTag(for: countryCode), !tag.isEmpty {
queryItems.append(URLQueryItem(name: "tag", value: tag))
}
components.queryItems = queryItems
return components.url
}
static func domain(for countryCode: String?) -> String {
guard let normalized = normalizedCountryCode(from: countryCode) else {
return fallbackDomain
}
return domainsByCountry[normalized] ?? fallbackDomain
}
static func affiliateTag(for countryCode: String?) -> String? {
guard let normalized = normalizedCountryCode(from: countryCode) else {
return fallbackTag
}
return tagsByCountry[normalized] ?? fallbackTag
}
private static func normalizedCountryCode(from countryCode: String?) -> String? {
guard let raw = countryCode?.uppercased(), !raw.isEmpty else { return nil }
if let alias = countryAliases[raw] {
return alias
}
return raw
}
}

View File

@@ -874,31 +874,7 @@ private struct BillOfMaterialsView: View {
case .affiliate(let url):
return url
case .amazonSearch(let query):
let domain = amazonDomain(for: info.countryCode)
guard let encodedQuery = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return nil }
return URL(string: "https://\(domain)/s?k=\(encodedQuery)")
}
}
private func amazonDomain(for countryCode: String?) -> String {
guard let countryCode else { return "www.amazon.com" }
switch countryCode.uppercased() {
case "DE": return "www.amazon.de"
case "FR": return "www.amazon.fr"
case "ES": return "www.amazon.es"
case "IT": return "www.amazon.it"
case "GB", "UK": return "www.amazon.co.uk"
case "CA": return "www.amazon.ca"
case "JP": return "www.amazon.co.jp"
case "AU": return "www.amazon.com.au"
case "NL": return "www.amazon.nl"
case "SE": return "www.amazon.se"
case "PL": return "www.amazon.pl"
case "MX": return "www.amazon.com.mx"
case "BR": return "www.amazon.com.br"
case "IN": return "www.amazon.in"
default: return "www.amazon.com"
return AmazonAffiliate.searchURL(query: query, countryCode: info.countryCode)
}
}
}

View File

@@ -1194,9 +1194,8 @@ private struct SystemBillOfMaterialsView: View {
case .affiliate(let url):
return url
case .amazonSearch(let query):
guard let encoded = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return nil }
let domain = amazonDomain(for: load.affiliateCountryCode ?? Locale.current.regionCode)
return URL(string: "https://\(domain)/s?k=\(encoded)")
let countryCode = load.affiliateCountryCode ?? Locale.current.regionCode
return AmazonAffiliate.searchURL(query: query, countryCode: countryCode)
}
}
@@ -1234,28 +1233,6 @@ private struct SystemBillOfMaterialsView: View {
completedItemIDs = Set(keys)
}
private func amazonDomain(for countryCode: String?) -> String {
guard let code = countryCode?.uppercased() else { return "www.amazon.com" }
switch code {
case "DE": return "www.amazon.de"
case "FR": return "www.amazon.fr"
case "ES": return "www.amazon.es"
case "IT": return "www.amazon.it"
case "GB", "UK": return "www.amazon.co.uk"
case "CA": return "www.amazon.ca"
case "JP": return "www.amazon.co.jp"
case "AU": return "www.amazon.com.au"
case "NL": return "www.amazon.nl"
case "SE": return "www.amazon.se"
case "PL": return "www.amazon.pl"
case "MX": return "www.amazon.com.mx"
case "BR": return "www.amazon.com.br"
case "IN": return "www.amazon.in"
default: return "www.amazon.com"
}
}
private func recommendedFuse(for load: SavedLoad) -> Int {
let targetFuse = load.current * 1.25
let standardFuses = [1, 2, 3, 5, 7, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 100, 125, 150, 175, 200, 225, 250, 300, 350, 400, 450, 500, 600, 700, 800]