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 pathWordPressComServiceRemote+SiteSegments.swift
More file actions
138 lines (118 loc) · 4.8 KB
/
Copy pathWordPressComServiceRemote+SiteSegments.swift
File metadata and controls
138 lines (118 loc) · 4.8 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
131
132
133
134
135
136
137
138
/// Models a type of site.
public struct SiteSegment {
public let identifier: Int64 // we use a numeric ID for segments; see p9wMUP-bH-612-p2 for discussion
public let title: String
public let subtitle: String
public let icon: URL?
public let iconColor: String?
public let mobile: Bool
public init(identifier: Int64, title: String, subtitle: String, icon: URL?, iconColor: String?, mobile: Bool) {
self.identifier = identifier
self.title = title
self.subtitle = subtitle
self.icon = icon
self.iconColor = iconColor
self.mobile = mobile
}
}
extension SiteSegment: Equatable {
public static func ==(lhs: SiteSegment, rhs: SiteSegment) -> Bool {
return lhs.identifier == rhs.identifier
}
}
extension SiteSegment: Decodable {
enum CodingKeys: String, CodingKey {
case segmentId = "id"
case segmentTypeTitle = "segment_type_title"
case segmentTypeSubtitle = "segment_type_subtitle"
case iconURL = "icon_URL"
case iconColor = "icon_color"
case mobile = "mobile"
}
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
identifier = try values.decode(Int64.self, forKey: .segmentId)
title = try values.decode(String.self, forKey: .segmentTypeTitle)
subtitle = try values.decode(String.self, forKey: .segmentTypeSubtitle)
if let iconString = try values.decodeIfPresent(String.self, forKey: .iconURL) {
icon = URL(string: iconString)
} else {
icon = nil
}
if let iconColorString = try values.decodeIfPresent(String.self, forKey: .iconColor) {
var cleanIconColorString = iconColorString
if iconColorString.hasPrefix("#") {
cleanIconColorString = String(iconColorString.dropFirst(1))
}
iconColor = cleanIconColorString
} else {
iconColor = nil
}
mobile = try values.decode(Bool.self, forKey: .mobile)
}
}
// MARK: - WordPressComServiceRemote (Site Segments)
/// Describes the errors that could arise when searching for site verticals.
///
/// - requestEncodingFailure: unable to encode the request parameters.
/// - responseDecodingFailure: unable to decode the server response.
/// - serviceFailure: the service returned an unexpected error.
///
public enum SiteSegmentsError: Error {
case requestEncodingFailure
case responseDecodingFailure
case serviceFailure
}
/// Advises the caller of results related to requests for site segments.
///
/// - success: the site segments request succeeded with the accompanying result.
/// - failure: the site segments request failed due to the accompanying error.
///
@frozen public enum SiteSegmentsResult {
case success([SiteSegment])
case failure(SiteSegmentsError)
}
public typealias SiteSegmentsServiceCompletion = (SiteSegmentsResult) -> Void
/// Site segments service, exclusive to WordPress.com.
///
public extension WordPressComServiceRemote {
func retrieveSegments(completion: @escaping SiteSegmentsServiceCompletion) {
let endpoint = "segments"
let remotePath = path(forEndpoint: endpoint, withVersion: ._2_0)
wordPressComRESTAPI.get(
remotePath,
parameters: nil,
success: { [weak self] responseObject, httpResponse in
WPKitLogInfo("\(responseObject) | \(String(describing: httpResponse))")
guard let self = self else {
return
}
do {
let response = try self.decodeResponse(responseObject: responseObject)
let validContent = self.validSegments(response)
completion(.success(validContent))
} catch {
WPKitLogError("Failed to decode \([SiteVertical].self) : \(error.localizedDescription)")
completion(.failure(SiteSegmentsError.responseDecodingFailure))
}
},
failure: { error, httpResponse in
WPKitLogError("\(error) | \(String(describing: httpResponse))")
completion(.failure(SiteSegmentsError.serviceFailure))
})
}
}
// MARK: - Serialization support
private extension WordPressComServiceRemote {
private func decodeResponse(responseObject: Any) throws -> [SiteSegment] {
let decoder = JSONDecoder()
let data = try JSONSerialization.data(withJSONObject: responseObject, options: [])
let response = try decoder.decode([SiteSegment].self, from: data)
return response
}
private func validSegments(_ allSegments: [SiteSegment]) -> [SiteSegment] {
return allSegments.filter {
return $0.mobile == true
}
}
}