ava
ava

Reputation: 1176

Parsing JSON in Swift

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 ?

Upvotes: 1

Views: 155

Answers (2)

vadian
vadian

Reputation: 285059

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.

Upvotes: 3

David Pasztor
David Pasztor

Reputation: 54706

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
    }
}

Upvotes: 1

Related Questions