swift 3 - How to persist objects

0

I'm an Android developer and I'm trying to learn some things for iOS as well. I have knocked myself a little on simple things, like saving persisting an object of mine to catch it again another time. On Android I would use a SharedPreference and would solve everything.

In Swift 3 I'm not sure how to do this. I have already seen that NSUserDefaults does not save objects.

Later I tried to use NSCoding , which looks like this:

class Appointment: NSObject, NSCoding {
let custoMercadoria: Double
let custoServico: Double
let aliquotaSimples: Double
let margem: Double
let fretePreco: Double
let cobrancaPreco: Double
let otherCost: Double

override init(){
 }

init(Appointment : (Double,Double,Double,Double,Double,Double,Double)){
    self.custoMercadoria = Appointment.0
    self.custoServico = Appointment.1
    self.aliquotaSimples = Appointment.2
    self.margem = Appointment.3
    self.fretePreco = Appointment.4
    self.cobrancaPreco = Appointment.5
    self.otherCost = Appointment.6
}
    func getAppointment() -> (Double,Double,Double,Double,Double,Double,Double) {
        return (self.custoMercadoria,self.custoServico,self.aliquotaSimples,self.margem,self.fretePreco,self.cobrancaPreco,self.otherCost)
    }

    required init(coder aDecoder: NSCoder) {
        self.custoMercadoria = aDecoder.decodeObject(forKey:"custoMercadoria") as! Double
        self.custoServico = aDecoder.decodeObject(forKey: "custoServico") as! Double
        self.aliquotaSimples = aDecoder.decodeObject(forKey: "aliquotaSimples") as! Double
        self.margem = aDecoder.decodeObject(forKey: "margem") as! Double
        self.fretePreco = aDecoder.decodeObject(forKey: "fretePreco") as! Double
        self.cobrancaPreco = aDecoder.decodeObject(forKey: "cobrancaPreco") as! Double
        self.otherCost = aDecoder.decodeObject(forKey: "otherCost") as! Double

    }

    func encode(with aCoder: NSCoder){
        aCoder.encode(self.custoMercadoria, forKey: "custoMercadoria")
        aCoder.encode(self.custoServico, forKey: "custoServico")
        aCoder.encode(self.aliquotaSimples, forKey: "aliquotaSimples")
        aCoder.encode(self.margem, forKey: "margem")
        aCoder.encode(self.fretePreco, forKey: "fretePreco")
        aCoder.encode(self.cobrancaPreco, forKey: "cobrancaPreco")
        aCoder.encode(self.otherCost, forKey: "otherCost")
    }
}

I am in doubt if the class assembly is correct, initializing the attributes, encode and decode. If anyone has any examples of how to use it, thank you too.

    
asked by anonymous 19.06.2017 / 20:36

4 answers

0

You can use Realm to persist this data in the database, it's simple and easy to use.

link

Then to serialize and deserialize this object you can use the link

    
20.06.2017 / 14:31
0

It has some problems in its class, especially in the initializer of its class. In the decoding part you should use the decodeDouble (forKey :) method instead of using decodeObject. By making your class conform to NSCoding you can convert your appointment to date using NSKeyedArchiever and save this data as property list file or simply as date in UserDefaults. For possible places to store the data of your application I recommend reading this link.

class Appointment: NSObject, NSCoding {
    let custoMercadoria: Double
    let custoServico: Double
    let aliquotaSimples: Double
    let margem: Double
    let fretePreco: Double
    let cobrancaPreco: Double
    let otherCost: Double

    init(custoMercadoria: Double,
         custoServico: Double,
         aliquotaSimples: Double,
         margem: Double,
         fretePreco: Double,
         cobrancaPreco: Double,
         otherCost: Double) {

        self.custoMercadoria = custoMercadoria
        self.custoServico = custoServico
        self.aliquotaSimples = aliquotaSimples
        self.margem = margem
        self.fretePreco = fretePreco
        self.cobrancaPreco = cobrancaPreco
        self.otherCost = otherCost
    }

