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 pathNotificationSyncServiceRemote.swift
More file actions
184 lines (155 loc) · 6.82 KB
/
Copy pathNotificationSyncServiceRemote.swift
File metadata and controls
184 lines (155 loc) · 6.82 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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import Foundation
// MARK: - NotificationSyncServiceRemote
//
public class NotificationSyncServiceRemote: ServiceRemoteWordPressComREST {
// MARK: - Constants
//
private let defaultPageSize = 100
// MARK: - Errors
//
public enum SyncError: Error {
case failed
}
public enum InputError: Int, Error {
case notificationIDsNotProvided
}
/// Retrieves latest Notifications (OR collection of Notifications, whenever noteIds is present)
///
/// - Parameters:
/// - pageSize: Number of hashes to retrieve.
/// - noteIds: Identifiers of notifications to retrieve.
/// - completion: callback to be executed on completion.
///
///
public func loadNotes(withPageSize pageSize: Int? = nil, noteIds: [String]? = nil, completion: @escaping ((Error?, [RemoteNotification]?) -> Void)) {
let fields = "id,note_hash,type,unread,body,subject,timestamp,meta"
loadNotes(withNoteIds: noteIds, fields: fields, pageSize: pageSize) { error, notes in
completion(error, notes)
}
}
/// Retrieves the Notification Hashes for the specified pageSize (OR collection of NoteID's, when present)
///
/// - Parameters:
/// - pageSize: Number of hashes to retrieve.
/// - noteIds: Identifiers of notifications to retrieve.
/// - completion: callback to be executed on completion.
///
/// - Notes: The RemoteNotification Entity will only have it's ID + Hash populated
///
public func loadHashes(withPageSize pageSize: Int? = nil, noteIds: [String]? = nil, completion: @escaping ((Error?, [RemoteNotification]?) -> Void)) {
let fields = "id,note_hash"
loadNotes(withNoteIds: noteIds, fields: fields, pageSize: pageSize) { error, notes in
completion(error, notes)
}
}
/// Updates a Notification's Read Status as specified.
///
/// - Parameters:
/// - notificationID: The NotificationID to Mark as Read.
/// - read: The new Read Status to set.
/// - completion: Closure to be executed on completion, indicating whether the OP was successful or not.
///
@objc public func updateReadStatus(_ notificationID: String, read: Bool, completion: @escaping ((Error?) -> Void)) {
updateReadStatusForNotifications([notificationID], read: read, completion: completion)
}
/// Updates an array of Notifications' Read Status as specified.
///
/// - Parameters:
/// - notificationIDs: ID's of Notifications to Mark as Read.
/// - read: The new Read Status to set.
/// - completion: Closure to be executed on completion, indicating whether the OP was successful or not.
///
@objc public func updateReadStatusForNotifications(_ notificationIDs: [String], read: Bool, completion: @escaping ((Error?) -> Void)) {
guard !notificationIDs.isEmpty else {
completion(InputError.notificationIDsNotProvided)
return
}
let path = "notifications/read"
let requestUrl = self.path(forEndpoint: path, withVersion: ._1_1)
// Note: Isn't the API wonderful?
let value = read ? 9999 : -9999
var notifications: [String: Int] = [:]
for notificationID in notificationIDs {
notifications[notificationID] = value
}
let parameters = ["counts": notifications]
wordPressComRESTAPI.post(requestUrl, parameters: parameters as [String: AnyObject]?, success: { (response, _) in
let error = self.errorFromResponse(response)
completion(error)
}, failure: { (error, _) in
completion(error)
})
}
/// Updates the Last Seen Notification's Timestamp.
///
/// - Parameters:
/// - timestamp: Timestamp of the last seen notification.
/// - completion: Closure to be executed on completion, indicating whether the OP was successful or not.
///
@objc public func updateLastSeen(_ timestamp: String, completion: @escaping ((Error?) -> Void)) {
let path = "notifications/seen"
let requestUrl = self.path(forEndpoint: path, withVersion: ._1_1)
let parameters = [
"time": timestamp
]
wordPressComRESTAPI.post(requestUrl, parameters: parameters as [String: AnyObject]?, success: { (response, _) in
let error = self.errorFromResponse(response)
completion(error)
}, failure: { (error, _) in
completion(error)
})
}
}
// MARK: - Private Methods
//
private extension NotificationSyncServiceRemote {
/// Attempts to parse the `success` field of a given response. When it's missing, or it's false,
/// this method will return SyncError.failed.
///
/// - Parameter response: JSON entity , as retrieved from the backend.
///
/// - Returns: SyncError.failed whenever the success field is either missing, or set to false.
///
func errorFromResponse(_ response: Any) -> Error? {
let document = response as? [String: AnyObject]
let success = document?["success"] as? Bool
guard success != true else {
return nil
}
return SyncError.failed
}
/// Retrieves the Notification for the specified pageSize (OR collection of NoteID's, when present).
/// Note that only the specified fields will be retrieved.
///
/// - Parameters:
/// - noteIds: Identifier for the notifications that should be loaded.
/// - fields: List of comma separated fields, to be loaded.
/// - pageSize: Number of notifications to load.
/// - completion: Callback to be executed on completion.
///
func loadNotes(withNoteIds noteIds: [String]? = nil, fields: String? = nil, pageSize: Int?, completion: @escaping ((Error?, [RemoteNotification]?) -> Void)) {
let path = "notifications/"
let requestUrl = self.path(forEndpoint: path, withVersion: ._1_1)
var parameters: [String: AnyObject] = [
"number": pageSize as AnyObject? ?? defaultPageSize as AnyObject
]
if let notificationIds = noteIds {
parameters["ids"] = (notificationIds as NSArray).componentsJoined(by: ",") as AnyObject?
}
if let fields = fields {
parameters["fields"] = fields as AnyObject?
}
wordPressComRESTAPI.get(requestUrl, parameters: parameters, success: { response, _ in
let document = response as? [String: AnyObject]
let notes = document?["notes"] as? [[String: AnyObject]]
let parsed = notes?.compactMap { RemoteNotification(document: $0) }
if let parsed = parsed {
completion(nil, parsed)
} else {
completion(SyncError.failed, nil)
}
}, failure: { error, _ in
completion(error, nil)
})
}
}