3

I need help in creating methods for reading/writing some objects to a file, for persistent storage. I've been stuck on this for the last 3 days. This is where I got:

My object:

class Item: NSObject {
var name : String = ""
var link : String = ""
var state : String = ""
var type : String = ""
var selected = false

func createItemWith(name:String, link:String, state:String, type:String) {
    self.name = name
    self.link = link
    self.state = state
    self.type = type
}
}

Then I add it to an array

self.itemsArray.addObject(item)

Now, each object represents a cell in a collection view, where the user can interact with it

   func collectionView(collectionView: UICollectionView,
    didSelectItemAtIndexPath indexPath: NSIndexPath) {
        let cell = self.collectionView.cellForItemAtIndexPath(indexPath)
        var cellCheckedImage = cell!.contentView.viewWithTag(20) as! UIImageView
        if ((itemsArray.objectAtIndex(indexPath.row) as! Item).selected == false) {
            cellCheckedImage.image = UIImage(named:"Checked")
            self.selectedItemsArray.append(itemsArray.objectAtIndex(indexPath.row) as! Item)
            (itemsArray.objectAtIndex(indexPath.row) as! Item).selected = true
        } else if ((itemsArray.objectAtIndex(indexPath.row) as! Item).selected == true) {
            cellCheckedImage.image = UIImage(named:"Unchecked")
            (itemsArray.objectAtIndex(indexPath.row) as! Item).selected = false
        }
}

Now, you can see, the items which the user interacted with I will move to a second array

self.selectedItemsArray.append(itemsArray.objectAtIndex(indexPath.row) as! Item)

which is

   var selectedItemsArray = [Item]()

Now, I have a second class which should write the previous array to a file

import Foundation

private let _SelectedItemsSharedInstance = SelectedItems()

class SelectedItems: NSObject {

private var itemsKey = "items"
var selectedItems = Array("")

class var sharedInstance: SelectedItems {
    return _SelectedItemsSharedInstance
}

func loadItemsFromFile() {
    // getting path 
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let documentsDirectory = paths[0] as! String
    let path = documentsDirectory.stringByAppendingPathComponent("SelectedItems.plist")
    let fileManager = NSFileManager.defaultManager()
    //check if file exists
    if(fileManager.fileExistsAtPath(path)) {


    }
}

func writeItemsToFile() {
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let documentsDirectory = paths.objectAtIndex(0) as! NSString
    let path = documentsDirectory.stringByAppendingPathComponent("SelectedItems.plist")
}
}

This is where I'm stuck. How can I write and read selectedItems to a file?

Update: this is how it worked My Object:

class Item: NSObject {
var name : NSString = ""
var link : NSString = ""
var state : NSString = ""
var type : NSString = ""
var selected = false

func createItemWith(name:String, link:String, state:String, type:String) {
    self.name = name
    self.link = link
    self.state = state
    self.type = type
}

init(name: NSString, link: NSString, state: NSString, type: NSString)
{
    self.name = name
    self.link = link
    self.state = state
    self.type =  type
}

required init(coder aDecoder: NSCoder) {
    self.link = aDecoder.decodeObjectForKey("link") as! NSString as String
    self.name = aDecoder.decodeObjectForKey("name") as! NSString as String
    self.state = aDecoder.decodeObjectForKey("state") as! NSString as String
    self.type = aDecoder.decodeObjectForKey("type") as! NSString as String
}

func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(link, forKey: "link")
    aCoder.encodeObject(name, forKey: "name")
    aCoder.encodeObject(name, forKey: "state")
    aCoder.encodeObject(name, forKey: "type")
}

}

And the methods that write and read them

func loadItemsFromFile() {
    // getting path 
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let documentsDirectory = paths[0] as! String
    let path = documentsDirectory.stringByAppendingPathComponent("SelectedItems.txt")
    let fileManager = NSFileManager.defaultManager()
    println(path)
    if(!fileManager.fileExistsAtPath(path)) {
        // If it doesn't, copy it from the default file in the Bundle
        if let bundlePath = NSBundle.mainBundle().pathForResource("SelectedItems", ofType: "txt") {
            let resultDictionary = NSMutableDictionary(contentsOfFile: bundlePath)
            if let data = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? [String] {
                self.selectedItemsArray = data
            }
        }
    }
    println(self.selectedItemsArray.description)
}

func writeItemsToFile() {
    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray
    let documentsDirectory = paths.objectAtIndex(0) as! NSString
    let path = documentsDirectory.stringByAppendingPathComponent("SelectedItems.txt")
    NSKeyedArchiver.archiveRootObject(self.selectedItemsArray, toFile: path)

}
2
  • Have you tried to use the writeToFile: method? Commented Apr 17, 2015 at 13:14
  • Yes, of course, but the written file is empty. I imagine I need to encode and decode my data, when written and read. Commented Apr 17, 2015 at 13:19

1 Answer 1

1

You can use NSKeyedArchiver and NSKeyedUnarchiver to store your array to a file. Something like this:

func applicationWillTerminate(aNotification: NSNotification) {
    NSKeyedArchiver.archiveRootObject(self.myArray, toFile: "a/file/path")
}

func applicationDidFinishLaunching(aNotification: NSNotification) {
    if let data = NSKeyedUnarchiver.unarchiveObjectWithFile("a/file/path") as? [String] {
        self.myArray = data
    }
}

In this example I use it inside the AppDelegate methods, but you can use it anywhere in your app.

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

2 Comments

Thank you! This did it, but it required to implement init and encodeWithCoder in my object class. I will update the parent question to reflect the changes I did!
Oops, indeed I forgot to mention that detail.

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.