In front of the
When I first learned the code related to NSNotification in Swift, I found that the type of the name parameter I was familiar with was changed from NSString in Objective-C to notification. name. Not exactly the String I expected… What’s going on here?
How do I use Notification in Swift
So, how do you use Notification in Swift? Take POST for example.
NotificationCenter.default.post(name: Notification.Name.UIApplicationDidFinishLaunching, object: nil)
Copy the code
Notification.Name can be omitted
NotificationCenter.default.post(name: .UIApplicationDidFinishLaunching, object: nil)
Copy the code
View definition found UIApplicationDidFinishLaunching is actually defined in structure NSNotification. Name extensions (extension) in a static constants (static let). Type is the NSNotification. Name
extension NSNotification.Name {
@available(iOS 4.0*),public static let UIApplicationDidEnterBackground: NSNotification.Name
@available(iOS 4.0*),public static let UIApplicationWillEnterForeground: NSNotification.Name
public static let UIApplicationDidFinishLaunching: NSNotification.Name. }Copy the code
So we can omit the previous Notification. The Name directly using the UIApplicationDidFinishLaunching (Notification. The Name is NSNotification. Alias Name)
What if we want to customize a notification, just like the system, we can add an extension to it
extension Notification.Name {
static let LoginStatusChanged = Notification.Name("LoginStatusChanged")}Copy the code
Notification.Name(“LoginStatusChanged”) is the initialization method
NotificationCenter.default.post(name: .LoginStatusChanged, object: nil)
Copy the code
Since the Notification LoginStatusChanged is defined in notification. Name, there is no need to add Notification after the Name to indicate that this is a Notification. So many of the names defined in Swift are very succinct.
Compare the use in Objective-C
Contrast that with the previous use in Objective-C
[[NSNotificationCenter defaultCenter] postNotificationName:"xxxxxxxxxx" object:nil
This is very error-prone, and checking for such errors is often time-consuming and inelegant, so we often use macro definitions or constants to prevent the problem of hard-coding strings.
But this can actually cause some headaches:
- To indicate that the defined string constant is a notification name, add a lengthy prefix or suffix to it
- It is also common in development to see constant names in code completion that are completely different from the occasion
- For ease of use and maintenance, all notifications are defined in a xxdefine.h header file and referenced in the PCH file, if any notifications are added, deleted, or modified. This will cause a full recompilation of the project. Also very headache….
So Swift is a very elegant way to use it.
The lines
In development, there are many other scenarios that require strings to be passed like Notification, which can be optimized using this kind of usage method.
scenario
Consider a scenario where you define a class EventReporter to handle buried requests.
class EventReporter {
static let shared = EventReporter(a)func reportEvent(_ eventId: String, withParams params: [String:Any]?) {
// Buried point reporting logic}}Copy the code
EventId is the ID of the event we buried. How can we optimize such a scenario in a way similar to notification. Name?
The principle of
From the documentation, you can see that Notification.Name actually complies with a protocol RawRepresentable
Overview
With a RawRepresentable type, you can switch back and forth between a custom type and an associated RawValue type without losing the value of the original RawRepresentable type. Using the raw value of a conforming type streamlines interoperation with Objective-C and legacy APIs and simplifies conformance to other protocols, such as Equatable, Comparable, and Hashable.
The RawRepresentable protocol is seen mainly in two categories of types: enumerations with raw value types and option sets.
Simply put, RawRepresentable types are used to switch back and forth between a custom type and its associated RawValue type, simplifying interaction with Objective-C and traditional apis. Enumerations with primitive value types and option sets (optionSets, which in Swift are integrated with the Protocol implementation RawRepresentable). It’s just a type that encapsulates the type that we want to use like String to make it easier to interact.
implementation
It is simple to define a structure to manage all of the buried events
struct EventID: RawRepresentable {}Copy the code
Complete the protocol code as prompted by the compiler
struct EventID: RawRepresentable {
typealias RawValue = String
var rawValue: String
init? (rawValue:String) {}}Copy the code
This makes it easier to see how it works. In fact, the internal rawValue property is the name of the event of type String that we need to use, which the initializer passes in to assign a value to, and returns a structure of type EventID
The initializer for notification. Name is not Optional because it is defined as the event Name (Notification Name). And init method doesn’t raise an exception, so there’s no need to use Optional here, okay? Can be
struct EventID: RawRepresentable {
typealias RawValue = String
var rawValue: String
init(rawValue: String) {
self.rawValue = rawValue
}
}
Copy the code
So, the code for our reporting class could be modified as follows, and we could also give params a default value so that if there are no arguments, we can just pass the eventId argument.
class EventReporter {
static let shared = EventReporter(a)func reportEvent(_ eventId: EventID, withParams params: [String:Any]? = nil) {
let event = eventId.rawValue
// insert logic}}Copy the code
Finally, define a buried event to look at. It is recommended to write in extension for easy maintenance.
extension EventID {
static let LoginPageExposure = EventID(rawValue: "login_page_exposure")}Copy the code
So when you use it,
EventReporter.shared.reportEvent(.LoginPageExposure)
Copy the code
When we type., the code completion will already prompt LoginPageExposure to us.
conclusion
Optimizing your code this way not only makes the intent of your code easier to understand, but it’s also easier and error-free to use. It also does not cause the LoginPageExposure event name to be forcibly popped by code completion when it is not intended.
Reference
- NSNotification.Name
- RawRepresentable