TF-2384 Handle hasMoreChange when get email changes in push notification

(cherry picked from commit 5477675671fa62a1d680e655e6a4e9f3ea09df51)
This commit is contained in:
dab246
2023-12-25 12:23:18 +07:00
committed by Dat H. Pham
parent ff3af007e0
commit a003331ee3
5 changed files with 104 additions and 52 deletions
+46 -7
View File
@@ -9,6 +9,11 @@ class JmapClient {
private var authentication: Authentication?
private var tokenRefreshManager: TokenRefreshManager?
private var authenticationInterceptor: AuthenticationInterceptor?
private var hasMoreChanges: Bool = true
private var currentSinceState: String?
private var totalListEmails = [Email]()
private var listErrors = [Error]()
func getNewEmails(
apiUrl: String,
@@ -19,8 +24,7 @@ class JmapClient {
basicAuth: String?,
tokenEndpointUrl: String?,
oidcScopes: [String]?,
onSuccess: @escaping ([Email]) -> Void,
onFailure: @escaping (Error) -> Void
onComplete: @escaping ([Email], [Error]) -> Void
) {
if (authenticationType == AuthenticationType.basic) {
authentication = AuthenticationCredential(
@@ -47,7 +51,26 @@ class JmapClient {
accountId: accountId,
tokenRefreshManager: tokenRefreshManager
)
hasMoreChanges = true
currentSinceState = sinceState
totalListEmails = [Email]()
listErrors = [Error]()
self.handleGetEmailChanges(
apiUrl: apiUrl,
accountId: accountId,
onComplete: onComplete
)
}
private func handleGetEmailChanges(apiUrl: String,
accountId: String,
onComplete: @escaping ([Email], [Error]) -> Void) {
guard hasMoreChanges, let sinceState = currentSinceState else {
return onComplete(self.totalListEmails, self.listErrors)
}
let jmapRequestObject = JmapRequestGenerator.shared.createEmailChangesRequest(
accountId: accountId,
sinceState: sinceState
@@ -59,13 +82,29 @@ class JmapClient {
headers: HTTPHeaders([jmapHeader]),
interceptor: authenticationInterceptor,
onSuccess: { (data: JmapResponseObject<Email>) in
if let listEmail = data.parsing(methodName: JmapConstants.EMAIL_GET_METHOD_NAME, methodCallId: "c1"), !listEmail.isEmpty {
onSuccess(listEmail)
if let response = data.parsing(methodName: JmapConstants.EMAIL_GET_METHOD_NAME, methodCallId: "c1") {
if let listEmail = response.list, !listEmail.isEmpty {
self.totalListEmails.append(contentsOf: listEmail)
}
self.hasMoreChanges = response.hasMoreChanges ?? false
self.currentSinceState = response.newState
self.handleGetEmailChanges(apiUrl: apiUrl, accountId: accountId, onComplete: onComplete)
} else {
onFailure(JmapExceptions.notFoundNewEmails)
self.listErrors.append(JmapExceptions.notFoundNewEmails)
self.hasMoreChanges = false
self.currentSinceState = nil
onComplete(self.totalListEmails, self.listErrors)
}
},
onFailure: onFailure
onFailure: { error in
self.listErrors.append(error)
self.hasMoreChanges = false
self.currentSinceState = nil
onComplete(self.totalListEmails, self.listErrors)
}
)
}
}
@@ -38,6 +38,13 @@ enum ResponseInvocation<T: Codable>: Codable {
case .string(_): return nil
}
}
var response: MethodResponse<T>? {
switch self {
case .methodResponse(let method): return method
case .string(_): return nil
}
}
}
struct MethodResponse<T: Codable>: Codable {
@@ -54,7 +61,7 @@ struct MethodResponse<T: Codable>: Codable {
}
extension JmapResponseObject {
func parsing(methodName: String, methodCallId: String) -> [T]? {
func parsing(methodName: String, methodCallId: String) -> MethodResponse<T>? {
let invocations = methodResponses.first { (responseInvocations: [ResponseInvocation<T>]) in
return responseInvocations.contains { (responseInvocation: ResponseInvocation<T>) in
return validateResponseInvocation(response: responseInvocation, methodName: methodName, methodCallId: methodCallId)
@@ -68,7 +75,7 @@ extension JmapResponseObject {
return validateMethodResponse(response: response)
}
return invocation?.listObject
return invocation?.response
}
}
+9 -7
View File
@@ -19,13 +19,15 @@ class AlamofireService {
request.httpBody = payloadData
AF.request(request, interceptor: interceptor).validate().responseDecodable(of: T.self) { response in
switch(response.result) {
case .success(let data):
onSuccess(data)
case .failure(let error):
onFailure(NetworkExceptions(value: "\(error.localizedDescription)"))
AF.request(request, interceptor: interceptor)
.validate()
.responseDecodable(of: T.self, queue: .global(qos: .default)) { response in
switch(response.result) {
case .success(let data):
onSuccess(data)
case .failure(let error):
onFailure(NetworkExceptions(value: "\(error.localizedDescription)"))
}
}
}
}
}
+11 -10
View File
@@ -53,17 +53,18 @@ class TokenRefreshManager {
request.httpBody = data
AF.request(request).responseDecodable(of: TokenResponse.self) { response in
if (response.response?.statusCode != 200) {
onFailure(NetworkExceptions(value: "Failed to get token: \(response.error?.localizedDescription ?? "Unknown Error")"))
} else {
switch(response.result) {
case .success(let data):
onSuccess(data)
case .failure(let error):
onFailure(NetworkExceptions(value: "Failed to get token \(error.localizedDescription)"))
AF.request(request)
.responseDecodable(of: TokenResponse.self, queue: .global(qos: .default)) { response in
if (response.response?.statusCode != 200) {
onFailure(NetworkExceptions(value: "Failed to get token: \(response.error?.localizedDescription ?? "Unknown Error")"))
} else {
switch(response.result) {
case .success(let data):
onSuccess(data)
case .failure(let error):
onFailure(NetworkExceptions(value: "Failed to get token \(error.localizedDescription)"))
}
}
}
}
}
}