0
NSKeyedArchiver.archiveRootObject(<#rootObject: AnyObject#>, toFile: <#String#>)

Only returns true the first time. Every next time I call it, the method returns false.

I read some SO, some posts said that I can't rewrite data this way. However, I tried :

 NSFileManager.defaultManager().removeItemAtPath(path, error: nil) 

and it still didn't help.

What I did:

  1. Checked all my model files for the NSCoding protocol
  2. Checked all my required init(coder aDecoder: NSCoder) and func encodeWithCoder(aCoder: NSCoder)

I am missing something, since I have done this in my last app and it worked fla`

import Foundation

    private let ON_DISK_DATA_DICTIONARY    = "savedDataPathsOnDisk"
    private let _WBMAccessDataOnDiskMShared = WBMAccessDataOnDiskM()
    private var dataDirectories:NSArray!   = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    private var dataDirectoryURL:NSURL!    = NSURL(fileURLWithPath: dataDirectories.objectAtIndex(0) as! String, isDirectory: true)
    private var dataDirectoryPath:String!  = dataDirectoryURL.path!

    let FILE_FORMAT = ".archive"

    class WBMAccessDataOnDiskM: NSObject
    {
        class var sharedData: WBMAccessDataOnDiskM
        {
            return _WBMAccessDataOnDiskMShared
        }

        private var dataAndPathDictionary = [String:String]()

        func getDataAndPathDictionary() -> [String:String]
        {
            return self.dataAndPathDictionary
        }

        func addDataAndPathToDictionary(data:String ,path:String)
        {
            if !checkIfDataAllreadyExists(data)
            {
                let fullPath                = createFullDataPath(path)
                dataAndPathDictionary[data] = fullPath
                NSUserDefaults.standardUserDefaults().setObject(dataAndPathDictionary, forKey: ON_DISK_DATA_DICTIONARY)
            }
        }

        func checkIfDataIsAvailable(dataPathComponent:String) -> (Bool,String)
        {
            var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
            var dataPath = paths.stringByAppendingPathComponent(dataPathComponent)
            var checkValidation = NSFileManager.defaultManager()

            println(dataPathComponent)

            if (checkValidation.fileExistsAtPath(dataPath))
            {
                return (true,dataPath)
            }
            else
            {
                return (false,"")
            }
        }

        func checkForDataOnDisk() -> Bool
        {
            let dataDict = NSUserDefaults.standardUserDefaults().objectForKey(ON_DISK_DATA_DICTIONARY) as? [String:String]

            if dataDict == nil
            {
                return false
            }
            else
            {
                dataAndPathDictionary = dataDict!
                return true
            }
        }

        private func checkIfDataAllreadyExists(data:String) -> Bool
        {
            let keys = self.dataAndPathDictionary.keys.array
            if contains(keys, data)
            {
                return true
            }
            return false
        }

        private func createFullDataPath(path:String) -> String
        {
            var fullPathURL = dataDirectoryURL.URLByAppendingPathComponent(path + FILE_FORMAT)
            return fullPathURL.path!
        }

        func saveDataArray(data:[AnyObject], path:String)
        {
            NSFileManager.defaultManager().removeItemAtPath(path, error: nil)

            if NSKeyedArchiver.archiveRootObject(data, toFile: path)
            {
               // SAVING
                println(" Saving data ARRAY ")
            }
            else
            {
                println(" NOT saving data ARRAY ")
            }
        }

        func saveDataObject(dataObject:AnyObject, path:String)
        {
            if NSKeyedArchiver.archiveRootObject(dataObject, toFile: path)
            {
                println(" Saving data OBJECT ")
            }
            else
            {
                println(" NOT saving data OBJECT ")
            }
        }

        // dataFromDisk = NSKeyedUnarchiver.unarchiveObjectWithFile(pathForNews) as? [AnyObject]
        func loadDataArray(path:String) -> [AnyObject]?
        {
            var dataArrayFromDisk: [AnyObject]?
            dataArrayFromDisk = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? [AnyObject]

            return dataArrayFromDisk
        }

        func loadDataObject(path:String) -> AnyObject?
        {
            var dataObjectFromDisk: AnyObject?
            dataObjectFromDisk = NSKeyedUnarchiver.unarchiveObjectWithFile(path)
            return dataObjectFromDisk
        }

        func getNewsDataLanguagePath() -> String
        {
            var currentOSLanguage = LOCALIZATION.currentOsLanguage
            currentOSLanguage     = currentOSLanguage.substringToIndex(2)
            if currentOSLanguage == "de"
            {
                return ON_DISK_CONTENT_DE
            }
            else if currentOSLanguage == "en"
            {
                return ON_DISK_CONTENT_ENG
            }
            return ON_DISK_CONTENT_ENG
        }
    `

I am using Xcode 6.4 and Swift 1.2.

Any help & code correction is welcome.

MB_iOSDeveloper
  • 4,178
  • 4
  • 24
  • 36

2 Answers2

1

Because of the code you put here does't contain the call of saveDataArray or saveDataObject so I judge that you have maintain the path of a archived object manually.This is where thing went wrong. The method of NSKeyedArchiver named archiveRootObject can automatically maintain the archiver file path.

In the Apple's doucumet

Archives an object graph rooted at a given object by encoding it into a data object then atomically writes the resulting data object to a file at a given path, and returns a Boolean value that indicates whether the operation was successful.

And there is another question in SO may help you.

Community
  • 1
  • 1
lynulzy
  • 561
  • 7
  • 19
0

I followed apple instructions in this good example: Persist Data But I had the same problem you describe with my app for AppleTV. At the end I change .Documents directory for CacheDirectory and it's working well.

static let DocumentsDirectorio = NSFileManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask).first!
abanet
  • 1,327
  • 17
  • 22