I a'm working in a old project
This code is not working, can someone tell me what i am doing wrong ? The json is returning from API, but the object is not being created (parsing json to class)
podfile
platform :ios, '10.0'
use_frameworks!
target 'RealTimeBalance' do
pod 'Fabric'
pod 'Crashlytics'
pod 'SwiftLint'
pod 'Alamofire', '~> 4.7'
pod 'ObjectMapper', '~> 3.3'
pod 'AlamofireObjectMapper', '~> 5.0'
pod 'PKHUD', '~> 5.0'
pod 'IQKeyboardManagerSwift'
pod 'SwiftyJSON', '~> 4.0'
pod 'lottie-ios'
pod 'Firebase/Analytics'
pod 'Firebase/Crashlytics'
pod 'Firebase/Messaging'
# Pods for RealTimeBalance
end
post_install do |installer|
installer.pods_project.build_configurations.each do |config|
config.build_settings["EXCLUDED_ARCHS[sdk-iphonesimulator*]"] = "arm64"
end
installer.generated_projects.each do |project|
project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '10.0'
end
end
end
end
// Class ViewController import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
RealTimeBalanceService.getRealTimeBalance(success: { result in
let balance = result
print(result.code)
}, failure: { error in
print("call failure 22")
print(error)
})
}
}
// Class RealTimeBalanceService import Foundation
class RealTimeBalanceService: NSObject {
static func getRealTimeBalance(success: @escaping(_ balance: RealTimeBalance) -> Void,
failure: @escaping(_ error: String) -> Void) {
let request = Router.getAccounts
Network.requestObject(request: request, type: RealTimeBalance.self) { result in
switch result {
case let .success(data):
success(data)
case let .failure( error):
failure(error.localizedDescription)
}
}
}
}
// Class Network.swift
import Foundation
import ObjectMapper
import Alamofire
import AlamofireObjectMapper
import PKHUD
import SwiftyJSON
enum NetworkError: LocalizedError {
case http(error: Error)
case custom(description: String)
case objectSerialization
var errorDescription: String? {
switch self {
case let .http(error): return error.localizedDescription
case let .custom(description): return description
case .objectSerialization: return "Could not serialize JSON into object.."
}
}
}
enum Result<T> {
case success(T)
case failure(NetworkError)
}
enum Router: URLRequestConvertible {
var path: String {
switch self {
case .getAccounts:
return API.Home.getAccounts
}
}
var parameters: Any {
var parameters: [String: Any] = [:]
parameters["username"] = "username"
return parameters
}
var encoding: ParameterEncoding {
switch self {
case .getAccounts:
return URLEncoding.httpBody
}
}
var arrayEncoding: ArrayEncoding {
return ArrayEncoding()
}
var method: HTTPMethod {
switch self {
case .getAccounts:
return .get
}
}
var headers: HTTPHeaders {
var headers: [String: String] = [:]
headers["Content-Type"] = "application/json"
return headers
}
func asURLRequest() throws -> URLRequest {
let url = try API.baseURL.asURL()
var urlRequest = URLRequest(url: url.appendingPathComponent(path.replacingOccurrences(of: "", with: "")))
urlRequest.httpMethod = method.rawValue
urlRequest.allHTTPHeaderFields = headers
urlRequest.timeoutInterval = 60
if let params = self.parameters as? [[String: String]] {
return try arrayEncoding.encode(urlRequest, with: params.asParameters())
}
let params = self.parameters as? [Int]
return try arrayEncoding.encode(urlRequest, with: params?.asParameters() ?? [:])
}
case getAccounts
}
struct API {
struct Home {
static let getAccounts = "/getbalance"
}
static var serverUrl: String {
return "http://localhost:3000"
}
static let baseURL = serverUrl
}
class Network {
class func requestObject<T: Mappable>(request: URLRequestConvertible,
type: T.Type,
completion: @escaping (Result<T>) -> Void) {
Alamofire.request(request)
.responseString(completionHandler: { print($0) })
.responseObject { (response: DataResponse<ObjectResult<T>>) in
//if App.Network.debug { printLog(response) }
switch response.result {
case let .success(value):
let code = response.response?.statusCode ?? 0
if value.success && code >= 200 && code <= 299 {
guard let result = value.result else {
completion(.failure(NetworkError.custom(description: "Unexpected error. Please contact account officer.")))
return
}
completion(.success(result))
} else {
if code == 401 {
if value.type == "sessionExpired" {
//unauthenticated()
return
} else if value.type == "apiAuthenticated" {
//AuthService.fetchAuth(success: { auth in
// Session.shared.auth = auth
requestObject(request: request, type: type, completion: completion)
//}, failure: { error in
// completion(.failure(NetworkError.custom(description: error)))
//})
return
}
}
completion(.failure(NetworkError.custom(description: value.message)))
}
case let .failure(error):
// let code = response.response?statusCode
/*if code == 401
unauthenticated()
return
}*/
completion(.failure(NetworkError.http(error: error)))
}
}
}
}
class ObjectResult<T: Mappable> : BaseResult {
var result: T?
var hasResult: Bool = false
override func mapping(map: Map) {
super.mapping(map: map)
hasResult = map.JSON.contains(where: { $0.key == "Return" })
result <- map["Return"]
}
}
class BaseResult: Mappable {
var type: String = ""
var success: Bool = false
var message: String = ""
init () {
}
required convenience init(map: Map) {
self.init()
self.mapping(map: map)
}
func mapping(map: Map) {
type <- map["Type"]
success <- map["Success"]
message <- map["Message"]
}
}
// Class RealTimeBalance.swift I am suspicious that it is this model that was made wrong
import ObjectMapper
// MARK: - RealTimeBalance
class RealTimeBalance: NSObject, NSCoding, Mappable {
var code: Int?
var data: DataClass?
init(code: Int?, data: DataClass?) {
self.code = code
self.data = data
}
override init() {
}
required init?(map: Map) {
}
required convenience init?(coder aDecoder: NSCoder) {
self.init()
self.code = aDecoder.decodeObject(forKey: "code") as? Int ?? 0
self.data = aDecoder.decodeObject(forKey: "data") as? DataClass
}
func encode(with aCoder: NSCoder) {
aCoder.encode(code, forKey: "code")
aCoder.encode(data, forKey: "data")
}
func mapping(map: Map) {
code <- map["code"]
data <- map["data"]
}
}
// MARK: - DataClass
class DataClass: NSObject, NSCoding, Mappable {
var account: Account?
var balance: Balance?
var balanceSource: String?
init(account: Account?, balance: Balance?, balanceSource: String?) {
self.account = account
self.balance = balance
self.balanceSource = balanceSource
}
override init() {
}
required init?(map: Map) {
}
required convenience init?(coder aDecoder: NSCoder) {
self.init()
self.account = aDecoder.decodeObject(forKey: "account") as? Account
self.balance = aDecoder.decodeObject(forKey: "balance") as? Balance
self.balanceSource = aDecoder.decodeObject(forKey: "balance") as? String
}
func encode(with aCoder: NSCoder) {
aCoder.encode(account, forKey: "account")
aCoder.encode(balance, forKey: "balance")
aCoder.encode(balanceSource, forKey: "balanceSource")
}
func mapping(map: Map) {
account <- map["account"]
balance <- map["balance"]
balanceSource <- map["balanceSource"]
}
}
// MARK: - Account
class Account: NSObject, NSCoding, Mappable {
var accountType, accountNumber: String?
init(accountType: String?, accountNumber: String?) {
self.accountType = accountType
self.accountNumber = accountNumber
}
override init() {
}
required init?(map: Map) {
}
required convenience init?(coder aDecoder: NSCoder) {
self.init()
self.accountType = aDecoder.decodeObject(forKey: "accountType") as? String
self.accountNumber = aDecoder.decodeObject(forKey: "accountNumber") as? String
}
func encode(with aCoder: NSCoder) {
aCoder.encode(accountType, forKey: "accountType")
aCoder.encode(accountNumber, forKey: "accountNumber")
}
func mapping(map: Map) {
accountType <- map["accountType"]
accountNumber <- map["accountNumber"]
}
}
// MARK: - Balance
class Balance: NSObject, NSCoding, Mappable {
var available, current, hold: Double?
init(available: Double?, current: Double?, hold: Double?) {
self.available = available
self.current = current
self.hold = hold
}
override init() {
}
required init?(map: Map) {
}
required convenience init?(coder aDecoder: NSCoder) {
self.init()
self.available = aDecoder.decodeDouble(forKey: "available") as? Double
self.current = aDecoder.decodeDouble(forKey: "current") as? Double
self.hold = aDecoder.decodeDouble(forKey: "hold") as? Double
}
func encode(with aCoder: NSCoder) {
aCoder.encode(available, forKey: "available")
aCoder.encode(current, forKey: "current")
aCoder.encode(hold, forKey: "hold")
}
func mapping(map: Map) {
available <- map["available"]
current <- map["current"]
hold <- map["hold"]
}
}
// Array Extension
import Foundation
import Alamofire
extension Array {
func asParameters() -> Parameters {
let arrayParametersKey = "arrayParametersKey"
return [arrayParametersKey: self]
}
}
// Class ArrayEncoding.swift
import Foundation
import Alamofire
struct ArrayEncoding: ParameterEncoding {
public let options: JSONSerialization.WritingOptions
public init(options: JSONSerialization.WritingOptions = []) {
self.options = options
}
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
let arrayParametersKey = "arrayParametersKey"
var urlRequest = try urlRequest.asURLRequest()
guard let parameters = parameters,
let array = parameters[arrayParametersKey] else {
return urlRequest
}
do {
let data = try JSONSerialization.data(withJSONObject: array, options: options)
if urlRequest.value(forHTTPHeaderField: "Content.Type") == nil {
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
}
urlRequest.httpBody = data
} catch {
throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error))
}
return urlRequest
}
}
the json
{
"code": 0,
"data": {
"account": {
"accountType": "String",
"accountNumber": "String"
},
"balance": {
"available": 5.0,
"current": 5.0,
"hold": 5.0
},
"balanceSource": "string"
}
}