Swift 3에서 커스텀 알림을 작성하려면 어떻게 해야 합니까?
Objective-C에서 커스텀 알림은 단순한 NSString일 뿐이지만 WWDC 버전의 Swift 3에서는 그것이 무엇을 해야 하는지 명확하지 않습니다.
그것을 실현하는 더 깨끗한 방법이 있다고 생각한다.
extension Notification.Name {
static let onSelectedSkin = Notification.Name("on-selected-skin")
}
그리고 이렇게 쓸 수 있어요.
NotificationCenter.default.post(name: .onSelectedSkin, object: selectedSkin)
여기에 프로토콜을 사용할 수도 있습니다.
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
★★★★★★★★★★★★★★★★★★.
알림.post는 다음과 같이 정의됩니다.
public func post(name aName: NSNotification.Name, object anObject: AnyObject?)
Objective-C에서 알림 이름은 일반 NSString입니다.Swift에서는 NSNotification으로 정의됩니다.이름.
NSNotification.이름은 다음과 같이 정의됩니다.
public struct Name : RawRepresentable, Equatable, Hashable, Comparable {
public init(_ rawValue: String)
public init(rawValue: String)
}
이건 좀 이상해요. Enum이 될 거라고 예상했는데, 더 이상 아무런 이득이 없는 커스텀 구조가 아닌 것 같아요.
NSNotification 알림에 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)
@CesarVarela가 제안한 것과 유사한 다른 옵션을 제안할 수도 있습니다.
extension Notification.Name {
static var notificationName: Notification.Name {
return .init("notificationName")
}
}
이를 통해 알림을 쉽게 게시 및 구독할 수 있습니다.
NotificationCenter.default.post(Notification(name: .notificationName))
이게 도움이 되길 바라.
NSNotification에 사용자 정의 이니셜라이저를 추가할 수 있습니다.이름.
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)
NSNotification.Name(rawValue: "myNotificationName")
이것저것 섞어서 실장해 봤는데 이게 제일 편해요.관심 있는 사용자를 위한 공유:
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)
}
}
이건 그냥 참고 사항입니다.
// Add observer:
NotificationCenter.default.addObserver(self,
selector: #selector(notificationCallback),
name: MyClass.myNotification,
object: nil)
// Post notification:
let userInfo = ["foo": 1, "bar": "baz"] as [String: Any]
NotificationCenter.default.post(name: MyClass.myNotification,
object: nil,
userInfo: userInfo)
enum을 사용하는 장점은 컴파일러가 이름이 올바른지 확인할 수 있다는 것입니다.잠재적인 문제를 줄이고 리팩터링을 용이하게 합니다.
알림 이름에 따옴표로 묶인 문자열 대신 enum을 사용하는 사용자에게 이 코드는 다음과 같은 기능을 합니다.
enum MyNotification: String {
case somethingHappened
case somethingElseHappened
case anotherNotification
case oneMore
}
extension NotificationCenter {
func add(observer: Any, selector: Selector,
notification: MyNotification, object: Any? = nil) {
addObserver(observer, selector: selector,
name: Notification.Name(notification.rawValue),
object: object)
}
func post(notification: MyNotification,
object: Any? = nil, userInfo: [AnyHashable: Any]? = nil) {
post(name: NSNotification.Name(rawValue: notification.rawValue),
object: object, userInfo: userInfo)
}
}
그 후 다음과 같이 사용할 수 있습니다.
NotificationCenter.default.post(.somethingHappened)
질문과는 무관하지만 따옴표로 묶인 문자열을 입력하지 않도록 스토리보드 세그먼트에서도 같은 작업을 수행할 수 있습니다.
enum StoryboardSegue: String {
case toHere
case toThere
case unwindToX
}
extension UIViewController {
func perform(segue: StoryboardSegue) {
performSegue(withIdentifier: segue.rawValue, sender: self)
}
}
그런 다음 뷰 컨트롤러에서 다음과 같이 호출합니다.
perform(segue: .unwindToX)
@CesarVarela의 답변은 좋지만 코드를 조금 더 깔끔하게 하기 위해 다음을 수행할 수 있습니다.
extension Notification.Name {
typealias Name = Notification.Name
static let onSelectedSkin = Name("on-selected-skin")
static let onFoo = Name("on-foo")
}
Objective-C와 Swift를 동시에 사용하는 프로젝트에서 깔끔하게 작업하고 싶다면 Objective-C에서 알림을 만드는 것이 더 쉬웠습니다.
.m/.h 파일을 만듭니다.
//CustomNotifications.h
#import <Foundation/Foundation.h>
// Add all notifications here
extern const NSNotificationName yourNotificationName;
//CustomNotifications.m
#import "CustomNotifications.h"
// Add their string values here
const NSNotificationName yourNotificationName = @"your_notification_as_string";
고객님의 고객명MyProject-Bridging-Header.h
(당신의 프로젝트 이름을 딴) Swift에게 노출시킵니다.
#import "CustomNotifications.h"
Objective-C의 알림을 다음과 같이 사용합니다.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(yourMethod:) name:yourNotificationName:nil];
Swift(5)에서는 다음과 같습니다.
NotificationCenter.default.addObserver(self, selector: #selector(yourMethod(sender:)), name: .yourNotificationName, object: nil)
문자열 전용 사용자 지정 알림을 사용하는 경우 클래스를 확장할 필요가 없습니다.String
extension String {
var notificationName : Notification.Name{
return Notification.Name.init(self)
}
}
언급URL : https://stackoverflow.com/questions/37899778/how-do-you-create-custom-notifications-in-swift-3
'programing' 카테고리의 다른 글
merge --squash와 rebase의 차이점은 무엇입니까? (0) | 2023.04.10 |
---|---|
iOS에서 바코드를 스캔하려면 어떻게 해야 합니까? (0) | 2023.04.10 |
awk 또는 sed를 사용하여 문자열을 재귀적으로 검색/교체하려면 어떻게 해야 합니까? (0) | 2023.04.10 |
Windows 명령어프롬프트에서 환경변수를 갱신하는 명령어가 있습니까? (0) | 2023.04.10 |
Windows 및 Linux에서의 C++ 컴파일: ifdef 스위치 (0) | 2023.04.10 |