2015-11-19 12 views
6

Chcę wysłać enum jako obiekt w zgłoszeniu:Jak wysłać wartość wyliczenia w powiadomieniu w Swift?

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

class myClass { 

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

Niestety to nie działa od enum nie pasujeAnyObject?.

Każdy pomysł, jak obejść ten problem?

Odpowiedz

7

Parametr object w funkcji, której używasz, to nadawca, obiekt publikujący powiadomienie, a nie parametr. Sprawdź dokumentację: here.

Należy umieścić wartość enum chcesz wysłać jako parametr w słowniku Informacja o użytkowniku i używać w następujący sposób:

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

W twoim przypadku:

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

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

I do obsługi powiadomienie, najpierw zarejestruj się:

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

Następnie obsłuż go:

func handleRuleFailNotification(notification: NSNotification) { 

     let userInfo = notification.userInfo 

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

Jest to niefortunne koniecznością. Powiadomienia wymuszają wyliczenia i struktury na status drugiej klasy. Uważam, że jest to poważny problem w Swift, ponieważ Enums są często ograniczonym int lub stringiem, a mimo to są w porządku jako wartość. – BaseZen

2

Najprostszym rozwiązaniem jest wysyłanie wartości RAW

RuleError.Create.rawValue 

które mogą być później przekształcane z powrotem do wyliczenia

RuleError(rawValue : "Create") 

ale parametru object nie jest odpowiednim miejscem do wyślij niestandardowe dane. Lepiej użyj słownika userInfo.

1

Możesz użyć boksu, aby wysłać czysty typ Swift jak enum przez NSNotification.

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

Aby wysyłać powiadomienia:

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

W swojej obserwatora, wartość można odczytać jako:

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

można wysłać Swift enum nawet z wartościami powiązanymi.

+0

Czy nie powinno to być 'userInfo? [" RuleError "]' w ostatnim bloku kodu? – Tropper

0

Przykład.Swift 3

1: Tworzenie Imię powiadomieniem

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

2: Niektóre ENUM

enum NetworkReachabilityStatus { 
    case connected 
    case notConnected 
} 

3: Wysyłanie danych

NotificationCenter.default.post(name: Notification.Name.NetworkReachabilityStatus, 
        object:nil, 
        userInfo:[kNetworkRechabilityStatus: NetworkReachabilityStatus.notConnected]) 
  • kNetworkRechabilityStatus - jest ciąg stały

4: Obserwując

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

I nie zapomnij, aby zrezygnować z powiadomienia :)

Powiązane problemy