NSUserdefaults解码器导致NSArray元素无法匹配Swift数组元素类型

时间:2017-03-01 19:51:54

标签: xcode swift3 nsuserdefaults nscoding

我试图从NSUserDefaults创建一个数组。旧应用程序在Obj C中,我认为我的userdefaults是文件类型NSArray,数组包含一个名为GD_Owed_HistoryObject的自定义类。

我尝试解码此类并使用Swift 3

在新应用中使用它
@objc(GD_Owed_HistoryObject)
class UserDefaultHistory: NSObject, NSCoding {

let saveDate: String?

init(saveDate: String) {
    self.saveDate = saveDate
}

required init(coder decoder: NSCoder) {
    self.saveDate = (decoder.decodeObject(forKey: "owedSaveDate") as? String)
}

func encode(with coder: NSCoder) {
    coder.encode(saveDate, forKey: "owedSaveDate")
}
}

我可以获取数组的计数,并且其中包含正确数量的对象

print("\(statementHistory.count) is the array count") // 3

我还试图弄清楚我的数组中有哪种对象

print("\(type(of: statementHistory)) type of array") // UserDefaultStatement

UserDefaultStatement是我假设从NSUserdefaults回来的。所以我试着用它来创建数组

import UIKit

@objc(GD_Owed_Bill)
class UserDefaultStatement: NSObject, NSCoding {
    var statementHistory: [UserDefaultHistory]

    init(statementHistory: UserDefaultHistory) {
        self.statementHistory = [statementHistory]
    }

    required init(coder decoder: NSCoder) {
        self.statementHistory = (decoder.decodeObject(forKey: "owedHistoryArray") as! Array)
    }

    func encode(with coder: NSCoder) {
        coder.encode(statementHistory, forKey: "owedHistoryArray")

    }

}

但是当我尝试访问UserDefaultHistory上的属性时,我收到此错误。

fatal error: NSArray element failed to match the Swift Array Element type
2017-03-01 11:58:37.411214 owed[1230:571980] fatal error: NSArray element failed to match the Swift Array Element type

我已经为此工作了2天而没有任何进展。我想我没有错误地分配数组类型,但我不知道如何询问我从解码中得到什么样的对象。

更新 在使用旧应用程序花了一些时间后,似乎我NSKeyArchived对象,判断我需要做什么来使用它们。

historyArray = [NSArray arrayWithArray:billDetails.historyArray];
NSLog(@"This is the array count for the history log %lu", (unsigned long)historyArray.count);

// check to see if there is history
[self checkHistory];

// un archive the history array objects
for (NSData *historyData in historyArray)
{
    // set a instance of the person class to each NSData object found in the temp array
    GD_Owed_HistoryObject *historyObject = [[GD_Owed_HistoryObject alloc] init];
    historyObject = [NSKeyedUnarchiver unarchiveObjectWithData:historyData];
    NSLog(@"This is the history object %@", historyObject);
    NSLog(@"This is the save date %@", historyObject.saveDate);
    NSLog(@"This is the total before %@", historyObject.beforeTotal);
    NSLog(@"This is the total after %@", historyObject.afterTotal);
    NSLog(@"This is the amount changed %@", historyObject.amountChanged);
    //[decodedHistoryArray addObject: historyObject];

    [decodedHistoryArray insertObject:historyObject atIndex:0];
}

我现在确切地知道如何将我的数组与其中的存档对象一起取出并取消存档。 statementHistory将是包含已归档项目的数组

更新

var historyArray = statementHistory

            let restoredStatement = NSKeyedUnarchiver.unarchiveObject(with: historyArray) as! UserDefaultHistory
            restoredStatement.statementHistory[0].saveDate

但是我收到了这个错误: Cannot convert value ot type '[UserDefaultHistory]' ot expected argument type 'Data'

1 个答案:

答案 0 :(得分:0)

问题中的代码基本上有效。错误必须在其他地方。

我在Playground中测试了这段代码,也许这是一个如何使用archiver / unarchiver的提示:

let defaultHistory = UserDefaultHistory(saveDate: "2017/3/1")
let statement = UserDefaultStatement(statementHistory: defaultHistory)

// archive the class to Data
let data = NSKeyedArchiver.archivedData(withRootObject: statement)
print(data as NSData) // the type cast prints the raw data rather than "xy bytes"

// unarchive the data to class
let restoredStatement = NSKeyedUnarchiver.unarchiveObject(with: data) as! UserDefaultStatement
restoredStatement.statementHistory[0].saveDate // "2017/3/1"

PS:正如您在上一个问题中提到的那样,您将归档[UserDefaultHistory],因此您肯定会返回[UserDefaultHistory]decodeObject(forKey: "owedHistoryArray") as! [UserDefaultHistory]))。您将在UserDefaultHistory中始终使用非可选字符串。根本不需要使用可选项。