【问题标题】:NSKeyedArchiver.archiveRootObject returns "false" if I want to overwrite data, why?如果我想覆盖数据,NSKeyedArchiver.archiveRootObject 返回“false”,为什么?
【发布时间】:2015-11-08 16:45:15
【问题描述】:
NSKeyedArchiver.archiveRootObject(<#rootObject: AnyObject#>, toFile: <#String#>)

仅在第一次返回 true。每次我调用它时,该方法都会返回 false。

我读了一些 SO,一些帖子说我不能以这种方式重写数据。但是,我试过了:

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

它仍然没有帮助。

我做了什么:

  1. 检查了我的所有模型文件中的NSCoding 协议
  2. 检查了我所有的required init(coder aDecoder: NSCoder)func encodeWithCoder(aCoder: NSCoder)

我遗漏了一些东西,因为我已经在我的上一个应用程序中做到了这一点,并且它工作正常`

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
        }
    `

我正在使用 Xcode 6.4 和 Swift 1.2。

欢迎任何帮助和代码更正。

【问题讨论】:

    标签: swift xcode6 nskeyedarchiver ios9.1


    【解决方案1】:

    由于您放在这里的代码不包含saveDataArraysaveDataObject的调用,所以我判断您已经手动维护了归档对象的路径。这就是问题所在。 NSKeyedArchiver 方法名为archiveRootObject 可以自动维护归档文件路径。

    在苹果的杜库梅中

    通过将基于给定对象的对象图编码为数据对象来归档它,然后以原子方式将生成的数据对象写入给定路径的文件,并返回一个布尔值,指示操作是否成功。

    SO 中的另一个问题可能对您有所帮助。

    【讨论】:

    • 我会尽快测试它。泰
    【解决方案2】:

    我在这个很好的例子中遵循了苹果的说明:Persist Data 但是我在 AppleTV 的应用程序中遇到了同样的问题。最后,我更改了 CacheDirectory 的 .Documents 目录,它运行良好。

    static let DocumentsDirectorio = NSFileManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask).first!
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多