2016-08-24 2 views
1

Je suis en train de développer chez Swift. Je veux stocker les données personnalisées via nsuserdefaults.Comment stocker les données personnalisées comme CBPeripheral via nsuserdefaults dans swift?

Mes données personnalisé est comme ce qui suit

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

Dans ViewController.swift

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

Lorsque je tente de stocker les données, je utilisez le code suivant:

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

Lorsque je tente de charger les données, j'utilise le code suivant:

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

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

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

    } 

} 

Mais il montrera l'erreur à aCoder.encodeObject(BLEPeripheral, forKey: "BLEPeripheral"), et le journal des erreurs est

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' 

Comment encoder le CBPeripheral?

Ai-je raté quelque chose? Comment stocker les données personnalisées via nsuserdefaults dans swift?

+0

'CBPeripheral' n'est pas compatible' NSCoding'. Vous ne pouvez pas le sauvegarder. Vous voudrez peut-être sauvegarder seulement des "informations intéressantes" à ce sujet, mais vous ne pouvez pas les stocker comme ça. – Larme

Répondre

2

C'est parce que CBPeripheral ne mettent pas en œuvre NSCoding. Ainsi, vous ne pourrez pas archiver votre objet BLEPeripheral dans NSUserDefaults.

Je pense que la meilleure solution est de stocker les propriétés directement vous êtes intéressé par (comme name ou identifier):

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

Edit:

Je pense que vous ne serez pas en mesure de stocker et construisez à nouveau votre CBPeripheral, peu importe comment. Apple présente l'objet CBPeripheral comme ça:

Alors, qui semble très logique que vous ne pouvez pas stocker cet objet et la reconstruire plus tard ... Je pense que la meilleure solution est de stocker le BLEPeripheral.identifier chercher revenir plus tard le CBPeripheral en utilisant la CBCentralManager. Vous pouvez le faire en utilisant la méthode retrievePeripherals(withIdentifiers:). Here is the documentation. Et je pense que vous ne devriez jamais créer un objet CBPeripheral par vous-même.

+0

Et j'essaie aussi 'self.BLEPeripheral.name = aDecoder.decodeObjectForKey (" BLEPeripheralName ") comme! String' Mais il montre 'Impossible d'assigner à la propriété: 'name' est une propriété get-only' – Wun

+0

En effet. Je ne pense pas que vous serez en mesure de reconstruire votre objet BLEPeripheral à partir de NSUserDefaults. Et quand on y pense, ça semble normal non? –

+0

Je viens d'éditer ma réponse pour expliquer pourquoi 'BLEPeripheral' ne devrait pas être stocké et reconstruit directement. –