【问题标题】:How to store the custom data like CBPeripheral via nsuserdefaults in swift?如何通过 nsuserdefaults 快速存储 CBPeripheral 等自定义数据?
【发布时间】:2016-08-24 11:24:42
【问题描述】:

我正在使用 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
    }
}

ViewController.swift

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

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

let data = NSKeyedArchiver.archivedDataWithRootObject(BLEConnectedDevice)
        NSUserDefaults.standardUserDefaults().setObject(data, forKey: "BLEConnectedDevice")
       userDefault.synchronize()

当我尝试加载数据时,我使用以下代码:

if let Data = NSUserDefaults.standardUserDefaults().objectForKey("BLEConnectedDevice") as? NSData {

    if let devcie = NSKeyedUnarchiver.unarchiveObjectWithData(Data) as? ConnectedDevice {

        print("NSUserDefaults = \(devcie.name)")

    }

}

但是会在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 进行编码?

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

【问题讨论】:

  • CBPeripheral 不符合 NSCoding。你不能保存它。您可能只想保存有关它的“有趣信息”,但不能这样存储。

标签: ios swift nsuserdefaults nscoding


【解决方案1】:

这是因为CBPeripheral 没有实现NSCoding。因此,您将无法将您的BLEPeripheral 对象归档到NSUserDefaults

我认为最好的解决方案是直接存储您感兴趣的属性(如nameidentifier):

aCoder.encodeObject(BLEPeripheral.name, forKey: "BLEPeripheralName")
aCoder.encodeObject(BLEPeripheral.identifier, forKey: "BLEPeripheralIdentifier")

编辑:

我认为无论如何您都无法再次存储和构建您的CBPeripheral。 Apple 像这样呈现CBPeripheral 对象:

因此,您无法存储此对象并稍后将其重新构建,这似乎很合乎逻辑……我认为最好的解决方案是存储 BLEPeripheral.identifier 并稍后使用 CBCentralManager 取回 CBPeripheral。您可以使用retrievePeripherals(withIdentifiers:) 方法来实现。 Here is the documentation。而且我认为你永远不应该自己构建CBPeripheral 对象。

【讨论】:

  • 我也尝试self.BLEPeripheral.name = aDecoder.decodeObjectForKey("BLEPeripheralName") as! String 但它显示Cannot assign to property: 'name' is a get-only property
  • 确实如此。我认为您将无法从 NSUserDefaults 再次构建您的 BLEPeripheral 对象。而当我们考虑它时,这似乎很正常吗?
  • 我刚刚编辑了我的答案,以解释为什么不应存储 BLEPeripheral 并直接再次构建。
  • 这是正确答案。仅存储标识符,然后使用 CBCentralManager 重新创建 CBPeripheral。你就是这样做的! :)
猜你喜欢
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 2017-08-30
相关资源
最近更新 更多