ios 将自定义对象保存到 NSUserDefaults

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29986957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:51:17  来源:igfitidea点击:

Save custom objects into NSUserDefaults

iosswiftnsuserdefaults

提问by Peter Pik

I'm having a news ViewControllerand a TeamViewController. The TeamViewControllercontain a tableView of teamObjects which when selected is added into array. I want to add this array into NSUserDefaultsso i can access them from the NewsControllerwhich contain a url request where the teamObjects is needed. However i keep getting:

我有一个新闻ViewController和一个TeamViewController. 所述TeamViewController含有选择加入到阵列时teamObjects的的tableView。我想将此数组添加到其中,NSUserDefaults以便我可以从NewsController其中包含需要 teamObjects 的 url 请求访问它们。但是我不断得到:

'Attempt to insert non-property list object ( "" ) for key teams'

'尝试为关键团队插入非属性列表对象 ("")'

I'm open for other suggestions if there is better ways than storing it in NSUserDefaults

如果有比将其存储更好的方法,我愿意接受其他建议 NSUserDefaults

didSelectRowAtIndexPathmethod

didSelectRowAtIndexPath方法

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)


    let team = self.teamArray[indexPath.row] as Team
    var removed = false

    for (index, value) in enumerate(self.teamSelected) {
        if (value == team) {
            self.teamSelected.removeAtIndex(index)
            removed = true
        }
    }

    if (!removed) {
        self.teamSelected.append(team)
    }

    var userDefaults = NSUserDefaults.standardUserDefaults()
    userDefaults.setValue(self.teamSelected, forKey: "teams")
    userDefaults.synchronize()

    tableView.reloadData()
}

My object

我的对象

class Team: NSObject{
    var id: Int!
    var name: NSString!
    var shortname: NSString!


    init(id: Int, name:NSString, shortname: NSString) {
        self.id = id
        self.name = name
        self.shortname = shortname

    }

}

回答by mohamede1945

Actually, you will need to archive the custom object into NSDatathen save it to user defaults and retrieve it from user defaults and unarchive it again. You can archive it like this

实际上,您需要将自定义对象存档到其中,NSData然后将其保存到用户默认值并从用户默认值中检索它并再次取消存档。你可以这样存档

let teams = [Team(id: 1, name: "team1", shortname: "t1"), Team(id: 2, name: "team2", shortname: "t2")]

var userDefaults = UserDefaults.standard
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: teams)
userDefaults.set(encodedData, forKey: "teams")
userDefaults.synchronize()

and unarchive it like this

并像这样解压它

let decoded  = userDefaults.data(forKey: "teams")
let decodedTeams = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Team]

But if you just did that you will get

但如果你只是这样做,你会得到

.Team encodeWithCoder:]: unrecognized selector sent to instance

You will have to make Team conform to NSCoding just like this

你必须像这样让 Team 符合 NSCoding

class Team: NSObject, NSCoding {
    var id: Int
    var name: String
    var shortname: String


    init(id: Int, name: String, shortname: String) {
        self.id = id
        self.name = name
        self.shortname = shortname

    }

    required convenience init(coder aDecoder: NSCoder) {
        let id = aDecoder.decodeInteger(forKey: "id")
        let name = aDecoder.decodeObject(forKey: "name") as! String
        let shortname = aDecoder.decodeObject(forKey: "shortname") as! String
        self.init(id: id, name: name, shortname: shortname)
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(id, forKey: "id")
        aCoder.encode(name, forKey: "name")
        aCoder.encode(shortname, forKey: "shortname")
    }
}

回答by Malav Soni

You can try NSKeyedUnarchiver, like below

您可以尝试NSKeyedUnarchiver,如下所示

Here i stored UIColor Object in UserDefault You can change it with your object

在这里,我将 UIColor 对象存储在 UserDefault 您可以使用您的对象更改它

 NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];

and to retrive that

并检索它

NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];

Note : This is Objective C but I hope you can covert this in Swift

注意:这是 Objective C,但我希望你能在 Swift 中隐藏它

Hope this solve your problem

希望这能解决您的问题



Update : Swift 5

更新:斯威夫特 5

Archive in Swift

在 Swift 中存档

do{
    let colorAsData = try NSKeyedArchiver.archivedData(withRootObject: UIColor.red, requiringSecureCoding: true)
    UserDefaults.standard.set(colorAsData, forKey: "myColor")
    UserDefaults.standard.synchronize()
}catch (let error){ 
    #if DEBUG
        print("Failed to convert UIColor to Data : \(error.localizedDescription)")
    #endif
}

Unarchive in Swift

在 Swift 中取消归档

do{
    if let colorAsData = UserDefaults.standard.object(forKey: "myColor") as? Data{
        if let color = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [UIColor.self], from: colorAsData){
            // Use Color
        }
    }
}catch (let error){
    #if DEBUG
        print("Failed to convert UIColor to Data : \(error.localizedDescription)")
    #endif
}