-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWebPageRepositoryImpl.swift
More file actions
130 lines (111 loc) · 3.84 KB
/
WebPageRepositoryImpl.swift
File metadata and controls
130 lines (111 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//
// WebPageRepositoryImpl.swift
// DevLog
//
// Created by 최윤진 on 2/8/26.
//
import Foundation
import UIKit
final class WebPageRepositoryImpl: WebPageRepository {
private let webPageService: WebPageService
private let metadataService: WebPageMetadataService
init(
webPageService: WebPageService,
metadataService: WebPageMetadataService
) {
self.webPageService = webPageService
self.metadataService = metadataService
}
func fetch(_ query: String) async throws -> [WebPage] {
let responses = try await webPageService.fetchWebPages(query)
var pages: [WebPage] = []
pages.reserveCapacity(responses.count)
for response in responses {
if await needsImageRestore(response) {
if let restored = try? await restoreWebPage(response) {
pages.append(restored)
} else if let page = try? responseWithoutImage(response).toDomain() {
pages.append(page)
}
continue
}
if let page = try? response.toDomain() {
pages.append(page)
}
}
return pages
}
func upsert(_ urlString: String) async throws {
let metadata = try await metadataService.fetchMetadata(from: urlString)
let request = WebPageRequest(
title: metadata.title,
url: urlString,
displayURL: metadata.displayURL,
imageURL: metadata.imageURL,
isDeleted: false
)
try await webPageService.upsertWebPage(request)
}
func delete(_ urlString: String) async throws {
try await webPageService.deleteWebPage(urlString)
await metadataService.removeCachedImage(for: urlString)
}
func undoDelete(_ urlString: String) async throws {
try await webPageService.undoDeleteWebPage(urlString)
}
}
private extension WebPageRepositoryImpl {
func needsImageRestore(_ response: WebPageResponse) async -> Bool {
guard !response.imageURL.isEmpty,
let imageURL = URL(string: response.imageURL),
imageURL.isFileURL else {
return false
}
let expectedImageURL: URL
do {
expectedImageURL = try metadataService.cachedImageURL(for: response.url)
} catch {
return true
}
if imageURL.standardizedFileURL != expectedImageURL.standardizedFileURL {
return true
}
return await Task.detached(priority: .utility) {
guard FileManager.default.fileExists(atPath: imageURL.path) else {
return true
}
guard let imageData = try? Data(contentsOf: imageURL) else {
return true
}
return UIImage(data: imageData) == nil
}.value
}
func restoreWebPage(_ response: WebPageResponse) async throws -> WebPage? {
let metadata = try await metadataService.fetchMetadata(from: response.url)
let request = WebPageRequest(
title: metadata.title,
url: response.url,
displayURL: metadata.displayURL,
imageURL: metadata.imageURL,
isDeleted: false
)
try await webPageService.upsertWebPage(request)
let newResponse = WebPageResponse(
id: response.id,
title: metadata.title,
url: response.url,
displayURL: metadata.displayURL,
imageURL: metadata.imageURL
)
return try? newResponse.toDomain()
}
func responseWithoutImage(_ response: WebPageResponse) -> WebPageResponse {
WebPageResponse(
id: response.id,
title: response.title,
url: response.url,
displayURL: response.displayURL,
imageURL: ""
)
}
}