TF-2384 Create TwakeCore in ios folder to handle network jmap request to server
Signed-off-by: dab246 <tdvu@linagora.com> (cherry picked from commit d8a330b987860f133b7e56b4aa67669c9d3c8f20)
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
import Foundation
|
||||
|
||||
struct Email: Codable {
|
||||
let id: String
|
||||
let subject: String?
|
||||
let preview: String?
|
||||
let from: [EmailAddress]?
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import Foundation
|
||||
|
||||
struct EmailAddress: Codable {
|
||||
let name: String?
|
||||
let email: String?
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import Foundation
|
||||
|
||||
struct JmapRequestObject: Codable {
|
||||
let using: [String]
|
||||
let methodCalls: [[RequestInvocation]]
|
||||
}
|
||||
|
||||
enum RequestInvocation: Codable {
|
||||
case methodRequest(MethodRequest)
|
||||
case string(String)
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
if let x = try? container.decode(String.self) {
|
||||
self = .string(x)
|
||||
return
|
||||
}
|
||||
if let x = try? container.decode(MethodRequest.self) {
|
||||
self = .methodRequest(x)
|
||||
return
|
||||
}
|
||||
throw DecodingError.typeMismatch(RequestInvocation.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for RequestInvocation"))
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
switch self {
|
||||
case .methodRequest(let x):
|
||||
try container.encode(x)
|
||||
case .string(let x):
|
||||
try container.encode(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MethodRequest: Codable {
|
||||
let accountId: String
|
||||
let sinceState: String?
|
||||
let ids: ResultReference?
|
||||
let properties: [String]?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case accountId
|
||||
case sinceState
|
||||
case ids = "#ids"
|
||||
case properties
|
||||
}
|
||||
}
|
||||
|
||||
struct ResultReference: Codable {
|
||||
let resultOf, name, path: String
|
||||
}
|
||||
|
||||
extension JmapRequestObject {
|
||||
func toData() -> Data? {
|
||||
if let encodedData = try? JSONEncoder().encode(self) {
|
||||
return encodedData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func toJson() -> String? {
|
||||
if let data = toData(), let jsonString = String(data: data, encoding: .utf8) {
|
||||
return jsonString
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import Foundation
|
||||
|
||||
struct JmapResponseObject<T: Codable>: Codable {
|
||||
let sessionState: String
|
||||
let methodResponses: [[ResponseInvocation<T>]]
|
||||
}
|
||||
|
||||
enum ResponseInvocation<T: Codable>: Codable {
|
||||
case methodResponse(MethodResponse<T>)
|
||||
case string(String)
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
if let x = try? container.decode(String.self) {
|
||||
self = .string(x)
|
||||
return
|
||||
}
|
||||
if let x = try? container.decode(MethodResponse<T>.self) {
|
||||
self = .methodResponse(x)
|
||||
return
|
||||
}
|
||||
throw DecodingError.typeMismatch(ResponseInvocation<T>.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ResponseInvocation"))
|
||||
}
|
||||
|
||||
func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
switch self {
|
||||
case .methodResponse(let x):
|
||||
try container.encode(x)
|
||||
case .string(let x):
|
||||
try container.encode(x)
|
||||
}
|
||||
}
|
||||
|
||||
var listObject: [T]? {
|
||||
switch self {
|
||||
case .methodResponse(let method): return method.list
|
||||
case .string(_): return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MethodResponse<T: Codable>: Codable {
|
||||
let accountId: String
|
||||
let oldState: String?
|
||||
let newState: String?
|
||||
let hasMoreChanges: Bool?
|
||||
let created: [String]?
|
||||
let updated: [String]?
|
||||
let destroyed: [String]?
|
||||
let notFound: [String]?
|
||||
let state: String?
|
||||
let list: [T]?
|
||||
}
|
||||
|
||||
extension JmapResponseObject {
|
||||
func parsing(methodName: String, methodCallId: String) -> [T]? {
|
||||
let invocations = methodResponses.first { (responseInvocations: [ResponseInvocation<T>]) in
|
||||
return responseInvocations.contains { (responseInvocation: ResponseInvocation<T>) in
|
||||
return validateResponseInvocation(response: responseInvocation, methodName: methodName, methodCallId: methodCallId)
|
||||
}
|
||||
}
|
||||
|
||||
if invocations == nil || invocations?.isEmpty == true {
|
||||
return nil
|
||||
} else {
|
||||
let invocation = invocations!.first { response in
|
||||
return validateMethodResponse(response: response)
|
||||
}
|
||||
|
||||
return invocation?.listObject
|
||||
}
|
||||
}
|
||||
|
||||
private func validateResponseInvocation(response: ResponseInvocation<T>, methodName: String, methodCallId: String) -> Bool {
|
||||
switch response {
|
||||
case .string(let stringValue):
|
||||
return stringValue == methodName || stringValue == methodCallId
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func validateMethodResponse(response: ResponseInvocation<T>) -> Bool {
|
||||
switch response {
|
||||
case .methodResponse(_):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user