Как обрабатывать пустой массив в процессе кодируемого декодирования - PullRequest
0 голосов
/ 24 мая 2018

Хорошо работает, когда массив address не пуст.Но происходит сбой, когда массив «address» пуст.Любая помощь будет высоко оценена.У меня есть структура для объекта адреса.По сути, «адрес» - это массив объектов типа «Адрес», но когда адрес пуст, он терпит неудачу.

{
    "success": "1",
    "message": "You have succesfully verified your mobile no",
    "details": {
        "customer_id": 825,
        "is_delivery_available": "0",
        "is_registration_complete": "0",
        "is_customer_verified": "0",
        "customer_status": "0",
        "cart_count": "0",
        "name_type": "mr",
        "firstname": "",
        "lastname": "",
        "full_name": "",
        "pincode": "",
        "profile_pic": "",
        "mobile": "8583846677",
        "email": "",
        "address": [

        ],
        "referral_code": ""
    }
}

Выше находится JSON, который я пытаюсь декодировать с использованием Codable в Swift4.

import Foundation

struct Signup: Codable {
    var success:String?
    var message:String?
    var details:Details?

    private enum CodingKeys: String, CodingKey { case success, message, details }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        success = try values.decode(String.self, forKey: .success)
        message = try values.decode(String.self, forKey: .message)
        if let _details = try? values.decode(Details.self, forKey: .details) {
            details = _details
        }
    }
}

struct Details: Codable {
    var address:[Address]?
    var cart_count:String?
    var customer_id:String?
    var customer_status:String?
    var email:String?
    var firstname:String?
    var full_name:String?
    var is_customer_verified:String?
    var is_delivery_available:String?
    var is_registration_complete:String?
    var lastname:String?
    var mobile:String?
    var name_type:String?
    var pincode:String?
    var profile_pic:String?
    var referral_code:String?

    private enum CodingKeys: String, CodingKey { case address, cart_count, customer_id, customer_status, email, firstname, full_name, is_customer_verified, is_delivery_available, is_registration_complete, lastname, mobile, name_type, pincode, profile_pic, referral_code }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)

        ****-->>> Issue is in this line. How to handle empty array while decoding. <<<--****
        address = try? values.decode([Address].self, forKey: .address) 

        cart_count = try values.decode(String.self, forKey: .cart_count)
        customer_id = try values.decode(String.self, forKey: .customer_id)
        customer_status = try values.decode(String.self, forKey: .customer_status)
        email = try values.decode(String.self, forKey: .email)
        firstname = try values.decode(String.self, forKey: .firstname)
        full_name = try values.decode(String.self, forKey: .full_name)
        is_customer_verified = try values.decode(String.self, forKey: .is_customer_verified)
        is_delivery_available = try values.decode(String.self, forKey: .is_delivery_available)
        is_registration_complete = try values.decode(String.self, forKey: .is_registration_complete)
        lastname = try values.decode(String.self, forKey: .lastname)
        mobile = try values.decode(String.self, forKey: .mobile)
        name_type = try values.decode(String.self, forKey: .name_type)
        pincode = try values.decode(String.self, forKey: .pincode)
        profile_pic = try values.decode(String.self, forKey: .profile_pic)
        referral_code = try values.decode(String.self, forKey: .referral_code)
    }
}

struct Address: Codable {
    var address_default:String?
    var address_id:String?
    var address_type:String?
    var city:String?
    var customer_id:String?
    var flat_or_house_or_office_no:String?
    var full_address:String?
    var full_name:String?
    var landmark:String?
    var lat:String?
    var lng:String?
    var mobile:String?
    var name_type:String?
    var pincode:String?
    var street_or_society_or_office_name:String?
}

Я застрял в этом.Как обрабатывать пустой массив при декодировании данных json в Swift4 Codable.

Ответы [ 2 ]

0 голосов
/ 18 июля 2018

Реальная проблема в том, что customer_id в Details это Int, а не String.Декодирование пустого массива должно работать.

Ваш код слишком сложен.Наслаждайтесь магией Codable и опустите все CodingKeys и инициализаторы и объявите все элементы структуры как необязательные и как константы

struct Signup: Decodable {
    let success : String
    let message : String
    let details : Details
}

struct Details : Decodable {
    let address : [Address]
    let cart_count : String
    let customer_id : Int
    let customer_status, email, firstname, full_name : String
    let is_customer_verified, is_delivery_available, is_registration_complete : String
    let lastname, mobile, name_type, pincode, profile_pic, referral_code : String
}

struct Address: Decodable {
    let address_default, address_id, address_type, city, customer_id : String
    let flat_or_house_or_office_no, full_address, full_name : String
    let landmark, lat, lng, mobile, name_type, pincode, street_or_society_or_office_name : String
}

Вы можете даже назвать члены camelCased

let cartCount : String
let customerId : Int
...
let isRegistrationComplete : String

и передайте стратегию декодирования ключа convertFromSnakeCase

decoder.keyDecodingStrategy = .convertFromSnakeCase

Все еще без дополнительного кода!

0 голосов
/ 18 июля 2018

Я столкнулся с этой проблемой и сделал, как показано ниже, чтобы решить эту проблему.

if let _address = try? values.decode([Address].self, forKey: .address) {
    address = _address
} else {
    address = []
}

Вы можете попробовать.

...