0

I am wondering how to save an array of objects from the following class:

class CustomDocument: NSObject, NSCoding {
    let name : String
    let image : UIImage

    init(n: String, i: UIImage){
        name = n
        image = i
    }

    //other code excluded
}

Originally, I saved this array to User Defaults. Because the objects took up a lot of space, it caused a lot of lag in the app.

What is the best way to save an array of data that takes up a lot of space?

Thank you so much for the help and all responses are appreciated.

2
  • Why do you want to save the UIImage? Commented Feb 2, 2019 at 4:39
  • 1. is your image is loaded from Server by network calling? You can load image with SDWebImage library, as this caches image when loaded, and after loaded it reads from cache 2. Why not using core data? Commented Feb 2, 2019 at 5:14

1 Answer 1

2

Try this code, Hope it helps:

class CustomDocument: NSObject, NSCoding  {

    var name : String?
    var image : UIImage?

    func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: "namekey")
        if let imageData = image!.jpegData(compressionQuality: 1.0){
            aCoder.encode(imageData, forKey: "imagekey")
        }
        UserDefaults.standard.synchronize()
    }

    required convenience init?(coder aDecoder: NSCoder) {
        self.init()
        if let name =  (aDecoder.decodeObject(forKey: "namekey") as? String){
            self.name = name
        }
        if let imageData = (aDecoder.decodeObject(forKey: "imagekey")  as? Data){
            if let image = UIImage(data: imageData){
                self.image = image
            }
        }
    }
}


func archiveDocument(document:CustomDocument) -> Data? {
    do {
        let archivedObject = try NSKeyedArchiver.archivedData(withRootObject: document, requiringSecureCoding: false)
        return archivedObject

    } catch {
        // do something with the error
    }
    return nil
}


func unarchiveDocument(unarchivedObject:Data) -> CustomDocument? {
    do {
        if let document = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(unarchivedObject) as? CustomDocument {
            return document
        }
    } catch {
        // do something with the error
    }
    return nil
}

Example:

//Set the object, also you can use an array instead of an object
let obj = CustomDocument()
obj.name = "doc1"
obj.image = UIImage(named: "my_image")
if let archivedObject = archiveDocument(document: obj){
    UserDefaults.standard.set(archivedObject, forKey: "obj")
}

//Get the object
if let  archivedObject = UserDefaults.standard.data(forKey: "obj"){           
    obj = unarchiveDocument(unarchivedObject: archivedObject)
    let myImage = obj?.image
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.