JSON не разбирается - PullRequest
       19

JSON не разбирается

0 голосов
/ 10 января 2019

Я очень плохо знаком с сайтом и ios, сам json и столкнулся с ошибкой, которую я не смог устранить. Я разбирал вложенную строку json, используя структурированные и кодируемые, но дал мне ошибку потока, но скомпилировал просто отлично.

ниже строка json

let jsonString = """
{
"status": "success",
"data": {
"deliveryBoyConfig": {
"id": "1079",
"fname": "Anish",
"lname": "mix",
"country_code": "+91",
"mobile": "9999043499",
"email": "abc@gmail.com",
"address": "delhi INDIA",
"userid": "9",
"imei_number": "357729053845270",
"last_update": null,
"post_id": null,
"capacity": null,
"geo_latitude": "29",
"geo_longitude": "77.1545846",
"geo_radius": "500",
"insert_datetime": "2018-02-03 08:01:26",
"update_datetime": null,
"orig_id": "1079",
"is_otp": "0",
"img_path": null,
"device_token": null,
"flag": null,
"osVersion": null,
"appVersion": null,
"latitude": "28.7039558",
"longitude": "77.1591989",
"timestamp": "1466845730469",
"duty_status": "1",
"battery": "0.49000000953674316",
"charging": "0",
"speed": "0",
"distance": "0",
"geofence_id": null,
"monthly_fix_earning": "0",
"daily_fix_earning": "0",
"reimbursement_per_km": "0",
"monthly_revenue_target": "0",
"monthly_task_target": "0",
"monthly_carrying_capacity": "0",
"emp_is_active": "1",
"emp_used_leaves": 365,
"emp_remaining_leaves": -365,
"emp_total_leaves": "0"
},
"userConfig":
{
"id": "9",
"companyname": "Roadcast",
"custom_logo": "https://test.roadcast.co.in/webserviceos_followme_api/userimages/1525348697_121x33-web.png",
"latitude": "28.7040795",
"longitude": "77.1591007",
"google_address": "RoadCast, Shaheed Udham Singh Marg, Shalimar Bagh, Delhi, India",
"timezone": "Asia/Kolkata",
"rc_users_id": "9",
"is_callback": "1",
"url_callback_base": "64456",
"url_callback_accept": "646546",
"url_callback_dispatch": "6567778",
"url_callback_complete": "7979897",
"url_callback_tracking": "987757b",
"url_callback_reject": "7567546758b",
"url_key_name": "usudfsdfsdf",
"url_key": "2323",
"notes": "7667",
"url_auth_key": "5666",
"sms_dispatch": "1",
"m_complete_popup": "ROADCAST",
"is_cash_inhand_auto_approve": "0",
"deliv_proof_compulsory": "1",
"cash_inhand_proof": "1",
"allow_cancel_from_app": "1",
"hide_pickup_amt": "0",
"auto_attendance": "0",
"auto_attendance_in": "IN",
"auto_attendance_out": "OUT",
"battery_optimization": "24",
"ttf_report": "1",
"ttf_for_dispatch": "1",
"ttf_time": "5",
"web_location": "1",
"kpi_attendance_in": "00:00:00",
"kpi_attendance_out": "00:00:00",
"kpi_duty_hours": "",
"kpi_distance_per_day": null,
"kpi_min_kms": null,
"kpi_max_idle_time": null,
"kpi_within_geofence": "0",
"kpi_outside_geofence": "0",
"kpi_min_orders": "10",
"kpi_max_orders": "10",
"kpi_def_deliv_time": null,
"kpi_delayed_orders": null,
"emp_limit": "5",
"shift_max_hours": "103",
"reset_shift_after": "2",
"shift_enable": "0",
"url_header_api_key_name": null,
"url_header_api_key": null,
"default_order_type": "D",
"extra_order_fields": "1",
"ord_fields_json": "[]",
"show_unique_fields": "1",
"show_stores": "0",
"currency": "INR",
"pod_upload_limit": "10",
"order_fields_names": "{\"pickupcheckbox\":0,\"deliverycheckbox\":0,\"additems\":\"ADD ITEMS\",\"delivery\":\"delivery\",\"pickup\":\"PICK-UP\",\"both\":\"Both\",\"additionalnotes\":\"Additional notes\",\"orderNumber\":\"Order No\",\"billAmount\":\"Bill amount\",\"orderType\":\"Order type\",\"custNameDeliv\":\"Customer name\",\"custMobileDeliv\":\"Customer Mobile\",\"custAddDeliv\":\"Customer address\",\"custAddDelivGgl\":\"Customer address Google\",\"paymentReceivedDeliv\":\"Payment received\",\"assignTo\":\"Assign order to\",\"custMobilePickup\":\"Customer Mobile\",\"custAddPickup\":\"Customer address\",\"custAddPickupGgl\":\"Customer address Google\",\"paymentReceivedPickup\":\"Payment received\",\"custNamePickup\":\"Customer name\",\"delivery_time\":\"Delivery time\",\"pickup_time\":\"Pick time\",\"deliver_by\":\"Deliver by\",\"pickup_by\":\"Pickup by\",\"assigned_at\":\"Assigned at\",\"dispatch_order_pickup\":\"Dispatch Order\",\"collect_payment_pickup\":\"Collect Payment\",\"incomplete_task_pickup\":\"Complete Delivery\",\"dispatch_order_delivery\":\"Dispatch Order\",\"collect_payment_delivery\":\"Collect Payment\",\"incomplete_task_delivery\":\"Complete Delivery\",\"order_progress_dispatch\":\"Dispatch\",\"order_progress_completed\":\"Completed\",\"order_progress_pickup_completed\":\"Completed\",\"order_progress_accepted\":\"Accepted\",\"select_customer\":\"Select Customer\",\"dispatch_completed_delivery\":\"Dispatch completed delivery\",\"dispatch_completed_pickup\":\"Dispatch completed pickup\",\"payment_completed_delivery\":\"Payment completed delivery\",\"payment_completed_pickup\":\"Dispatch completed pickup\",\"task_completed_delivery\":\"Task completed delivery\",\"task_completed_pickup\":\"Task completed delivery\",\"default_dispatch_pickup\":\"Default dispatch pickup\"}",
"page_access_settings": "[{\"id\":9,\"priv\":[0,1]},{\"id\":766,\"priv\":[0,1]}]",
"marker_input_field": "{\"name\":\"\",\"type\":\"dropdown\",\"options\":[{\"name\":\"sdf\",\"color\":\"#0F9595\"}]}",
"auto_gen_ord_no": "0",
"auto_gen_ord_prefix": "RC",
"is_payment_available": "1",
"show_create_order": "1",
"duty_config": "1",
"tracking_type": "0",
"interval_tracking_time": "10",
"sms_comp_name": "ssdf",
"sms_callcenter_no": "2323233232",
"uniqueCompanyName": "bbbbbbb",
"auto_complete_ord": "0",
"auto_complete_ord_val": "{\"time\":\"1\",\"accepted\":0,\"unassigned\":0,\"notaccepted\":0,\"all\":0}",
"auto_dispatch_ord": "0",
"auto_dispatch_time": "1",
"enable_idle_time": "0",
"idle_time_val": "1",
"show_sales_management": "1",
"expense_types": "[]",
"sales_task_prefix": "task1234",
"show_distance_module": "1",
"auto_complete_stask": "0",
"auto_complete_stask_val": "1",
"create_stask_backdate": "1",
"create_stask_backdate_val": "1",
"route_plan_visibility_val": "1",
"route_plan_visibility_type": "M",
"route_plan_is_freeze": "1",
"holiday_calendar_type": "",
"holiday_max_in_late_status": "0",
"holiday_max_in_late_value": "04:30",
"holiday_max_in_half_status": "0",
"holiday_max_in_half_value": "05:00",
"holiday_max_out_status": "0",
"holiday_max_out_value": "15:30",
"holiday_min_hours_status": "0",
"holiday_min_hours_value": "5",
"holiday_approval_date_limit_status": "0",
"holiday_approval_date_limit_value": "1",
"holiday_approval_required_status": "0",
"leave_types": "[\"Privilege leave\",\"Casual Leave\",\"Travel Leave\",\"medical leave\"]",
"enable_leave_types": "0",
"holiday_weekend": "[\"sunday\"]",
"emp_total_leaves": "0",
"late_equi_half_status": "0",
"late_equi_half_value": "2",
"transport_mode_input_field": "{\"name\":\"Transport Mode\",\"type\":\"text\"}",
"show_custom_form": "1",
"enable_receipt_sharing": "1",
"customer_types": "[\"Customer\",\"Buyer\",\"Seller\",\"seller2\",\"customer\",\"Test\",\"Retailer\"]"
}
},
"message": "OK"
}

"" "

ниже приведены структуры, которые я использую

class JSONNull: Codable, Hashable {

public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
    return true
}

public var hashValue: Int {
    return 0
}

public init() {}

public required init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()
    if !container.decodeNil() {
        throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
    }
}

public func encode(to encoder: Encoder) throws {
    var container = encoder.singleValueContainer()
    try container.encodeNil()
}
}


struct Welcome: Codable {
    let status: String
    let data: DataClass
    let message: String
}

struct DataClass: Codable {
    let deliveryBoyConfig: DeliveryBoyConfig
    let userConfig: [String: String?]
}

struct DeliveryBoyConfig: Codable {
    let id, fname, lname, countryCode: String
    let mobile, email, address, userid: String
    let imeiNumber: String
    let lastUpdate, postID, capacity: JSONNull?
    let geoLatitude, geoLongitude, geoRadius, insertDatetime: String
    let updateDatetime: JSONNull?
    let origID, isOtp: String
    let imgPath, deviceToken, flag, osVersion: JSONNull?
    let appVersion: JSONNull?
    let latitude, longitude, timestamp, dutyStatus: String
    let battery, charging, speed, distance: String
    let geofenceID: JSONNull?
    let monthlyFixEarning, dailyFixEarning, reimbursementPerKM, monthlyRevenueTarget: String
    let monthlyTaskTarget, monthlyCarryingCapacity, empIsActive: String
    let empUsedLeaves, empRemainingLeaves: Int
    let empTotalLeaves: String

    enum CodingKeys: String, CodingKey {
        case id, fname, lname
        case countryCode = "country_code"
        case mobile, email, address, userid
        case imeiNumber = "imei_number"
        case lastUpdate = "last_update"
        case postID = "post_id"
        case capacity
        case geoLatitude = "geo_latitude"
        case geoLongitude = "geo_longitude"
        case geoRadius = "geo_radius"
        case insertDatetime = "insert_datetime"
        case updateDatetime = "update_datetime"
        case origID = "orig_id"
        case isOtp = "is_otp"
        case imgPath = "img_path"
        case deviceToken = "device_token"
        case flag, osVersion, appVersion, latitude, longitude, timestamp
        case dutyStatus = "duty_status"
        case battery, charging, speed, distance
        case geofenceID = "geofence_id"
        case monthlyFixEarning = "monthly_fix_earning"
        case dailyFixEarning = "daily_fix_earning"
        case reimbursementPerKM = "reimbursement_per_km"
        case monthlyRevenueTarget = "monthly_revenue_target"
        case monthlyTaskTarget = "monthly_task_target"
        case monthlyCarryingCapacity = "monthly_carrying_capacity"
        case empIsActive = "emp_is_active"
        case empUsedLeaves = "emp_used_leaves"
        case empRemainingLeaves = "emp_remaining_leaves"
        case empTotalLeaves = "emp_total_leaves"
    }
}

и я разбираю его, используя метод ниже

 func jsonOne(){

    do{
    let jsonData = Data(jsonString.utf8)
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let encoder = JSONEncoder()
    let habla = try! decoder.decode(Welcome.self, from : jsonData)

    print(habla)

        let x = habla.data.deliveryBoyConfig.address ; print(x)
        let y  = habla.data.userConfig ; print(y)

    } catch{  print("bad json")  }
}

1 Ответ

0 голосов
/ 10 января 2019

Вы можете использовать приведенный ниже код для анализа вашего JSON с кодируемым протоколом.

Как его инициализировать:

do{
    let myCustomJSON = try MyCustomJSON(json)
}catch{
    return
}

Классы моделей:

  class MyCustomJSON: Codable {
    let status: String
    let data: DataClass
    let message: String

    enum CodingKeys: String, CodingKey {
        case status = "status"
        case data = "data"
        case message = "message"
    }

    init(status: String, data: DataClass, message: String) {
        self.status = status
        self.data = data
        self.message = message
    }
}

class DataClass: Codable {
    let deliveryBoyConfig: DeliveryBoyConfig
    let userConfig: [String: String?]

    enum CodingKeys: String, CodingKey {
        case deliveryBoyConfig = "deliveryBoyConfig"
        case userConfig = "userConfig"
    }

    init(deliveryBoyConfig: DeliveryBoyConfig, userConfig: [String: String?]) {
        self.deliveryBoyConfig = deliveryBoyConfig
        self.userConfig = userConfig
    }
}

class DeliveryBoyConfig: Codable {
    let id: String
    let fname: String
    let lname: String
    let countryCode: String
    let mobile: String
    let email: String
    let address: String
    let userid: String
    let imeiNumber: String
    let lastUpdate: JSONNull?
    let postID: JSONNull?
    let capacity: JSONNull?
    let geoLatitude: String
    let geoLongitude: String
    let geoRadius: String
    let insertDatetime: String
    let updateDatetime: JSONNull?
    let origID: String
    let isOtp: String
    let imgPath: JSONNull?
    let deviceToken: JSONNull?
    let flag: JSONNull?
    let osVersion: JSONNull?
    let appVersion: JSONNull?
    let latitude: String
    let longitude: String
    let timestamp: String
    let dutyStatus: String
    let battery: String
    let charging: String
    let speed: String
    let distance: String
    let geofenceID: JSONNull?
    let monthlyFixEarning: String
    let dailyFixEarning: String
    let reimbursementPerKM: String
    let monthlyRevenueTarget: String
    let monthlyTaskTarget: String
    let monthlyCarryingCapacity: String
    let empIsActive: String
    let empUsedLeaves: Int
    let empRemainingLeaves: Int
    let empTotalLeaves: String

    enum CodingKeys: String, CodingKey {
        case id = "id"
        case fname = "fname"
        case lname = "lname"
        case countryCode = "country_code"
        case mobile = "mobile"
        case email = "email"
        case address = "address"
        case userid = "userid"
        case imeiNumber = "imei_number"
        case lastUpdate = "last_update"
        case postID = "post_id"
        case capacity = "capacity"
        case geoLatitude = "geo_latitude"
        case geoLongitude = "geo_longitude"
        case geoRadius = "geo_radius"
        case insertDatetime = "insert_datetime"
        case updateDatetime = "update_datetime"
        case origID = "orig_id"
        case isOtp = "is_otp"
        case imgPath = "img_path"
        case deviceToken = "device_token"
        case flag = "flag"
        case osVersion = "osVersion"
        case appVersion = "appVersion"
        case latitude = "latitude"
        case longitude = "longitude"
        case timestamp = "timestamp"
        case dutyStatus = "duty_status"
        case battery = "battery"
        case charging = "charging"
        case speed = "speed"
        case distance = "distance"
        case geofenceID = "geofence_id"
        case monthlyFixEarning = "monthly_fix_earning"
        case dailyFixEarning = "daily_fix_earning"
        case reimbursementPerKM = "reimbursement_per_km"
        case monthlyRevenueTarget = "monthly_revenue_target"
        case monthlyTaskTarget = "monthly_task_target"
        case monthlyCarryingCapacity = "monthly_carrying_capacity"
        case empIsActive = "emp_is_active"
        case empUsedLeaves = "emp_used_leaves"
        case empRemainingLeaves = "emp_remaining_leaves"
        case empTotalLeaves = "emp_total_leaves"
    }

    init(id: String, fname: String, lname: String, countryCode: String, mobile: String, email: String, address: String, userid: String, imeiNumber: String, lastUpdate: JSONNull?, postID: JSONNull?, capacity: JSONNull?, geoLatitude: String, geoLongitude: String, geoRadius: String, insertDatetime: String, updateDatetime: JSONNull?, origID: String, isOtp: String, imgPath: JSONNull?, deviceToken: JSONNull?, flag: JSONNull?, osVersion: JSONNull?, appVersion: JSONNull?, latitude: String, longitude: String, timestamp: String, dutyStatus: String, battery: String, charging: String, speed: String, distance: String, geofenceID: JSONNull?, monthlyFixEarning: String, dailyFixEarning: String, reimbursementPerKM: String, monthlyRevenueTarget: String, monthlyTaskTarget: String, monthlyCarryingCapacity: String, empIsActive: String, empUsedLeaves: Int, empRemainingLeaves: Int, empTotalLeaves: String) {
        self.id = id
        self.fname = fname
        self.lname = lname
        self.countryCode = countryCode
        self.mobile = mobile
        self.email = email
        self.address = address
        self.userid = userid
        self.imeiNumber = imeiNumber
        self.lastUpdate = lastUpdate
        self.postID = postID
        self.capacity = capacity
        self.geoLatitude = geoLatitude
        self.geoLongitude = geoLongitude
        self.geoRadius = geoRadius
        self.insertDatetime = insertDatetime
        self.updateDatetime = updateDatetime
        self.origID = origID
        self.isOtp = isOtp
        self.imgPath = imgPath
        self.deviceToken = deviceToken
        self.flag = flag
        self.osVersion = osVersion
        self.appVersion = appVersion
        self.latitude = latitude
        self.longitude = longitude
        self.timestamp = timestamp
        self.dutyStatus = dutyStatus
        self.battery = battery
        self.charging = charging
        self.speed = speed
        self.distance = distance
        self.geofenceID = geofenceID
        self.monthlyFixEarning = monthlyFixEarning
        self.dailyFixEarning = dailyFixEarning
        self.reimbursementPerKM = reimbursementPerKM
        self.monthlyRevenueTarget = monthlyRevenueTarget
        self.monthlyTaskTarget = monthlyTaskTarget
        self.monthlyCarryingCapacity = monthlyCarryingCapacity
        self.empIsActive = empIsActive
        self.empUsedLeaves = empUsedLeaves
        self.empRemainingLeaves = empRemainingLeaves
        self.empTotalLeaves = empTotalLeaves
    }
}

// MARK: Convenience initializers and mutators

extension MyCustomJSON {
    convenience init(data: Data) throws {
        let me = try newJSONDecoder().decode(MyCustomJSON.self, from: data)
        self.init(status: me.status, data: me.data, message: me.message)
    }

    convenience init(_ json: String, using encoding: String.Encoding = .utf8) throws {
        guard let data = json.data(using: encoding) else {
            throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
        }
        try self.init(data: data)
    }

    convenience init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }

    func with(
        status: String? = nil,
        data: DataClass? = nil,
        message: String? = nil
    ) -> MyCustomJSON {
        return MyCustomJSON(
            status: status ?? self.status,
            data: data ?? self.data,
            message: message ?? self.message
        )
    }

    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(), encoding: encoding)
    }
}

extension DataClass {
    convenience init(data: Data) throws {
        let me = try newJSONDecoder().decode(DataClass.self, from: data)
        self.init(deliveryBoyConfig: me.deliveryBoyConfig, userConfig: me.userConfig)
    }

    convenience init(_ json: String, using encoding: String.Encoding = .utf8) throws {
        guard let data = json.data(using: encoding) else {
            throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
        }
        try self.init(data: data)
    }

    convenience init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }

    func with(
        deliveryBoyConfig: DeliveryBoyConfig? = nil,
        userConfig: [String: String?]? = nil
    ) -> DataClass {
        return DataClass(
            deliveryBoyConfig: deliveryBoyConfig ?? self.deliveryBoyConfig,
            userConfig: userConfig ?? self.userConfig
        )
    }

    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(), encoding: encoding)
    }
}

extension DeliveryBoyConfig {
    convenience init(data: Data) throws {
        let me = try newJSONDecoder().decode(DeliveryBoyConfig.self, from: data)
        self.init(id: me.id, fname: me.fname, lname: me.lname, countryCode: me.countryCode, mobile: me.mobile, email: me.email, address: me.address, userid: me.userid, imeiNumber: me.imeiNumber, lastUpdate: me.lastUpdate, postID: me.postID, capacity: me.capacity, geoLatitude: me.geoLatitude, geoLongitude: me.geoLongitude, geoRadius: me.geoRadius, insertDatetime: me.insertDatetime, updateDatetime: me.updateDatetime, origID: me.origID, isOtp: me.isOtp, imgPath: me.imgPath, deviceToken: me.deviceToken, flag: me.flag, osVersion: me.osVersion, appVersion: me.appVersion, latitude: me.latitude, longitude: me.longitude, timestamp: me.timestamp, dutyStatus: me.dutyStatus, battery: me.battery, charging: me.charging, speed: me.speed, distance: me.distance, geofenceID: me.geofenceID, monthlyFixEarning: me.monthlyFixEarning, dailyFixEarning: me.dailyFixEarning, reimbursementPerKM: me.reimbursementPerKM, monthlyRevenueTarget: me.monthlyRevenueTarget, monthlyTaskTarget: me.monthlyTaskTarget, monthlyCarryingCapacity: me.monthlyCarryingCapacity, empIsActive: me.empIsActive, empUsedLeaves: me.empUsedLeaves, empRemainingLeaves: me.empRemainingLeaves, empTotalLeaves: me.empTotalLeaves)
    }

    convenience init(_ json: String, using encoding: String.Encoding = .utf8) throws {
        guard let data = json.data(using: encoding) else {
            throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
        }
        try self.init(data: data)
    }

    convenience init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }

    func with(
        id: String? = nil,
        fname: String? = nil,
        lname: String? = nil,
        countryCode: String? = nil,
        mobile: String? = nil,
        email: String? = nil,
        address: String? = nil,
        userid: String? = nil,
        imeiNumber: String? = nil,
        lastUpdate: JSONNull?? = nil,
        postID: JSONNull?? = nil,
        capacity: JSONNull?? = nil,
        geoLatitude: String? = nil,
        geoLongitude: String? = nil,
        geoRadius: String? = nil,
        insertDatetime: String? = nil,
        updateDatetime: JSONNull?? = nil,
        origID: String? = nil,
        isOtp: String? = nil,
        imgPath: JSONNull?? = nil,
        deviceToken: JSONNull?? = nil,
        flag: JSONNull?? = nil,
        osVersion: JSONNull?? = nil,
        appVersion: JSONNull?? = nil,
        latitude: String? = nil,
        longitude: String? = nil,
        timestamp: String? = nil,
        dutyStatus: String? = nil,
        battery: String? = nil,
        charging: String? = nil,
        speed: String? = nil,
        distance: String? = nil,
        geofenceID: JSONNull?? = nil,
        monthlyFixEarning: String? = nil,
        dailyFixEarning: String? = nil,
        reimbursementPerKM: String? = nil,
        monthlyRevenueTarget: String? = nil,
        monthlyTaskTarget: String? = nil,
        monthlyCarryingCapacity: String? = nil,
        empIsActive: String? = nil,
        empUsedLeaves: Int? = nil,
        empRemainingLeaves: Int? = nil,
        empTotalLeaves: String? = nil
    ) -> DeliveryBoyConfig {
        return DeliveryBoyConfig(
            id: id ?? self.id,
            fname: fname ?? self.fname,
            lname: lname ?? self.lname,
            countryCode: countryCode ?? self.countryCode,
            mobile: mobile ?? self.mobile,
            email: email ?? self.email,
            address: address ?? self.address,
            userid: userid ?? self.userid,
            imeiNumber: imeiNumber ?? self.imeiNumber,
            lastUpdate: lastUpdate ?? self.lastUpdate,
            postID: postID ?? self.postID,
            capacity: capacity ?? self.capacity,
            geoLatitude: geoLatitude ?? self.geoLatitude,
            geoLongitude: geoLongitude ?? self.geoLongitude,
            geoRadius: geoRadius ?? self.geoRadius,
            insertDatetime: insertDatetime ?? self.insertDatetime,
            updateDatetime: updateDatetime ?? self.updateDatetime,
            origID: origID ?? self.origID,
            isOtp: isOtp ?? self.isOtp,
            imgPath: imgPath ?? self.imgPath,
            deviceToken: deviceToken ?? self.deviceToken,
            flag: flag ?? self.flag,
            osVersion: osVersion ?? self.osVersion,
            appVersion: appVersion ?? self.appVersion,
            latitude: latitude ?? self.latitude,
            longitude: longitude ?? self.longitude,
            timestamp: timestamp ?? self.timestamp,
            dutyStatus: dutyStatus ?? self.dutyStatus,
            battery: battery ?? self.battery,
            charging: charging ?? self.charging,
            speed: speed ?? self.speed,
            distance: distance ?? self.distance,
            geofenceID: geofenceID ?? self.geofenceID,
            monthlyFixEarning: monthlyFixEarning ?? self.monthlyFixEarning,
            dailyFixEarning: dailyFixEarning ?? self.dailyFixEarning,
            reimbursementPerKM: reimbursementPerKM ?? self.reimbursementPerKM,
            monthlyRevenueTarget: monthlyRevenueTarget ?? self.monthlyRevenueTarget,
            monthlyTaskTarget: monthlyTaskTarget ?? self.monthlyTaskTarget,
            monthlyCarryingCapacity: monthlyCarryingCapacity ?? self.monthlyCarryingCapacity,
            empIsActive: empIsActive ?? self.empIsActive,
            empUsedLeaves: empUsedLeaves ?? self.empUsedLeaves,
            empRemainingLeaves: empRemainingLeaves ?? self.empRemainingLeaves,
            empTotalLeaves: empTotalLeaves ?? self.empTotalLeaves
        )
    }

    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(), encoding: encoding)
    }
}

// MARK: Encode/decode helpers

class JSONNull: Codable, Hashable {

    public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
        return true
    }

    public var hashValue: Int {
        return 0
    }

    public init() {}

    public required init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if !container.decodeNil() {
            throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encodeNil()
    }
}

func newJSONDecoder() -> JSONDecoder {
    let decoder = JSONDecoder()
    if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
        decoder.dateDecodingStrategy = .iso8601
    }
    return decoder
}

func newJSONEncoder() -> JSONEncoder {
    let encoder = JSONEncoder()
    if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
        encoder.dateEncodingStrategy = .iso8601
    }
    return encoder
}
...