This repository was archived by the owner on Sep 15, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathReaderPostServiceRemote+Cards.swift
More file actions
124 lines (111 loc) · 5.46 KB
/
Copy pathReaderPostServiceRemote+Cards.swift
File metadata and controls
124 lines (111 loc) · 5.46 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
public enum ReaderSortingOption: String, CaseIterable {
case popularity
case date
case noSorting
var queryValue: String? {
guard self != .noSorting else {
return nil
}
return rawValue
}
}
public enum ReaderStream: String {
case discover = "discover"
case firstPosts = "first-posts"
}
extension ReaderPostServiceRemote {
/// Returns a collection of RemoteReaderCard using the tags API
/// a Reader Card can represent an item for the reader feed, such as
/// - Reader Post
/// - Topics you may like
/// - Blogs you may like and so on
///
/// - Parameter topics: an array of String representing the topics
/// - Parameter page: a String that represents a page handle
/// - Parameter sortingOption: a ReaderSortingOption that represents a sorting option
/// - Parameter success: Called when the request succeeds and the data returned is valid
/// - Parameter failure: Called if the request fails for any reason, or the response data is invalid
public func fetchCards(for topics: [String],
page: String? = nil,
sortingOption: ReaderSortingOption = .noSorting,
refreshCount: Int? = nil,
success: @escaping ([RemoteReaderCard], String?) -> Void,
failure: @escaping (Error) -> Void) {
let path = "read/tags/cards"
guard let requestUrl = cardsEndpoint(with: path,
topics: topics,
page: page,
sortingOption: sortingOption,
refreshCount: refreshCount) else {
return
}
fetch(requestUrl, success: success, failure: failure)
}
/// Returns a collection of RemoteReaderCard using the discover streams API
/// a Reader Card can represent an item for the reader feed, such as
/// - Reader Post
/// - Topics you may like
/// - Blogs you may like and so on
///
/// - Parameter stream: The name of the stream. By default, `.discover`.
/// - Parameter topics: an array of String representing the topics
/// - Parameter page: a String that represents a page handle
/// - Parameter sortingOption: a ReaderSortingOption that represents a sorting option
/// - Parameter count: the number of cards to fetch. Warning: This also changes the number of objects returned for recommended sites/tags.
/// - Parameter success: Called when the request succeeds and the data returned is valid
/// - Parameter failure: Called if the request fails for any reason, or the response data is invalid
public func fetchStreamCards(stream: ReaderStream = .discover,
for topics: [String],
page: String? = nil,
sortingOption: ReaderSortingOption = .noSorting,
refreshCount: Int? = nil,
count: Int? = nil,
success: @escaping ([RemoteReaderCard], String?) -> Void,
failure: @escaping (Error) -> Void) {
let path = "read/streams/\(stream.rawValue)"
guard let requestUrl = cardsEndpoint(with: path,
topics: topics,
page: page,
sortingOption: sortingOption,
count: count,
refreshCount: refreshCount) else {
return
}
fetch(requestUrl, success: success, failure: failure)
}
private func fetch(_ endpoint: String,
success: @escaping ([RemoteReaderCard], String?) -> Void,
failure: @escaping (Error) -> Void) {
Task { @MainActor [wordPressComRestApi] in
await wordPressComRestApi.perform(.get, URLString: endpoint, type: ReaderCardEnvelope.self)
.map { ($0.body.cards, $0.body.nextPageHandle) }
.mapError { error -> Error in error.asNSError() }
.execute(onSuccess: success, onFailure: failure)
}
}
private func cardsEndpoint(with path: String,
topics: [String],
page: String? = nil,
sortingOption: ReaderSortingOption = .noSorting,
count: Int? = nil,
refreshCount: Int? = nil) -> String? {
var path = URLComponents(string: path)
path?.queryItems = topics.map { URLQueryItem(name: "tags[]", value: $0) }
if let page {
path?.queryItems?.append(URLQueryItem(name: "page_handle", value: page))
}
if let sortingOption = sortingOption.queryValue {
path?.queryItems?.append(URLQueryItem(name: "sort", value: sortingOption))
}
if let count {
path?.queryItems?.append(URLQueryItem(name: "count", value: String(count)))
}
if let refreshCount {
path?.queryItems?.append(URLQueryItem(name: "refresh", value: String(refreshCount)))
}
guard let endpoint = path?.string else {
return nil
}
return self.path(forEndpoint: endpoint, withVersion: ._2_0)
}
}