Skip to content

Commit 50dd477

Browse files
sghctoclaude
andcommitted
Ads: fallback chain — custom domain → workers.dev → GitHub Pages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 47460a1 commit 50dd477

1 file changed

Lines changed: 27 additions & 11 deletions

File tree

Tickr/Services/AdService.swift

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ struct AdsPayload: Codable {
3737
class AdService: ObservableObject {
3838
static let shared = AdService()
3939

40-
private static let remoteURL = "https://h4ux.github.io/Tickr/ads.json"
40+
private static let adEndpoints = [
41+
"https://service.h4ux.com/ads-service",
42+
"https://billowing-term-c225.alon-f46.workers.dev/ads",
43+
"https://h4ux.github.io/Tickr/ads.json",
44+
]
4145

4246
@Published var currentAd: AdContent
4347
@Published var bannerImage: NSImage?
@@ -102,19 +106,31 @@ class AdService: ObservableObject {
102106
}
103107

104108
func fetchAds() {
105-
guard let url = URL(string: Self.remoteURL) else { return }
109+
fetchAdsFromEndpoint(index: 0)
110+
}
106111

107-
URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
108-
guard let self = self,
109-
let data = data,
110-
let payload = try? JSONDecoder().decode(AdsPayload.self, from: data),
111-
!payload.ads.isEmpty else { return }
112+
private func fetchAdsFromEndpoint(index: Int) {
113+
guard index < Self.adEndpoints.count,
114+
let url = URL(string: Self.adEndpoints[index]) else { return }
112115

113-
let matching = payload.ads.filter { $0.matchesCountry(self.userCountry) }
116+
var request = URLRequest(url: url)
117+
request.timeoutInterval = 5
114118

115-
DispatchQueue.main.async {
116-
self.allAds = matching.isEmpty ? payload.ads : matching
117-
self.rotateAd()
119+
URLSession.shared.dataTask(with: request) { [weak self] data, response, _ in
120+
guard let self = self else { return }
121+
let http = response as? HTTPURLResponse
122+
123+
if let data = data, http?.statusCode == 200,
124+
let payload = try? JSONDecoder().decode(AdsPayload.self, from: data),
125+
!payload.ads.isEmpty {
126+
let matching = payload.ads.filter { $0.matchesCountry(self.userCountry) }
127+
DispatchQueue.main.async {
128+
self.allAds = matching.isEmpty ? payload.ads : matching
129+
self.rotateAd()
130+
}
131+
} else {
132+
// Fallback to next endpoint
133+
self.fetchAdsFromEndpoint(index: index + 1)
118134
}
119135
}.resume()
120136
}

0 commit comments

Comments
 (0)