{"id":19189249,"url":"https://github.com/plexinc/lrnotificationobserver","last_synced_at":"2025-07-09T06:07:01.144Z","repository":{"id":138045076,"uuid":"267336000","full_name":"plexinc/LRNotificationObserver","owner":"plexinc","description":null,"archived":false,"fork":false,"pushed_at":"2021-04-21T07:01:55.000Z","size":44,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-01-04T06:21:42.680Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/plexinc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-27T14:06:53.000Z","updated_at":"2021-06-20T23:14:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"919059fe-b0be-43da-9565-aac77de76418","html_url":"https://github.com/plexinc/LRNotificationObserver","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plexinc%2FLRNotificationObserver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plexinc%2FLRNotificationObserver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plexinc%2FLRNotificationObserver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plexinc%2FLRNotificationObserver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/plexinc","download_url":"https://codeload.github.com/plexinc/LRNotificationObserver/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240266854,"owners_count":19774074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T11:28:46.303Z","updated_at":"2025-02-23T03:43:50.474Z","avatar_url":"https://github.com/plexinc.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"LRNotificationObserver\n======================\n\n[![Build Status](http://img.shields.io/travis/luisrecuenco/LRNotificationObserver/master.svg?style=flat)](https://travis-ci.org/luisrecuenco/LRNotificationObserver)\n[![Pod Version](http://img.shields.io/cocoapods/v/LRNotificationObserver.svg?style=flat)](http://cocoadocs.org/docsets/LRNotificationObserver/)\n[![Pod Platform](http://img.shields.io/cocoapods/p/LRNotificationObserver.svg?style=flat)](http://cocoadocs.org/docsets/LRNotificationObserver/)\n[![Pod License](http://img.shields.io/cocoapods/l/LRNotificationObserver.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html)\n\nLRNotificationObserver is a smarter, simpler and better way to use NSNotificationCenter with [RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization).\n\n### The problem about NSNotificationCenter\n\nThe typical use of NSNotificationCenter is a two-step process:\n\n1. Register for a specific notification.\n\n   ```\n   [[NSNotificationCenter defaultCenter] addObserver:anObserver\n                                             selector:@selector(handleNotification:)\n                                                 name:aNotificationName\n                                               object:anObjectThatFiresTheNotification];\n   ```\n\n2. Unregister from it.\n\n   ```\n   [[NSNotificationCenter defaultCenter] removeObserver:anObserver\n                                                    name:aNotificationName\n                                                  object:anObjectThatFiresTheNotification];\n   ```\n\n   You can also unsubscribe from every notification some observer may have registered for.\n\n   ```\n   [[NSNotificationCenter defaultCenter] removeObserver:self];\n   ```\n\nWhen using this code in a UIViewController subclass, we usually put the subscribe code in *init*, *viewDidLoad* or *view(Will/Did)Appear* and the unsubscribe code in *dealloc*, *viewDidUnload* or *view(Will/Did)Disappear*. Make sure to only unsubscribe from all notifications at once in dealloc unless you also want to unsubscribe from every notification the parent class may have subscribed. This is a typical problem in UIViewControllers when you unsubscribe from all notifications in viewDidDisappear by mistake and you stop receiving rotation events. Rule of thumb: unsubscribe from what you have explictly subscribed...\n\nThere are two main problems with that API:\n\n1. In the most common use of NSNotificationCenter, we will unsubscribe from all the notifications when the observer dies, that means, we have to override dealloc just to put that unsubscribe code. With ARC, it'd be nice if we didn't have to do this.\n\n2. We can only supply a selector, not a block.\n\nYes, not that big of a deal, this is not as a bad API as KVO is, but annoying still.\n\nThe second problem was solved by Apple when they introduced blocks to the language with iOS 4 and Mac OS X 10.6. The new way to listen to notifications is not [as harmful as some say](http://sealedabstract.com/code/nsnotificationcenter-with-blocks-considered-harmful/).\n\n```\nid observer = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification\n                                                                object:nil\n                                                                 queue:[NSOperationQueue mainQueue]\n                                                            usingBlock:^(NSNotification *note) {\n                                                                // Handle notification\n                                                            }];\n```\n\nThe real problem about this new API is that it is misunderstood most of the times. It returns an anonymous object (the observer) which must be saved just to unsubscribe when needed.\n\n```\n[[NSNotificationCenter defaultCenter] removeObserver:observer];\n```\n\nThat makes us not only saving that observer in our class, but also overriding dealloc and removing it from the notification center.\n\nSo, when Apple introduced this new API... why not using RAII and let that new observer unsubscribe from the notification when it dies? Why making us store that object to unsubscribe later which, in a lot of cases, is forgotten?\n\nThis is the issue LRNotificationObserver tries to solve.\n\n### Installation\n\n1. **Using CocoaPods**\n\n   Add LRNotificationObserver to your Podfile:\n\n   ```\n   platform :ios, \"6.0\"\n   pod 'LRNotificationObserver'\n   ```\n\n   Run the following command:\n\n   ```\n   pod install\n   ```\n\n2. **Manually**\n\n   Clone the project or add it as a submodule. Drag the whole LRNotificationObserver folder to your project.\n\n### Usage\n\nTo listen to notifications, you have to create a LRNotificationObserver instance. To do so, just use the following method.\n\n```\n+ (instancetype)observerForName:(NSString *)name\n                          block:(LRNotificationObserverBlock)block;\n```\n\nWhen the notification with that name is fired, the block will be executed.\n\nThe LRNotificationObserverBlock contains the NSNotification instance.\n\n```\ntypedef void(^LRNotificationObserverBlock)(NSNotification *note);\n```\n\nImagine you want to listen to background notifications, instead of using NSNotificationCenter and having to implement dealloc just to unsubscribe, you can simply hold a LRNotificationObserver property in the object where you want to handle the notification (your view controller for instance) and let it be released when the object dies. No more overriding dealloc just to unsubscribe from notifications. It is as simple as follows.\n\n```\n@property (nonatomic, strong) LRNotificationObserver *backgroundObserver;\n\nself.backgroundObserver = [LRNotificationObserver observerForName:UIApplicationDidEnterBackgroundNotification\n                                                            block:^(NSNotification *note) {\n                                                                // Do appropriate background task\n                                                            }];\n```\n\nThe most interesting method in LRNotificationObserver is *stopObserving* in case you want to unsubscribe in other places different from dealloc (*viewWillDisappear* from instance).\n\nMost times you just want to unsubscribe in dealloc. Having to create the observer property just to maintain the latter alive can be a little annoying. It's cleaner than implementing dealloc to do so for sure, but it's even cleaner not to do it... There's a way to do that, just use the following method.\n\n```\n+ (void)observeName:(NSString *)name\n              owner:(id)owner\n              block:(LRNotificationObserverBlock)block;\n```\n\nYou must provide an owner, which is in charge of retaining the observer which is created under the hood. Don't worry, that owner won't be retained whatsover. The observer will be attached to the owner at runtime and release it when the latter is deallocated.\n\nImagine you want to listen to memory warning notifications. Just use the following code.\n\n```\n[LRNotificationObserver observeName:UIApplicationDidReceiveMemoryWarningNotification\n                              owner:self\n                              block:^(NSNotification *note) {\n                                  // Purge unnecessary cache\n                              }];\n```\n\nThat's it, no deallocs, no new properties, just that code. Of cource, there are [other more obscure ways](http://www.merowing.info/2012/03/automatic-removal-of-nsnotificationcenter-or-kvo-observers/) to achieve the same thing.\n\nThere are various ways of getting the notification callbacks. You can use blocks or target-action pattern and specify the queue (NSOperationQueue and dispatch queue) in which you want to receive the callbacks. You can also specify the object from which you want to receive the notifications.\n\nImagine you want to update the UI in a specific method when receving a notification. The following code does so.\n\n```\n[LRNotificationObserver observeName:@\"someNotificationThatShouldUpdateTheUI\"\n                             object:anObject\n                              owner:anOwner\n                     dispatch_queue:dispatch_get_main_queue()\n                             target:viewController\n                           selector:@selector(methodToBeExecutedOnMainThread:)];\n```\n\nWhen using the target-action callback, you can choose to receive the notification object (specify : in the selector) or not. Just the same way as NSNotificationCenter *addObserver:selector:name:object:* works despite what Apple says...\n\n```\nnotificationSelector\nSelector that specifies the message the receiver sends notificationObserver to notify it of the notification posting. The method specified by notificationSelector must have one and only one argument (an instance of NSNotification).\n```\n\n### Tests\n\nRunning the tests is as simple as executing the rakefile.\n\n```\nrake\n```\n\n### Example\n\nTo run the simple example, remember to install cocoa pods dependencies first.\n\n```\nrake test:cocoa_pods\n```\n\n### Requirements\n\nLRNotificationObserver requires either iOS 6.0 or Mac OS X 10.8 and ARC.\n\nYou can still use LRNotificationObserver in your non-arc project. Just set -fobjc-arc compiler flag in every source file.\n\n### Contact\n\nLRNotificationObserver was created by Luis Recuenco: [@luisrecuenco](https://twitter.com/luisrecuenco).\n\n### Contributing\n\nIf you want to contribute to the project just follow this steps:\n\n1. Fork the repository.\n2. Clone your fork to your local machine.\n3. Create your feature branch with the appropriate tests.\n4. Commit your changes, run the tests, push to your fork and submit a pull request.\n\n## License\n\nLRNotificationObserver is available under the MIT license. See the [LICENSE file](https://github.com/luisrecuenco/LRNotificationObserver/blob/master/LICENSE) for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplexinc%2Flrnotificationobserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplexinc%2Flrnotificationobserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplexinc%2Flrnotificationobserver/lists"}