Skip to content

Commit

Permalink
API処理をConcurrency対応
Browse files Browse the repository at this point in the history
  • Loading branch information
KaitoMuraoka committed Nov 18, 2024
1 parent 8dfef40 commit 5374bb4
Showing 1 changed file with 32 additions and 43 deletions.
75 changes: 32 additions & 43 deletions Osushi/Model/APIModelData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,76 +17,65 @@ final class APIModelData: ObservableObject {
]

func fetchPostsIfNeeded() {
let now: Date = .now
if let lastFetchDate {
guard now.timeIntervalSince(lastFetchDate) > fetchThresholdSeconds else {
print("取得できませんでした。:\(now.timeIntervalSince(lastFetchDate))")
return
Task {
let now: Date = .now
if let lastFetchDate {
guard now.timeIntervalSince(lastFetchDate) > fetchThresholdSeconds else {
print("取得できませんでした。:\(now.timeIntervalSince(lastFetchDate))")
return
}
}
await fetchPosts()
lastFetchDate = now
}
fetchPosts()
lastFetchDate = now
}

private func fetchPosts() {
@MainActor
private func fetchPosts() async {
markdownContent.removeAll()
guard var url = URL(string: Url.osushiApi) else { return }
url.append(queryItems: APIModelData.githubApiQuery)

URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
guard let data, let self else { return }
if let error {
// TODO: エラー処理をここに記述
DispatchQueue.main.async {
self.errorMessage = "API Request Failed: \(error.localizedDescription)"
}
return
}
do {
let (data, _) = try await URLSession.shared.data(from: url)

// APIエラーレスポンスのハンドリング
if let rateLimitError = try? self.decoder.decode(RateLimitError.self, from: data) {
DispatchQueue.main.async {
self.errorMessage = rateLimitError.message
}
if let rateLimitError = try? decoder.decode(RateLimitError.self, from: data) {
errorMessage = rateLimitError.message
return
}

if let response = try? self.decoder.decode([Post].self, from: data) {
DispatchQueue.main.async {
if let response = try? decoder.decode([Post].self, from: data) {
// TaskGroupを使用して並列処理する
await withTaskGroup(of: Void.self) { group in
for post in response {
self.fetchDownloadUrl(post.downloadUrl)
group.addTask {
await self.fetchDownloadUrl(post.downloadUrl)
}
}
}
return
}
} catch {
errorMessage = "API Request Failed: \(error.localizedDescription)"
}
.resume()
}

private func fetchDownloadUrl(_ downloadUrl: String) {
@MainActor
private func fetchDownloadUrl(_ downloadUrl: String) async {
if downloadUrl == Url.indexDownload { return }
guard let url = URL(string: downloadUrl) else {
fatalError("Invalid Url")
}

URLSession.shared.dataTask(with: url) { data, response, error in
guard let data else { return }
if let error {
fatalError("API Request Failed: \(error.localizedDescription)")
}

if let markdownString = String(data: data, encoding: .utf8) {
DispatchQueue.main.async {
if markdownString.starts(with: " ") { return }
self.markdownContent.append(markdownString)
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
let markdownString = String(decoding: data, as: UTF8.self)
guard markdownString.starts(with: " ") else {
markdownContent.append(markdownString)
return
} else {
self.markdownContent.append("**エラー**")
// TODO: アラートを表示
print("Error fetching markdown content: \(error?.localizedDescription ?? "Unknown error")")
}
} catch {
fatalError("API Request Failed: \(error.localizedDescription)")
}
.resume()
}
}

0 comments on commit 5374bb4

Please sign in to comment.