    required init(coder aDecoder: NSCoder) {
        self.custoMercadoria = aDecoder.decodeDouble(forKey: "custoMercadoria")
        self.custoServico = aDecoder.decodeDouble(forKey: "custoServico")
        self.aliquotaSimples = aDecoder.decodeDouble(forKey: "aliquotaSimples")
        self.margem = aDecoder.decodeDouble(forKey: "margem")
        self.fretePreco = aDecoder.decodeDouble(forKey: "fretePreco")
        self.cobrancaPreco = aDecoder.decodeDouble(forKey: "cobrancaPreco")
        self.otherCost = aDecoder.decodeDouble(forKey: "otherCost")

    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(custoMercadoria, forKey: "custoMercadoria")
        aCoder.encode(custoServico, forKey: "custoServico")
        aCoder.encode(aliquotaSimples, forKey: "aliquotaSimples")
        aCoder.encode(margem, forKey: "margem")
        aCoder.encode(fretePreco, forKey: "fretePreco")
        aCoder.encode(cobrancaPreco, forKey: "cobrancaPreco")
        aCoder.encode(otherCost, forKey: "otherCost")
    }
}

Saving and reading data from a plist in the Documents folder on the Playground (obs: UserDefaults does not work on the playground)

let appointment1 = Appointment(custoMercadoria: 199.99, custoServico: 99.99, aliquotaSimples: 0.1, margem: 1.5, fretePreco: 25.0, cobrancaPreco: 5.0, otherCost: 1.1)
let appointment2 = Appointment(custoMercadoria: 299.99, custoServico: 199.99, aliquotaSimples: 0.1, margem: 1.5, fretePreco: 25.0, cobrancaPreco: 5.0, otherCost: 2.2)

var appointments: [Appointment] = []
appointments.append(appointment1)
appointments.append(appointment2)
let data = NSKeyedArchiver.archivedData(withRootObject: appointments)
let apointmentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("apointments.plist")
do {
    try data.write(to: apointmentsURL)
    print("data saved")
    // acessando seus dados
    do {
        let data = try Data(contentsOf: apointmentsURL)
        if let appointments = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Appointment] {
            appointments.forEach {
                print("Appointment:\n",
                      "custoMercadoria:", $0.custoMercadoria, "\n",
                      "custoServico:",    $0.custoServico, "\n",
                      "aliquotaSimples:", $0.aliquotaSimples, "\n",
                      "margem:",          $0.margem, "\n",
                      "fretePreco:",      $0.fretePreco, "\n",
                      "cobrancaPreco:",   $0.cobrancaPreco, "\n",
                      "otherCost:",       $0.otherCost, "\n")
            }
        } else {
            print("Could not unarchieve data")
        }
    } catch {
        print(error)
    }
} catch {
    print(error)
}

Saving the data in your App's UserDefaults:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let appointment1 = Appointment(custoMercadoria: 199.99, custoServico: 99.99, aliquotaSimples: 0.1, margem: 1.5, fretePreco: 25.0, cobrancaPreco: 5.0, otherCost: 1.1)
        let appointment2 = Appointment(custoMercadoria: 299.99, custoServico: 199.99, aliquotaSimples: 0.1, margem: 1.5, fretePreco: 25.0, cobrancaPreco: 5.0, otherCost: 2.2)
        var appointments: [Appointment] = []
        appointments.append(appointment1)
        appointments.append(appointment2)
        let data = NSKeyedArchiver.archivedData(withRootObject: appointments)
        UserDefaults.standard.set(data, forKey: "appointments")
        // acessando seus dados
        if let data = UserDefaults.standard.data(forKey: "appointments"),
            let appointments = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Appointment] {
            appointments.forEach {
                print( $0.custoMercadoria,
                       $0.custoServico,
                       $0.aliquotaSimples,
                       $0.margem,
                       $0.fretePreco,
                       $0.cobrancaPreco,
                       $0.otherCost)
            }
        } else {
            print("Could not unarchieve data")
        }
    }
}
    
22.06.2017 / 18:17
0

To save things to the device memory I think CoreData is great. You can model the objects you need to save, define relationships, and it's relatively easy to find and register objects ...

    
28.06.2017 / 04:02
0

You have several ways to persist data in IOS.

You have UserDefaults but the goal is not to store large amounts of data. You can only save primitive data.

You have SQLLite or wrappers for the same as FMDB and CordeData (Apple)

And you have my favorite. Realm. Very good, already brings mechanisms like triggers that work great.

    
27.08.2017 / 16:47