2016-08-24 104 views
0

我正在Swift中开发。我想通过nsuserdefaults存储自定义数据。如何通过nsuserdefaults在swift中存储自定义数据?

我的自定义数据就像下面

ConnectedDevice.swift

import UIKit 
import Foundation 


class ConnectedDevice { 

    var name:String? 

    var ConnectState:Bool=false 

    var AlertState:Int=0 

    var Battery:NSInteger=0 

    var AlertStatus:Int! 

} 

ViewController.swift

var userDefault = NSUserDefaults.standardUserDefaults() 
var ConnDevice:[ConnectedDevice] = [ConnectedDevice]() 

当我尝试来存储数据,我使用以下代码:

userDefault.setValue(ConnDevice, forKey: "ConnectedDevice") 
userDefault.synchronize() 

当我尝试加载数据,我用下面的代码:

var test = userDefault.objectForKey("ConnectedDevice") 
if((test) != nil){ 
    ConnDevice = test as! [ConnectedDevice] 
} 

但它显示的错误日志像下面当我尝试通过nsuserdefaults来存储数据。看来数据类型是无效的。

2016-08-24 17:17:50.315 Anti-Lost[471:212884] Attempt to set a non-property-list object (
    "Anti_Lost.ConnectedDevice" 
) as an NSUserDefaults/CFPreferences value for key ConnectedDevice 
2016-08-24 17:17:50.318 Anti-Lost[471:212884] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object (
    "Anti_Lost.ConnectedDevice" 
) for key ConnectedDevice' 

我错过了什么吗? 如何在swift中通过nsuserdefaults存储自定义数据? ----------------------------------编辑------------- --------------------

我修改代码如下所示:

ConnectedDevice.swift

import UIKit 
import Foundation 
import CoreBluetooth 
import CoreLocation 

class ConnectedDevice : NSObject , NSCoding{ 

    var RSSI_threshold:NSNumber=0 

    var Current_RSSI:NSNumber=0 

    var name:String? 

    var bdAddr:NSUUID? 

    var ConnectState:Bool=false 

    var AlertState:Int=0 

    var BLEPeripheral : CBPeripheral! 

    var DisconnectAddress:[String] = [String]() 

    var DisconnectTime:[String] = [String]() 

    var Battery:NSInteger=0 

    var Location:[CLLocation] = [CLLocation]() 

    var AlertStatus:Int! 



    func encodeWithCoder(aCoder: NSCoder) { 

     aCoder.encodeObject(RSSI_threshold, forKey: "RSSI_threshold") 
     aCoder.encodeObject(Current_RSSI, forKey: "Current_RSSI") 
     aCoder.encodeObject(name, forKey: "name") 
     aCoder.encodeObject(bdAddr, forKey: "bdAddr") 
     aCoder.encodeBool(ConnectState, forKey: "ConnectState") 
     aCoder.encodeInteger(AlertState, forKey: "AlertState") 
     aCoder.encodeObject(BLEPeripheral, forKey: "BLEPeripheral") 
     aCoder.encodeObject(DisconnectAddress, forKey: "DisconnectAddress") 
     aCoder.encodeObject(DisconnectTime, forKey: "DisconnectTime") 
     aCoder.encodeObject(Battery, forKey: "Battery") 
     aCoder.encodeObject(Location, forKey: "Location") 
     aCoder.encodeObject(AlertStatus, forKey: "AlertStatus") 


    } 

    override init() { 


    } 

    required init?(coder aDecoder: NSCoder) { 

     self.RSSI_threshold = aDecoder.decodeObjectForKey("RSSI_threshold") as! NSNumber 
     self.Current_RSSI = aDecoder.decodeObjectForKey("Current_RSSI") as! NSNumber 
     self.name = aDecoder.decodeObjectForKey("name") as? String 
     self.bdAddr = aDecoder.decodeObjectForKey("bdAddr") as? NSUUID 
     self.ConnectState = aDecoder.decodeObjectForKey("ConnectState") as! Bool 
     self.AlertState = aDecoder.decodeObjectForKey("AlertState") as! Int 
     self.BLEPeripheral = aDecoder.decodeObjectForKey("BLEPeripheral") as! CBPeripheral 
     self.DisconnectAddress = aDecoder.decodeObjectForKey("DisconnectAddress") as! [String] 
     self.DisconnectTime = aDecoder.decodeObjectForKey("DisconnectTime") as! [String] 
     self.Battery = aDecoder.decodeObjectForKey("Battery") as! NSInteger 
     self.Location = aDecoder.decodeObjectForKey("Location") as! [CLLocation] 
     self.AlertStatus = aDecoder.decodeObjectForKey("AlertStatus") as! Int 
    } 
} 

并且我使用以下代码来存储数据

let data = NSKeyedArchiver.archivedDataWithRootObject(ConnectedDevice) 
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "ConnectedDevice") 

但它会显示错误的aCoder.encodeObject(BLEPeripheral, forKey: "BLEPeripheral"),错误日志

2016-08-24 18:37:57.022 Anti-Lost[476:222607] -[CBPeripheral encodeWithCoder:]: unrecognized selector sent to instance 0x14e9fc60 
2016-08-24 18:37:57.024 Anti-Lost[476:222607] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CBPeripheral encodeWithCoder:]: unrecognized selector sent to instance 0x14e9fc60' 

如何编码CBPeripheral

+0

你需要让'ConnectedDevice'符合'NSCoding'并使用'NSKeyedArchiver'。 – Larme

+0

可能重复的[如何在NSUserDefaults中存储自定义对象](http://stackoverflow.com/questions/2315948/how-to-store-custom-objects-in-nsuserdefaults) –

回答

2

你的类必须符合NSCoding协议,这里是我的应用程序的一个小样本:

class BarData: NSObject, NSCoding { 
    let url: String 
    let date: NSDate 
    var isFavorite: Bool = false 

    init(url: String, date: NSDate) { 
     self.url = url 
     self.date = date 
    } 

    //MARK: - NSCoding - 
    @objc required init(coder aDecoder: NSCoder) { 
     url = aDecoder.decodeObjectForKey("url") as! String 
     date = aDecoder.decodeObjectForKey("date") as! NSDate 
     isFavorite = aDecoder.decodeBoolForKey("isFavorite") 
    } 

    @objc func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeObject(url, forKey: "url") 
     aCoder.encodeObject(date, forKey: "date") 
     aCoder.encodeBool(isFavorite, forKey: "isFavorite") 
    } 
} 
+0

嗨,我已经修改了代码。但它有其他错误。它似乎无法编码CBPeripheral ... – Wun

+0

@Wun,因为CBPeripheral必须符合NSCoding,并且递归的一切都不符合NSCoding – HaneTV

1

尝试userDefault.setObject(ConnDevice, forKey: "ConnectedDevice")代替userDefault.setValue(ConnDevice, forKey: "ConnectedDevice")

相关问题