1

I want to parse JSON object that receive from server. there is my code for parsing JSON and create object.

class Transaction {

  var id: String!
  var amount: String!
  var balance: String!
  var detail: String!
  var serial: String!
  var time : String!
  var type: String!


  init(id: String, amount: String, balance: String, detail:String, serial: String, time: String, type: String ) {

    self.id = id
    self.amount = amount
    self.balance = balance
    self.detail = detail
    self.serial = serial
    self.time = time
    self.type = type

  }

func CreateTransactionObject(json: [String:Any]) -> Transaction? {

    guard   let id = json["id"] as? String,
    let amount = json["amount"] as? String,
    let balance = json["balance"] as? String,
    let detail = json["detail"] as? String,
    let serial = json["serial"] as? String,
    let time  = json["time"] as? String,
    let type = json["type"] as? String

    else {

      return nil
    }

    let object = Transaction(id: id, amount: amount, balance: balance, detail: detail, serial: serial, time: time, type: type)

    return object

  }

this work fine when guard statement don't return nil. for example when one of the parameters is null guard statement return nil and object can't create. how can parse JSON that if any object don't receive from server or get null ?

4
  • 2
    Not related, but never ever declare properties in a class as implicit unwrapped optional which are initialized in an init method passing non-optional values. The properties work also (even better) without trailing exclamation or question mark. Commented Aug 9, 2017 at 8:49
  • also, use if-let statement for doing what you want to because if guard statement get a nil value it will return. Commented Aug 9, 2017 at 8:55
  • @Rishabh thanks for reply, i looking for better way instead if let statement, But I do not think there's a better way. Commented Aug 9, 2017 at 8:59
  • @vadian thanks for reply. I will pay attention to this matter. Commented Aug 9, 2017 at 9:00

2 Answers 2

3

I recommend to use a dedicated init method.

Declare the properties in two ways:

  • If an empty string or 0 can represent no value declare the property as non-optional and use the nil coalescing operator (like the first 5 properties).
  • If no value must be handled separately declare the property as standard optional (like time and type)

class Transaction {

  var id: String
  var amount: String
  var balance: Int
  var detail: String
  let serial: String

  var time : String?
  var type: String?

  init(json: [String:Any]) {    
     self.id = json["id"] as? String ?? ""
     self.amount = json["amount"] as? String ?? ""
     self.balance = json["balance"] as? Int ?? 0
     self.detail = json["detail"] as? String ?? ""
     self.serial = json["serial"] as? String ?? ""
     self.time  = json["time"] as? String
     self.type = json["type"] as? String
  }
}

It's also a good habit to declare properties which are not going to change their value as constants with let (like serial). The initialization works the same way.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, thats good way i will can parse my JSON when initialize Object.
but when any of item is Int instead string how can user it ?
I updated the answer for a heterogenous dictionary (specifying balance as Int)
1

If the object is still usable if one of its properties is nil, declare the properties nil and use if let statements for optional unwrapping instead of the guard let. This way, the properties that don't exist will be initialized to nil, instead of the whole object being initialized to nil. This way you don't even need a designated initializer.

class Transaction {

    var id: String?
    var amount: String?
    var balance: String?
    var detail: String?
    var serial: String?
    var time : String?
    var type: String?

    func CreateTransactionObject(json: [String:Any]) -> Transaction {
        let transaction = Transaction()

        transaction.id = json["id"] as? String
        transaction.amount = json["amount"] as? String
        transaction.balance = json["balance"] as? String
        transaction.detail = json["detail"] as? String
        transaction.serial = json["serial"] as? String
        transaction.time  = json["time"] as? String
        transaction.type = json["type"] as? String

        return transaction
    }
}

3 Comments

If all properties are optional anyway all if - let expressions are redundant and can be omitted.
in this code when any of item return null , after initialize this item is nil ?
Yes. You didn't specify what do you need in case any of the values are nil, so I assumed they should be nil in the object class as well.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.