1

I'm trying to implement the NSCoder, but am currently facing a stubborn issue. My goal is to save the array of strings via NSCoder to a local file and load it when the app opens next time.

Here is the class i've created, but i'm not sure how i should handle the init and encoder functions:

class MyObject: NSObject, NSCoding {

var storyPoints: [String] = []

init(storyPoints : [String]) {
    self.storePoints = storePoints
}


required init(coder decoder: NSCoder) {
    super.init()

???

}

func encodeWithCoder(coder: NSCoder) {
???
}

}

Moreover, how do i access it in my view controller? where should i declare a path for saving the NSCoder? It's not really clear enough.

Looking forward to any advices.

Thank you.

1
  • take a look at the link raywenderlich.com/12779/… to get clear picture about persisiting user data with the help of NSCoder and NSKeyedArcheiver Commented Sep 11, 2015 at 15:01

1 Answer 1

2

Here is an implementation and a playground example that saves the object to the /tmp directory. The init(coder:) function overrides NSObject's so is required and since it is not a designated initializer it must be marked as convenience. Also because init(coder:) is a convenience initializer, it can not call super.init().

To directly answer your question about archiving an array, just type cast the result from decoderObjectForKey(_:). Check the NSCoding documentation for information and API's to code/decode. There is a lot there.

import Cocoa

class MyObject: NSObject, NSCoding {

  var storyPoints: [String] = []

  init(storyPoints : [String]) {
    self.storyPoints = storyPoints
  }

  convenience required init(coder decoder: NSCoder) {
    let storyPoints = decoder.decodeObjectForKey("storypoints") as! [String]
    self.init(storyPoints: storyPoints)
  }

  func encodeWithCoder(coder: NSCoder) {
    coder.encodeObject(storyPoints, forKey: "storypoints")
  }
}

enter image description here

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

5 Comments

Thank you! Works nicely, but each time i run the app the array values are reassigned as if no changes happened.
Can you confirm that you are calling the archiveRootObject(_:toFile:) method after the changes are made to your object?
yes i'm doing it in the function code - right after the obj.storyPoints.append(newObject) happens. yet when i restart - the array is blank again.
there is a little difficulty, because - i can append the array either with one function or the other separately. so to access MyObject array from both functions i declared it on the top before viewDidLoad. What i don't understand is - i have to declare the NSKeyedArchiver and the rest of the code twice in two separate functions?
Be sure that you are using MVC best practices. Do use NSCoding for initializing and saving your model. How your view controllers access the model is important but can't be handled here in comments. Don't worry about the cost of instantiating NSKeyedArchiver/Unarchiver. It is a singleton and should be used as needed.

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.