Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3 init method that accepts JSON with optional parameters

Tags:

swift

as per Leo Dabus's excellent advice here How to insert into Sqlite with optional parameters using Swift 3 , I modified my class to allow optional parameters. However, I have a convenience method (as shown below) that accepts a JSON string to initialize the object. However, if you look at the self.init at the very bottom, it requires me to add "!" to the optional parameters. As I understand, this is not correct because these parameters can be nil. Is there a good way to handle this? Thanks!!!

class Address : BaseEntity {

    var Id: Int
    var AddressType: Int
    var AddressStatus: Int
    var Address1: String
    var Address2: String
    var City: String
    var State: String
    var Zip: String
    var Country: String
    var Latitude: Double
    var Longitude: Double

    init(id: Int, addressType: Int, addressStatus: Int, address1: String = "", address2: String = "", city: String = "", state: String = "", zip: String = "", country: String = "", latitude: Double = 0, longitude: Double = 0, isDeleted: Bool, created: Date? = nil, createdBy: Int = 0, modified: Date? = nil, modifiedBy: Int = 0) {
        self.Id = id
        self.AddressType = addressType
        self.AddressStatus = addressStatus
        self.Address1 = address1
        self.Address2 = address2
        self.City = city
        self.State = state
        self.Zip = zip
        self.Country = country
        self.Latitude = latitude
        self.Longitude = longitude
        super.init(isDeleted: isDeleted, created: created, createdBy: createdBy, modified: modified, modifiedBy: modifiedBy)
    }

    convenience init?(json: [String: Any]) {

        guard let id = json["Id"] as? Int,
            let addressType = json["AddressType"] as? Int,
            let addressStatus = json["AddressStatus"] as? Int,
            let isDeleted = json["IsDeleted"] as? Bool
            else {
                return nil
        }

        let address1 = json["Address1"] as? String
        let address2 = json["Address2"] as? String
        let city = json["City"] as? String
        let state = json["State"] as? String
        let zip = json["Zip"] as? String
        let country = json["Country"] as? String
        let latitude = json["Latitude"] as? Double
        let longitude = json["Longitude"] as? Double

        let date = Foundation.Date()
        let created = date.dateFromJson(json: json["Created"] as? String)
        let createdBy = json["CreatedBy"] as? Int
        let modified = date.dateFromJson(json: json["Modified"] as? String)
        let modifiedBy = json["ModifiedBy"] as? Int

        self.init(id: id, addressType: addressType, addressStatus: addressStatus, address1: address1!, address2: address2!, city: city!, state: state!, zip: zip!, country: country!, latitude: latitude!, longitude: longitude!, isDeleted: isDeleted, created: created, createdBy: createdBy!, modified: modified, modifiedBy: modifiedBy!)
    }
}
like image 895
Primico Avatar asked Apr 18 '26 05:04

Primico


1 Answers

Besides my comment about the naming convention, there is no need to make your properties variable. You should take a look at the "??" nil coalescing operator:

class Address {
    let id: Int
    let addressType: Int
    let addressStatus: Int
    let address1: String
    let address2: String
    let city: String
    let state: String
    let zip: String
    let country: String
    let latitude: Double?
    let longitude: Double?

    init(id: Int, addressType: Int, addressStatus: Int, address1: String = "", address2: String = "", city: String = "", state: String = "", zip: String = "", country: String = "", latitude: Double? = nil, longitude: Double? = nil) {
        self.id = id
        self.addressType = addressStatus
        self.addressStatus = addressStatus
        self.address1 = address1
        self.address2 = address2
        self.city = city
        self.state = state
        self.zip = zip
        self.country = country
        self.latitude = latitude
        self.longitude = longitude
    }
    init?(json: [String: Any]) {
        guard
            let id = json["Id"] as? Int,
            let addressType = json["AddressType"] as? Int,
            let addressStatus = json["AddressStatus"] as? Int,
            let isDeleted = json["IsDeleted"] as? Bool
            else {
                return nil
        }
        self.id = id
        self.addressType = addressType
        self.addressStatus = addressStatus
        self.address1 = json["Address1"] as? String ?? ""
        self.address2 = json["Address2"] as? String ?? ""
        self.city = json["City"] as? String ?? ""
        self.state = json["State"] as? String ?? ""
        self.zip = json["Zip"] as? String ?? ""
        self.country = json["Country"] as? String ?? ""
        self.latitude = json["Latitude"] as? Double
        self.longitude = json["Longitude"] as? Double

        print(isDeleted)
        // call super.init here
    }
}

let address1 = Address(id: 1, addressType: 2, addressStatus: 3)
let address2 = Address(id: 2, addressType: 3, addressStatus: 4, address1: "Any Address", latitude: 22.0, longitude: 43.0)   // You don't need to add all parameters as long as you keep them in the same order as your initializer
print(address1.id)         // 1
print(address1.address1)   // "" empty String
print(address2.latitude ?? "nil")   // 22.0
print(address2.longitude ?? "nil")   // 43.0
like image 157
Leo Dabus Avatar answered May 04 '26 08:05

Leo Dabus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!