2015-11-19 24 views
6

Voglio inviare un enum come un oggetto in una notifica:Come inviare un valore enum in una notifica in Swift?

enum RuleError:String { 
    case Create, Update, Delete 
} 

class myClass { 

    func foo() { 
     NSNotificationCenter.defaultCenter().postNotificationName("RuleFailNotification", 
              object: RuleError.Create) 
    } 
} 

Purtroppo questo non funziona in quanto un enum non corrispondeAnyObject?.

Qualche idea su come aggirare questo problema?

risposta

7

Il parametro object nella funzione che si sta utilizzando è il mittente, l'oggetto che invia la notifica, non il parametro. Controlla i documenti here.

Si dovrebbe mettere il valore enum che si desidera inviare come parametro nel dizionario informazioni utente e utilizzare il seguente metodo:

func postNotificationName(_ aName: String, 
        object anObject: AnyObject?, 
       userInfo aUserInfo: [NSObject : AnyObject]?) 

Nel tuo caso:

let userInfo = ["RuleError" : RuleError.Create.rawValue] 

NSNotificationCenter.defaultCenter().postNotificationName("RuleFailNotification", 
     object: self, 
     userInfo:userInfo) 

E per gestire il notifica, prima registrarsi per questo:

NSNotificationCenter.defaultCenter().addObserver(
     self, 
     selector: "handleRuleFailNotification:", 
     name: "RuleFailNotification", 
     object: nil) 

Quindi gestirlo:

func handleRuleFailNotification(notification: NSNotification) { 

     let userInfo = notification.userInfo 

     RuleError(rawValue: userInfo!["RuleError"] as! String) 
    } 
+1

Questa è una sfortunata necessità. Le notifiche costringono enumerazioni e strutture in uno stato di seconda classe. Ritengo che questa sia una grave lacuna in Swift, dal momento che gli Enum sono spesso solo un Int o String limitato, eppure questi vanno bene come valore. – BaseZen

2

La soluzione più semplice è quella di inviare il valore grezzo

RuleError.Create.rawValue 

che potrebbe essere successivamente riconvertito in un enum

RuleError(rawValue : "Create") 

Ma il parametro object non è il luogo adatto per invia dati personalizzati. Meglio usare il dizionario userInfo.

1

È possibile utilizzare la boxe per inviare un tipo di Swift puro come enum tramite NSNotification.

final class Box<T>: NSObject { 
    let value: T 
    init(_ value: T) { 
     self.value = value 
    } 
} 

di inviare una notifica:

let userInfo = ["RuleError" : Box(RuleError.Create)] 
NSNotificationCenter.defaultCenter().postNotificationName("RuleFailNotification", 
    object: self, 
    userInfo:userInfo) 

Nel suo osservatore, il valore può essere recuperato come:

if let box = notification.userInfo?["RuleFailNotification"] as? Box<RuleError> { 
    let ruleError = box.value 
} 

È possibile inviare un enum Swift, anche con valori associati.

+0

Non dovrebbe essere 'userInfo? [" RuleError "]' nell'ultimo blocco di codice? – Tropper

0

Esempio.Swift 3

1: Creazione di nome notifica

extension NSNotification.Name { 
    public static let NetworkReachabilityStatus: NSNotification.Name = 
    NSNotification.Name(rawValue: "NetworkReachabilityStatusChanged") 
} 

2: Alcuni enum

enum NetworkReachabilityStatus { 
    case connected 
    case notConnected 
} 

3: dati contabili

NotificationCenter.default.post(name: Notification.Name.NetworkReachabilityStatus, 
        object:nil, 
        userInfo:[kNetworkRechabilityStatus: NetworkReachabilityStatus.notConnected]) 
  • kNetworkRechabilityStatus - è costante stringa
  • 012.

4: Osservando

override func viewDidLoad() { 
    super.viewDidLoad() 
    NotificationCenter.default.addObserver(self, selector: #selector(networkStatusChanged(_:)), name: Notification.Name.NetworkReachabilityStatus, object: nil) 
} 

func networkStatusChanged(_ notification: Notification) { 
    let status: NetworkReachabilityStatus = notification.userInfo?[kNetworkRechabilityStatus] as! NetworkReachabilityStatus 
    switch status { 
    case .connected: 

     break 
    case .notConnected: 

     break 
    } 
} 

E non dimenticare di annullare l'iscrizione a notifica :)