[swift] Swift 3에서 사용자 지정 알림을 어떻게 생성합니까?

Objective-C에서 사용자 지정 알림은 단순한 NSString 일 뿐이지 만 WWDC 버전의 Swift 3에서는 그것이 무엇인지 명확하지 않습니다.



답변

이를 위해 프로토콜을 사용할 수도 있습니다.

protocol NotificationName {
    var name: Notification.Name { get }
}

extension RawRepresentable where RawValue == String, Self: NotificationName {
    var name: Notification.Name {
        get {
            return Notification.Name(self.rawValue)
        }
    }
}

그런 다음 알림 이름 enum을 원하는 곳 으로 정의하십시오 . 예를 들면 :

class MyClass {
    enum Notifications: String, NotificationName {
        case myNotification
    }
}

그리고 그것을 다음과 같이 사용하십시오.

NotificationCenter.default.post(name: Notifications.myNotification.name, object: nil)

이렇게하면 알림 이름이 재단에서 분리됩니다 Notification.Name. 그리고 구현이 Notification.Name변경 되는 경우에만 프로토콜을 수정해야합니다 .


답변

그것을 달성하는 더 깨끗한 (내 생각에) 방법이 있습니다

extension Notification.Name {

    static let onSelectedSkin = Notification.Name("on-selected-skin")
}

그런 다음 이렇게 사용할 수 있습니다

NotificationCenter.default.post(name: .onSelectedSkin, object: selectedSkin)


답변

Notification.post는 다음과 같이 정의됩니다.

public func post(name aName: NSNotification.Name, object anObject: AnyObject?)

Objective-C에서 알림 이름은 일반 NSString입니다. Swift에서는 NSNotification.Name으로 정의됩니다.

NSNotification.Name은 다음과 같이 정의됩니다.

public struct Name : RawRepresentable, Equatable, Hashable, Comparable {
    public init(_ rawValue: String)
    public init(rawValue: String)
}

이것은 더 이상 이익이없는 것처럼 보이는 사용자 지정 구조체가 아닌 Enum이 될 것으로 기대하기 때문에 다소 이상합니다.

Notification for NSNotification.Name에는 typealias가 있습니다.

public typealias Name = NSNotification.Name

혼란스러운 부분은 알림과 NSNotification이 모두 Swift에 존재한다는 것입니다.

따라서 고유 한 사용자 지정 알림을 정의하려면 다음과 같이하십시오.

public class MyClass {
    static let myNotification = Notification.Name("myNotification")
}

그런 다음 그것을 부릅니다.

NotificationCenter.default().post(name: MyClass.myNotification, object: self)


답변

더 쉬운 방법 :

let name:NSNotification.Name = NSNotification.Name("notificationName")
NotificationCenter.default.post(name: name, object: nil)


답변

NSNotification.Name에 사용자 지정 이니셜 라이저를 추가 할 수 있습니다.

extension NSNotification.Name {
    enum Notifications: String {
        case foo, bar
    }
    init(_ value: Notifications) {
        self = NSNotification.Name(value.rawValue)
    }
}

용법:

NotificationCenter.default.post(name: Notification.Name(.foo), object: nil)


답변

@CesarVarela가 제안한 것과 유사한 다른 옵션을 제안 할 수 있습니다.

extension Notification.Name {
    static var notificationName: Notification.Name {
        return .init("notificationName")
    }
}

이렇게하면 알림을 쉽게 게시하고 구독 할 수 있습니다.

NotificationCenter.default.post(Notification(name: .notificationName))

이것이 당신을 도울 수 있기를 바랍니다.


답변

저기저기서 여러 가지를 혼합하여 직접 구현했으며 이것이 가장 편리하다는 것을 알았습니다. 관심이있는 사람을 위해 공유 :

public extension Notification {
    public class MyApp {
        public static let Something = Notification.Name("Notification.MyApp.Something")
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(self.onSomethingChange(notification:)),
                                               name: Notification.MyApp.Something,
                                               object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @IBAction func btnTapped(_ sender: UIButton) {
        NotificationCenter.default.post(name: Notification.MyApp.Something,
                                      object: self,
                                    userInfo: [Notification.MyApp.Something:"foo"])
    }

    func onSomethingChange(notification:NSNotification) {
        print("notification received")
        let userInfo = notification.userInfo!
        let key = Notification.MyApp.Something
        let something = userInfo[key]! as! String //Yes, this works :)
        print(something)
    }
}