// // NetworkServiceAPITable.swift // Wallet // // Created by Igor on 05.11.2020. // Copyright © 2020 List. All rights reserved. // import EosioSwift import PromiseKit import Foundation extension Network.Service.Table { typealias EncodeType = EosioRpcTableRowsRequest.EncodeType } extension Network.Service { class Table: Common.Service.Provider {} } extension Network.Service.Table { func fetch( endpoint: String = ApplicationEnvironment.shared().current.node.orCreate(""), code: String, table: String, scope: String, limit: Int = 10000, encodeType: EncodeType = .dec, reverse: Bool? = nil, showPayer: Bool? = nil, keyType: String? = nil, indexPosition: String = "1", lowerBound: String? = nil, upperBound: String? = nil, exclude: [String] = [], fieldName: String? = nil, type: T.Type ) async -> [T] { let environment = ApplicationEnvironment.shared().current return await withCheckedContinuation({ (continuation: CheckedContinuation<[T], Never>) in EosioRpcProvider(endpoint: URL(string: endpoint)!, headers: environment.headers).getTableRows(requestParameters: EosioRpcTableRowsRequest( scope: scope, code: code, table: table, json: true, limit: UInt32(limit), tableKey: nil, lowerBound: lowerBound, upperBound: upperBound, indexPosition: indexPosition, keyType: keyType, encodeType: encodeType, reverse: reverse, showPayer: showPayer) ) { result in switch result { case let .success(rows): if let fieldName = fieldName { if let rows = rows.rows as? [[String: Any]] { continuation.resume(returning: rows.compactMap({ $0[fieldName] as? T })) } else { continuation.resume(returning: []) } } else { if let rows = rows.rows as? [[String: Any]], let data = rows.jsonString?.data(using: .utf8), let collection = try? JSONDecoder().decode([T].self, from: data) { continuation.resume(returning: collection) } else { continuation.resume(returning: []) } } case let .failure(error): print(error) print(error.reason) var exclude = exclude exclude.append(endpoint) if let node = ApplicationEnvironment.shared().current.nodes.filter({ !exclude.contains($0) }).first { self.fetch( endpoint: node, code: code, table: table, scope: scope, limit: limit, encodeType: encodeType, reverse: reverse, showPayer: showPayer, keyType: keyType, indexPosition: indexPosition, lowerBound: lowerBound, upperBound: upperBound, exclude: exclude, type: type, completion: continuation.resume ) } else { continuation.resume(returning: []) } } } }) } func fetch( endpoint: String = ApplicationEnvironment.shared().current.node.orCreate(""), code: String, table: String, scope: String, limit: Int = 10000, encodeType: EncodeType = .dec, reverse: Bool? = nil, showPayer: Bool? = nil, keyType: String? = nil, indexPosition: String = "1", lowerBound: String? = nil, upperBound: String? = nil, exclude: [String] = [], fieldName: String? = nil, type: T.Type, completion: @escaping ([T]) -> Void ) { guard let url = URL(string: endpoint) else { completion([]) return } let environment = ApplicationEnvironment.shared().current EosioRpcProvider(endpoint: url, headers: environment.headers).getTableRows(requestParameters: EosioRpcTableRowsRequest( scope: scope, code: code, table: table, json: true, limit: UInt32(limit), tableKey: nil, lowerBound: lowerBound, upperBound: upperBound, indexPosition: indexPosition, keyType: keyType, encodeType: encodeType, reverse: reverse, showPayer: showPayer) ) { result in switch result { case let .success(rows): if let fieldName = fieldName { if let rows = rows.rows as? [[String: Any]] { completion(rows.compactMap({ $0[fieldName] as? T })) } else { completion([]) } } else { if let rows = rows.rows as? [[String: Any]], let data = rows.jsonString?.data(using: .utf8), let collection = try? JSONDecoder().decode([T].self, from: data) { completion(collection) } else { completion([]) } } case let .failure(error): print(error) print(error.reason) var exclude = exclude exclude.append(endpoint) if let node = ApplicationEnvironment.shared().current.nodes.filter({ !exclude.contains($0) }).first { self.fetch( endpoint: node, code: code, table: table, scope: scope, limit: limit, encodeType: encodeType, reverse: reverse, showPayer: showPayer, keyType: keyType, indexPosition: indexPosition, lowerBound: lowerBound, upperBound: upperBound, exclude: exclude, type: type, completion: completion ) } else { completion([]) } } } } }