Swift 3 - How to persist objects

Asked

Viewed 364 times

1

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

On Swift 3 I’m not sure how to do this. I’ve seen that the NSUserDefaults unsaved objects.

Later I tried to use the NSCoding, that has remained so:

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, by initializing the attributes, Match and Code. If anyone has any example of how to use also thank you.

4 answers

0

To store things in the memory of the device I think Coredata is great. You can shape the objects you need to store, define relationships and it’s relatively easy to search and register objects...

0

You have several ways to persist data on IOS.

You got the UserDefaults but the goal is not to store large amounts of data. You can only store 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 are very useful.

0

  • Can’t I do it in a simpler way? I think it’s not very suitable to use a comic book, in this case

  • @Luangabriel depends on what you save, Nsuserdefaults was not made for you to save whole objects...

0

There are some problems in your class, especially in the initializer of your class. In the part of Decoding Voce you must use the decodeDouble(forKey:) method instead of using decodeObject. By making your class conform to Nscoding Voce 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 locations to store your application data 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 Playground folder (Obs: Userdefaults does not work on 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")
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.