2015-11-19 2 views
6

Я хочу послать перечисление в качестве объекта уведомления:Как отправить значение перечисления в уведомлении в Swift?

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

class myClass { 

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

К сожалению, это не работает, так как перечисление не соответствуетAnyObject?.

Любая идея, как обойти эту проблему?

ответ

7

Параметр object в функции, которую вы используете, является отправителем, объект отправляет уведомление, а не параметр. Ознакомьтесь с документами here.

Вы должны поместить значение перечисления, которое требуется передать в качестве параметра в информации пользователя словаря и использовать следующий метод:

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

В вашем случае:

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

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

И обрабатывать уведомление, первый регистр для него:

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

Затем справиться с этим:

func handleRuleFailNotification(notification: NSNotification) { 

     let userInfo = notification.userInfo 

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

Это досадная необходимость. Уведомления активируют перечисления и структуры во второй класс. Я чувствую, что это серьезный недостаток в Swift, поскольку Enums часто являются только ограниченным Int или String, и все же они хороши как ценность. – BaseZen

2

Самое простое решение отправить необработанное значение

RuleError.Create.rawValue 

, которые впоследствии преобразуются обратно в перечислении

RuleError(rawValue : "Create") 

Но параметра object не является подходящим местом для отправлять пользовательские данные. Лучше используйте словарь userInfo.

1

Вы можете использовать бокс, чтобы отправить чистый тип Swift, например enum, через NSNotification.

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

Чтобы отправить уведомление:

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

В вашем наблюдателя, величина может быть получена как:

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

Вы можете отправить Swift перечисление даже с соответствующими значениями.

+0

Разве это не 'userInfo? [" RuleError "]' в последнем блоке кода? – Tropper

0

Пример.Swift 3

1: создание имени УВЕДОМЛЕНИЕ

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

2: Некоторые Enum

enum NetworkReachabilityStatus { 
    case connected 
    case notConnected 
} 

3: Ваши данные

NotificationCenter.default.post(name: Notification.Name.NetworkReachabilityStatus, 
        object:nil, 
        userInfo:[kNetworkRechabilityStatus: NetworkReachabilityStatus.notConnected]) 
  • kNetworkRechabilityStatus - это строковая константа

4: Наблюдение

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

И не забудьте отказаться от уведомления :)