├── .travis.yml ├── Example ├── LRNotificationObserverExample │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── LRNotificationObserverExample-Prefix.pch │ ├── main.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── LRNotificationObserverExample-Info.plist │ ├── AppDelegate.h │ └── AppDelegate.m ├── LRNotificationObserverExampleTests │ ├── en.lproj │ │ └── InfoPlist.strings │ └── LRNotificationObserverExampleTests-Info.plist ├── Podfile ├── LRNotificationObserverExample.xcworkspace │ └── contents.xcworkspacedata └── LRNotificationObserverExample.xcodeproj │ ├── project.xcworkspace │ └── contents.xcworkspacedata │ ├── xcuserdata │ └── luisrecuenco.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist │ ├── xcshareddata │ └── xcschemes │ │ ├── LRNotificationObserverExampleTests.xcscheme │ │ └── LRNotificationObserverExample.xcscheme │ └── project.pbxproj ├── .gitignore ├── Package.swift ├── LRNotificationObserver.podspec ├── LICENSE ├── Rakefile ├── LRNotificationObserver ├── LRNotificationObserver.h ├── LRNotificationObserver+Owner.h ├── LRNotificationObserver+NSNotificationCenter.h ├── LRNotificationObserver+NSNotificationCenter.m ├── LRNotificationObserver+Owner.m └── LRNotificationObserver.m ├── README.md └── Tests └── LRNotificationObserverTests.m /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | script: rake 3 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExampleTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '6.0' 2 | 3 | target :LRNotificationObserverExampleTests, :exclusive => true do 4 | pod 'Kiwi' 5 | end 6 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | 20 | #CocoaPods 21 | Example/Pods 22 | Example/Podfile.lock 23 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample/LRNotificationObserverExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LRNotificationObserverExample 4 | // 5 | // Created by Luis Recuenco on 30/10/13. 6 | // Copyright (c) 2013 Luis Recuenco. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "LRNotificationObserver", 6 | products: [ 7 | .library( 8 | name: "LRNotificationObserver", 9 | targets: ["LRNotificationObserver"]), 10 | ], 11 | dependencies: [], 12 | targets: [ 13 | .target( 14 | name: "LRNotificationObserver", 15 | path: "LRNotificationObserver", 16 | publicHeadersPath: ""), 17 | ] 18 | ) 19 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /LRNotificationObserver.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'LRNotificationObserver' 3 | s.version = '0.1.2' 4 | s.license = 'MIT' 5 | s.summary = 'A smarter, simple and better way to use NSNotificationCenter with RAII.' 6 | s.homepage = 'https://github.com/luisrecuenco/LRNotificationObserver' 7 | s.author = { "Luis Recuenco" => "luisrecuenco@gmail.com" } 8 | s.source = { :git => 'https://github.com/luisrecuenco/LRNotificationObserver.git', :tag => '0.1.2' } 9 | s.ios.deployment_target = '6.0' 10 | s.osx.deployment_target = '10.8' 11 | s.tvos.deployment_target = '9.0' 12 | s.source_files = 'LRNotificationObserver' 13 | s.requires_arc = true 14 | end 15 | 16 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExampleTests/LRNotificationObserverExampleTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | Luis-Recuenco.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample.xcodeproj/xcuserdata/luisrecuenco.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LRNotificationObserverExample.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | LRNotificationObserverExampleTests.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 33B24EB118208B7000E866E5 21 | 22 | primary 23 | 24 | 25 | 33B24ECC18208B7000E866E5 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 luisrecuenco 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | namespace :test do 2 | desc "Install xctool latest version necessary to run the tests" 3 | task :prepare_for_xctool do 4 | system("brew update && brew uninstall xctool && brew install xctool --HEAD") 5 | end 6 | 7 | desc "Install cocoa pods dependencies" 8 | task :cocoa_pods do 9 | system("cd Example && pod install") 10 | end 11 | 12 | desc "Run the LRNotificationObserver tests with xctool" 13 | task :xctool => :cocoa_pods do 14 | $success = system("cd Example && xctool test -workspace LRNotificationObserverExample.xcworkspace -scheme LRNotificationObserverExampleTests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO") 15 | end 16 | 17 | desc "Run the LRNotificationObserver tests with xcodebuild" 18 | task :xcodebuild => :cocoa_pods do 19 | $success = system('cd Example && xcodebuild test -workspace LRNotificationObserverExample.xcworkspace -scheme LRNotificationObserverExampleTests -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO') 20 | end 21 | end 22 | 23 | desc "Run the LRNotificationObserver tests" 24 | task :test => 'test:xcodebuild' do 25 | if $success 26 | puts "\033[0;32m** iOS unit tests passed successfully **" 27 | else 28 | puts "\033[0;31m** iOS unit tests failed **" 29 | end 30 | end 31 | 32 | task :default => :test 33 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample/LRNotificationObserverExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | Luis-Recuenco.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // AppDelegate.h 2 | // 3 | // Copyright (c) 2013 Luis Recuenco 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | @interface AppDelegate : UIResponder 26 | 27 | @property (strong, nonatomic) UIWindow *window; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample.xcodeproj/xcshareddata/xcschemes/LRNotificationObserverExampleTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 52 | 53 | 54 | 55 | 61 | 62 | 64 | 65 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /LRNotificationObserver/LRNotificationObserver.h: -------------------------------------------------------------------------------- 1 | // LRNotificationObserver.h 2 | // 3 | // Copyright (c) 2013 Luis Recuenco 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | typedef void(^LRNotificationObserverBlock)(NSNotification *note); 26 | 27 | @interface LRNotificationObserver : NSObject 28 | 29 | - (instancetype)initWithNotificationCenter:(NSNotificationCenter *)notificationCenter; 30 | 31 | - (void)configureForName:(NSString *)name 32 | block:(LRNotificationObserverBlock)block; 33 | 34 | - (void)configureForName:(NSString *)name 35 | operationQueue:(NSOperationQueue *)operationQueue 36 | block:(LRNotificationObserverBlock)block; 37 | 38 | - (void)configureForName:(NSString *)name 39 | dispatchQueue:(dispatch_queue_t)dispatchQueue 40 | block:(LRNotificationObserverBlock)block; 41 | 42 | - (void)configureForName:(NSString *)name 43 | target:(id)target 44 | action:(SEL)action; 45 | 46 | - (void)configureForName:(NSString *)name 47 | operationQueue:(NSOperationQueue *)operationQueue 48 | target:(id)target 49 | action:(SEL)action; 50 | 51 | - (void)configureForName:(NSString *)name 52 | dispatchQueue:(dispatch_queue_t)dispatchQueue 53 | target:(id)target 54 | action:(SEL)action; 55 | 56 | - (void)stopObserving; 57 | 58 | @end 59 | 60 | @interface LRNotificationObserver (Object) 61 | 62 | - (void)configureForName:(NSString *)name 63 | object:(id)object 64 | block:(LRNotificationObserverBlock)block; 65 | 66 | - (void)configureForName:(NSString *)name 67 | object:(id)object 68 | operationQueue:(NSOperationQueue *)operationQueue 69 | block:(LRNotificationObserverBlock)block; 70 | 71 | - (void)configureForName:(NSString *)name 72 | object:(id)object 73 | dispatchQueue:(dispatch_queue_t)dispatchQueue 74 | block:(LRNotificationObserverBlock)block; 75 | 76 | - (void)configureForName:(NSString *)name 77 | object:(id)object 78 | target:(id)target 79 | action:(SEL)action; 80 | 81 | - (void)configureForName:(NSString *)name 82 | object:(id)object 83 | operationQueue:(NSOperationQueue *)operationQueue 84 | target:(id)target 85 | action:(SEL)action; 86 | 87 | - (void)configureForName:(NSString *)name 88 | object:(id)object 89 | dispatchQueue:(dispatch_queue_t)dispatchQueue 90 | target:(id)target 91 | action:(SEL)action; 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /LRNotificationObserver/LRNotificationObserver+Owner.h: -------------------------------------------------------------------------------- 1 | // LRNotificationObserver+Owner.h 2 | // 3 | // Copyright (c) 2014 Luis Recuenco 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LRNotificationObserver.h" 24 | 25 | @interface LRNotificationObserver (Owner) 26 | 27 | + (void)observeName:(NSString *)name 28 | owner:(id)owner 29 | block:(LRNotificationObserverBlock)block; 30 | 31 | + (void)observeName:(NSString *)name 32 | owner:(id)owner 33 | operationQueue:(NSOperationQueue *)operationQueue 34 | block:(LRNotificationObserverBlock)block; 35 | 36 | + (void)observeName:(NSString *)name 37 | owner:(id)owner 38 | dispatchQueue:(dispatch_queue_t)dispatchQueue 39 | block:(LRNotificationObserverBlock)block; 40 | 41 | + (void)observeName:(NSString *)name 42 | owner:(id)owner 43 | target:(id)target 44 | action:(SEL)action; 45 | 46 | + (void)observeName:(NSString *)name 47 | owner:(id)owner 48 | operationQueue:(NSOperationQueue *)operationQueue 49 | target:(id)target 50 | action:(SEL)action; 51 | 52 | + (void)observeName:(NSString *)name 53 | owner:(id)owner 54 | dispatchQueue:(dispatch_queue_t)dispatchQueue 55 | target:(id)target 56 | action:(SEL)action; 57 | 58 | @end 59 | 60 | @interface LRNotificationObserver (Owner_Object) 61 | 62 | + (void)observeName:(NSString *)name 63 | object:(id)object 64 | owner:(id)owner 65 | block:(LRNotificationObserverBlock)block; 66 | 67 | + (void)observeName:(NSString *)name 68 | object:(id)object 69 | owner:(id)owner 70 | operationQueue:(NSOperationQueue *)operationQueue 71 | block:(LRNotificationObserverBlock)block; 72 | 73 | + (void)observeName:(NSString *)name 74 | object:(id)object 75 | owner:(id)owner 76 | dispatchQueue:(dispatch_queue_t)dispatchQueue 77 | block:(LRNotificationObserverBlock)block; 78 | 79 | + (void)observeName:(NSString *)name 80 | object:(id)object 81 | owner:(id)owner 82 | target:(id)target 83 | action:(SEL)action; 84 | 85 | + (void)observeName:(NSString *)name 86 | object:(id)object 87 | owner:(id)owner 88 | operationQueue:(NSOperationQueue *)operationQueue 89 | target:(id)target 90 | action:(SEL)action; 91 | 92 | + (void)observeName:(NSString *)name 93 | object:(id)object 94 | owner:(id)owner 95 | dispatchQueue:(dispatch_queue_t)dispatchQueue 96 | target:(id)target 97 | action:(SEL)action; 98 | @end 99 | -------------------------------------------------------------------------------- /LRNotificationObserver/LRNotificationObserver+NSNotificationCenter.h: -------------------------------------------------------------------------------- 1 | // LRNotificationObserver+NSNotificationCenter.h 2 | // 3 | // Copyright (c) 2014 Luis Recuenco 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LRNotificationObserver.h" 24 | 25 | @interface LRNotificationObserver (NSNotificationCenter) 26 | 27 | + (instancetype)observerForName:(NSString *)name 28 | block:(LRNotificationObserverBlock)block; 29 | 30 | + (instancetype)observerForName:(NSString *)name 31 | operationQueue:(NSOperationQueue *)operationQueue 32 | block:(LRNotificationObserverBlock)block; 33 | 34 | + (instancetype)observerForName:(NSString *)name 35 | dispatchQueue:(dispatch_queue_t)dispatchQueue 36 | block:(LRNotificationObserverBlock)block; 37 | 38 | + (instancetype)observerForName:(NSString *)name 39 | target:(id)target 40 | action:(SEL)action; 41 | 42 | + (instancetype)observerForName:(NSString *)name 43 | operationQueue:(NSOperationQueue *)operationQueue 44 | target:(id)target 45 | action:(SEL)action; 46 | 47 | + (instancetype)observerForName:(NSString *)name 48 | dispatchQueue:(dispatch_queue_t)dispatchQueue 49 | target:(id)target 50 | action:(SEL)action; 51 | @end 52 | 53 | @interface LRNotificationObserver (NSNotificationCenter_Object) 54 | 55 | + (instancetype)observerForName:(NSString *)name 56 | object:(id)object 57 | block:(LRNotificationObserverBlock)block; 58 | 59 | + (instancetype)observerForName:(NSString *)name 60 | object:(id)object 61 | operationQueue:(NSOperationQueue *)operationQueue 62 | block:(LRNotificationObserverBlock)block; 63 | 64 | + (instancetype)observerForName:(NSString *)name 65 | object:(id)object 66 | dispatchQueue:(dispatch_queue_t)dispatchQueue 67 | block:(LRNotificationObserverBlock)block; 68 | 69 | + (instancetype)observerForName:(NSString *)name 70 | object:(id)object 71 | target:(id)target 72 | action:(SEL)action; 73 | 74 | + (instancetype)observerForName:(NSString *)name 75 | object:(id)object 76 | operationQueue:(NSOperationQueue *)operationQueue 77 | target:(id)target 78 | action:(SEL)action; 79 | 80 | + (instancetype)observerForName:(NSString *)name 81 | object:(id)object 82 | dispatchQueue:(dispatch_queue_t)dispatchQueue 83 | target:(id)target 84 | action:(SEL)action; 85 | @end 86 | 87 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample.xcodeproj/xcshareddata/xcschemes/LRNotificationObserverExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /LRNotificationObserver/LRNotificationObserver+NSNotificationCenter.m: -------------------------------------------------------------------------------- 1 | // LRNotificationObserver+NSNotificationCenter.m 2 | // 3 | // Copyright (c) 2014 Luis Recuenco 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LRNotificationObserver+NSNotificationCenter.h" 24 | 25 | @implementation LRNotificationObserver (NSNotificationCenter) 26 | 27 | + (instancetype)observerForName:(NSString *)name 28 | block:(LRNotificationObserverBlock)block 29 | { 30 | return [self observerForName:name object:nil block:block]; 31 | } 32 | 33 | + (instancetype)observerForName:(NSString *)name 34 | object:(id)object 35 | block:(LRNotificationObserverBlock)block 36 | { 37 | return [self observerWithConfiguration:^(LRNotificationObserver *observer) { 38 | [observer configureForName:name object:object block:block]; 39 | }]; 40 | } 41 | 42 | + (instancetype)observerForName:(NSString *)name 43 | operationQueue:(NSOperationQueue *)operationQueue 44 | block:(LRNotificationObserverBlock)block 45 | { 46 | return [self observerForName:name object:nil operationQueue:operationQueue block:block]; 47 | } 48 | 49 | + (instancetype)observerForName:(NSString *)name 50 | object:(id)object 51 | operationQueue:(NSOperationQueue *)operationQueue 52 | block:(LRNotificationObserverBlock)block 53 | { 54 | return [self observerWithConfiguration:^(LRNotificationObserver *observer) { 55 | [observer configureForName:name object:object operationQueue:operationQueue block:block]; 56 | }]; 57 | } 58 | 59 | + (instancetype)observerForName:(NSString *)name 60 | dispatchQueue:(dispatch_queue_t)dispatchQueue 61 | block:(LRNotificationObserverBlock)block 62 | { 63 | return [self observerForName:name object:nil dispatchQueue:dispatchQueue block:block]; 64 | } 65 | 66 | + (instancetype)observerForName:(NSString *)name 67 | object:(id)object 68 | dispatchQueue:(dispatch_queue_t)dispatchQueue 69 | block:(LRNotificationObserverBlock)block 70 | { 71 | return [self observerWithConfiguration:^(LRNotificationObserver *observer) { 72 | [observer configureForName:name object:object dispatchQueue:dispatchQueue block:block]; 73 | }]; 74 | } 75 | 76 | + (instancetype)observerForName:(NSString *)name 77 | target:(id)target 78 | action:(SEL)action 79 | { 80 | return [self observerForName:name object:nil target:target action:action]; 81 | } 82 | 83 | + (instancetype)observerForName:(NSString *)name 84 | object:(id)object 85 | target:(id)target 86 | action:(SEL)action 87 | { 88 | return [self observerWithConfiguration:^(LRNotificationObserver *observer) { 89 | [observer configureForName:name object:object target:target action:action]; 90 | }]; 91 | } 92 | 93 | + (instancetype)observerForName:(NSString *)name 94 | operationQueue:(NSOperationQueue *)operationQueue 95 | target:(id)target 96 | action:(SEL)action 97 | { 98 | return [self observerForName:name 99 | object:nil 100 | operationQueue:operationQueue 101 | target:target 102 | action:action]; 103 | } 104 | 105 | + (instancetype)observerForName:(NSString *)name 106 | object:(id)object 107 | operationQueue:(NSOperationQueue *)operationQueue 108 | target:(id)target 109 | action:(SEL)action 110 | { 111 | return [self observerWithConfiguration:^(LRNotificationObserver *observer) { 112 | [observer configureForName:name 113 | object:object 114 | operationQueue:operationQueue 115 | target:target 116 | action:action]; 117 | }]; 118 | } 119 | 120 | + (instancetype)observerForName:(NSString *)name 121 | dispatchQueue:(dispatch_queue_t)dispatchQueue 122 | target:(id)target 123 | action:(SEL)action 124 | { 125 | return [self observerForName:name object:nil dispatchQueue:dispatchQueue target:target action:action]; 126 | } 127 | 128 | + (instancetype)observerForName:(NSString *)name 129 | object:(id)object 130 | dispatchQueue:(dispatch_queue_t)dispatchQueue 131 | target:(id)target 132 | action:(SEL)action 133 | { 134 | 135 | return [self observerWithConfiguration:^(LRNotificationObserver *observer) { 136 | [observer configureForName:name object:object dispatchQueue:dispatchQueue target:target action:action]; 137 | }]; 138 | } 139 | 140 | #pragma mark - Private 141 | 142 | + (LRNotificationObserver *)observerWithConfiguration:(void(^)(LRNotificationObserver *observer))configurationBlock 143 | { 144 | LRNotificationObserver *observer = [self notificationCenterObserver]; 145 | configurationBlock(observer); 146 | return observer; 147 | } 148 | 149 | + (LRNotificationObserver *)notificationCenterObserver 150 | { 151 | NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 152 | 153 | return [[LRNotificationObserver alloc] initWithNotificationCenter:notificationCenter]; 154 | } 155 | 156 | @end 157 | -------------------------------------------------------------------------------- /LRNotificationObserver/LRNotificationObserver+Owner.m: -------------------------------------------------------------------------------- 1 | // LRNotificationObserver+Owner.m 2 | // 3 | // Copyright (c) 2014 Luis Recuenco 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LRNotificationObserver+Owner.h" 24 | #import "LRNotificationObserver+NSNotificationCenter.h" 25 | #import 26 | 27 | @implementation LRNotificationObserver (Owner) 28 | 29 | + (void)observeName:(NSString *)name 30 | owner:(id)owner 31 | block:(LRNotificationObserverBlock)block; 32 | { 33 | [self observeName:name object:nil owner:owner block:block]; 34 | } 35 | 36 | + (void)observeName:(NSString *)name 37 | object:(id)object 38 | owner:(id)owner 39 | block:(LRNotificationObserverBlock)block; 40 | { 41 | [self observeWithOwner:owner observerBlock:^LRNotificationObserver *{ 42 | return [self observerForName:name object:object block:block]; 43 | }]; 44 | } 45 | 46 | + (void)observeName:(NSString *)name 47 | owner:(id)owner 48 | operationQueue:(NSOperationQueue *)operationQueue 49 | block:(LRNotificationObserverBlock)block 50 | { 51 | [self observeName:name object:nil owner:owner operationQueue:operationQueue block:block]; 52 | } 53 | 54 | + (void)observeName:(NSString *)name 55 | object:(id)object 56 | owner:(id)owner 57 | operationQueue:(NSOperationQueue *)operationQueue 58 | block:(LRNotificationObserverBlock)block 59 | { 60 | [self observeWithOwner:owner observerBlock:^LRNotificationObserver *{ 61 | return [self observerForName:name object:object operationQueue:operationQueue block:block]; 62 | }]; 63 | } 64 | 65 | + (void)observeName:(NSString *)name 66 | owner:(id)owner 67 | dispatchQueue:(dispatch_queue_t)dispatchQueue 68 | block:(LRNotificationObserverBlock)block 69 | { 70 | [self observeName:name object:nil owner:owner dispatchQueue:dispatchQueue block:block]; 71 | } 72 | 73 | + (void)observeName:(NSString *)name 74 | object:(id)object 75 | owner:(id)owner 76 | dispatchQueue:(dispatch_queue_t)dispatchQueue 77 | block:(LRNotificationObserverBlock)block 78 | { 79 | [self observeWithOwner:owner observerBlock:^LRNotificationObserver *{ 80 | return [self observerForName:name object:object dispatchQueue:dispatchQueue block:block]; 81 | }]; 82 | } 83 | 84 | + (void)observeName:(NSString *)name 85 | owner:(id)owner 86 | target:(id)target 87 | action:(SEL)action 88 | { 89 | [self observeName:name object:nil owner:owner target:target action:action]; 90 | } 91 | 92 | + (void)observeName:(NSString *)name 93 | object:(id)object 94 | owner:(id)owner 95 | target:(id)target 96 | action:(SEL)action 97 | { 98 | [self observeWithOwner:owner observerBlock:^LRNotificationObserver *{ 99 | return [self observerForName:name object:object target:target action:action]; 100 | }]; 101 | } 102 | 103 | + (void)observeName:(NSString *)name 104 | owner:(id)owner 105 | operationQueue:(NSOperationQueue *)operationQueue 106 | target:(id)target 107 | action:(SEL)action 108 | { 109 | [self observeName:name 110 | object:nil 111 | owner:owner 112 | operationQueue:operationQueue 113 | target:target 114 | action:action]; 115 | } 116 | 117 | + (void)observeName:(NSString *)name 118 | object:(id)object 119 | owner:(id)owner 120 | operationQueue:(NSOperationQueue *)operationQueue 121 | target:(id)target 122 | action:(SEL)action 123 | { 124 | [self observeWithOwner:owner observerBlock:^LRNotificationObserver *{ 125 | return [self observerForName:name 126 | object:object 127 | operationQueue:operationQueue 128 | target:target 129 | action:action]; 130 | }]; 131 | } 132 | 133 | + (void)observeName:(NSString *)name 134 | owner:(id)owner 135 | dispatchQueue:(dispatch_queue_t)dispatchQueue 136 | target:(id)target 137 | action:(SEL)action 138 | { 139 | [self observeName:name 140 | object:nil 141 | owner:owner 142 | dispatchQueue:dispatchQueue 143 | target:target 144 | action:action]; 145 | } 146 | 147 | + (void)observeName:(NSString *)name 148 | object:(id)object 149 | owner:(id)owner 150 | dispatchQueue:(dispatch_queue_t)dispatchQueue 151 | target:(id)target 152 | action:(SEL)action 153 | { 154 | [self observeWithOwner:owner observerBlock:^LRNotificationObserver *{ 155 | return [self observerForName:name 156 | object:object 157 | dispatchQueue:dispatchQueue 158 | target:target 159 | action:action]; 160 | }]; 161 | } 162 | 163 | #pragma mark - Private 164 | 165 | + (void)observeWithOwner:(id)owner observerBlock:(LRNotificationObserver *(^)(void))observerBlock 166 | { 167 | NSAssert(owner, @"Owner cannot be nil"); 168 | 169 | [self addObserver:observerBlock() asPropertyOfOwner:owner]; 170 | } 171 | 172 | + (void)addObserver:(LRNotificationObserver *)observer asPropertyOfOwner:(id)owner 173 | { 174 | objc_setAssociatedObject(owner, (__bridge void *)observer, observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 175 | } 176 | 177 | @end 178 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // AppDelegate.m 2 | // 3 | // Copyright (c) 2013 Luis Recuenco 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "AppDelegate.h" 24 | #import "LRNotificationObserver+NSNotificationCenter.h" 25 | #import "LRNotificationObserver+Owner.h" 26 | 27 | @interface AppDelegate () 28 | 29 | @property (nonatomic, strong) LRNotificationObserver *backgroundObserver; 30 | @property (nonatomic, strong) LRNotificationObserver *foregroundObserver; 31 | 32 | @end 33 | 34 | @implementation AppDelegate 35 | 36 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 37 | { 38 | if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) 39 | { 40 | UIUserNotificationSettings *notificationsSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:nil]; 41 | [application registerUserNotificationSettings:notificationsSettings]; 42 | } 43 | 44 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 45 | self.window.backgroundColor = [UIColor whiteColor]; 46 | [self.window makeKeyAndVisible]; 47 | 48 | __weak typeof(self) wself = self; 49 | self.backgroundObserver = [LRNotificationObserver observerForName:UIApplicationDidEnterBackgroundNotification 50 | block:^(NSNotification *note) { 51 | __strong typeof(wself) self = wself; 52 | [self showLocalNotification]; 53 | }]; 54 | 55 | self.foregroundObserver = [LRNotificationObserver observerForName:UIApplicationWillEnterForegroundNotification 56 | operationQueue:[NSOperationQueue mainQueue] 57 | target:self 58 | action:@selector(foregroundObserverFired:)]; 59 | 60 | [LRNotificationObserver observeName:UIApplicationDidReceiveMemoryWarningNotification 61 | owner:self 62 | dispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 63 | block:^(NSNotification *note) { 64 | __strong typeof(wself) self = wself; 65 | [self handleMemoryWarning]; 66 | }]; 67 | 68 | return YES; 69 | } 70 | 71 | #pragma mark - LRNotificationObserver actions 72 | 73 | - (void)foregroundObserverFired:(NSNotification *)notification 74 | { 75 | [self showAlertViewWithTitle:@"Foreground observer fired"]; 76 | } 77 | 78 | - (void)showLocalNotification 79 | { 80 | UILocalNotification *notification = [[UILocalNotification alloc] init]; 81 | notification.alertBody = @"Background observer fired"; 82 | notification.fireDate = [NSDate date]; 83 | [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 84 | } 85 | 86 | - (void)handleMemoryWarning 87 | { 88 | // This method is fired in a the global dispatch queue we specified, 89 | // going back to the main queue to show the alert. 90 | dispatch_async(dispatch_get_main_queue(), ^(void) { 91 | [self showAlertViewWithTitle:@"Memory warning observer fired"]; 92 | }); 93 | } 94 | 95 | - (void)showAlertViewWithTitle:(NSString *)title 96 | { 97 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title 98 | message:nil 99 | delegate:nil 100 | cancelButtonTitle:@"ok" 101 | otherButtonTitles:nil]; 102 | 103 | [alert show]; 104 | } 105 | 106 | - (void)applicationWillResignActive:(UIApplication *)application 107 | { 108 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 109 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 110 | } 111 | 112 | - (void)applicationDidEnterBackground:(UIApplication *)application 113 | { 114 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 115 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 116 | } 117 | 118 | - (void)applicationWillEnterForeground:(UIApplication *)application 119 | { 120 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 121 | } 122 | 123 | - (void)applicationDidBecomeActive:(UIApplication *)application 124 | { 125 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 126 | } 127 | 128 | - (void)applicationWillTerminate:(UIApplication *)application 129 | { 130 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LRNotificationObserver 2 | ====================== 3 | 4 | [![Build Status](http://img.shields.io/travis/luisrecuenco/LRNotificationObserver/master.svg?style=flat)](https://travis-ci.org/luisrecuenco/LRNotificationObserver) 5 | [![Pod Version](http://img.shields.io/cocoapods/v/LRNotificationObserver.svg?style=flat)](http://cocoadocs.org/docsets/LRNotificationObserver/) 6 | [![Pod Platform](http://img.shields.io/cocoapods/p/LRNotificationObserver.svg?style=flat)](http://cocoadocs.org/docsets/LRNotificationObserver/) 7 | [![Pod License](http://img.shields.io/cocoapods/l/LRNotificationObserver.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html) 8 | 9 | LRNotificationObserver is a smarter, simpler and better way to use NSNotificationCenter with [RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization). 10 | 11 | ### The problem about NSNotificationCenter 12 | 13 | The typical use of NSNotificationCenter is a two-step process: 14 | 15 | 1. Register for a specific notification. 16 | 17 | ``` 18 | [[NSNotificationCenter defaultCenter] addObserver:anObserver 19 | selector:@selector(handleNotification:) 20 | name:aNotificationName 21 | object:anObjectThatFiresTheNotification]; 22 | ``` 23 | 24 | 2. Unregister from it. 25 | 26 | ``` 27 | [[NSNotificationCenter defaultCenter] removeObserver:anObserver 28 | name:aNotificationName 29 | object:anObjectThatFiresTheNotification]; 30 | ``` 31 | 32 | You can also unsubscribe from every notification some observer may have registered for. 33 | 34 | ``` 35 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 36 | ``` 37 | 38 | When 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... 39 | 40 | There are two main problems with that API: 41 | 42 | 1. 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. 43 | 44 | 2. We can only supply a selector, not a block. 45 | 46 | Yes, not that big of a deal, this is not as a bad API as KVO is, but annoying still. 47 | 48 | The 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/). 49 | 50 | ``` 51 | id observer = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification 52 | object:nil 53 | queue:[NSOperationQueue mainQueue] 54 | usingBlock:^(NSNotification *note) { 55 | // Handle notification 56 | }]; 57 | ``` 58 | 59 | The 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. 60 | 61 | ``` 62 | [[NSNotificationCenter defaultCenter] removeObserver:observer]; 63 | ``` 64 | 65 | That makes us not only saving that observer in our class, but also overriding dealloc and removing it from the notification center. 66 | 67 | So, 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? 68 | 69 | This is the issue LRNotificationObserver tries to solve. 70 | 71 | ### Installation 72 | 73 | 1. **Using CocoaPods** 74 | 75 | Add LRNotificationObserver to your Podfile: 76 | 77 | ``` 78 | platform :ios, "6.0" 79 | pod 'LRNotificationObserver' 80 | ``` 81 | 82 | Run the following command: 83 | 84 | ``` 85 | pod install 86 | ``` 87 | 88 | 2. **Manually** 89 | 90 | Clone the project or add it as a submodule. Drag the whole LRNotificationObserver folder to your project. 91 | 92 | ### Usage 93 | 94 | To listen to notifications, you have to create a LRNotificationObserver instance. To do so, just use the following method. 95 | 96 | ``` 97 | + (instancetype)observerForName:(NSString *)name 98 | block:(LRNotificationObserverBlock)block; 99 | ``` 100 | 101 | When the notification with that name is fired, the block will be executed. 102 | 103 | The LRNotificationObserverBlock contains the NSNotification instance. 104 | 105 | ``` 106 | typedef void(^LRNotificationObserverBlock)(NSNotification *note); 107 | ``` 108 | 109 | Imagine 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. 110 | 111 | ``` 112 | @property (nonatomic, strong) LRNotificationObserver *backgroundObserver; 113 | 114 | self.backgroundObserver = [LRNotificationObserver observerForName:UIApplicationDidEnterBackgroundNotification 115 | block:^(NSNotification *note) { 116 | // Do appropriate background task 117 | }]; 118 | ``` 119 | 120 | The most interesting method in LRNotificationObserver is *stopObserving* in case you want to unsubscribe in other places different from dealloc (*viewWillDisappear* from instance). 121 | 122 | Most 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. 123 | 124 | ``` 125 | + (void)observeName:(NSString *)name 126 | owner:(id)owner 127 | block:(LRNotificationObserverBlock)block; 128 | ``` 129 | 130 | You 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. 131 | 132 | Imagine you want to listen to memory warning notifications. Just use the following code. 133 | 134 | ``` 135 | [LRNotificationObserver observeName:UIApplicationDidReceiveMemoryWarningNotification 136 | owner:self 137 | block:^(NSNotification *note) { 138 | // Purge unnecessary cache 139 | }]; 140 | ``` 141 | 142 | That'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. 143 | 144 | There 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. 145 | 146 | Imagine you want to update the UI in a specific method when receving a notification. The following code does so. 147 | 148 | ``` 149 | [LRNotificationObserver observeName:@"someNotificationThatShouldUpdateTheUI" 150 | object:anObject 151 | owner:anOwner 152 | dispatch_queue:dispatch_get_main_queue() 153 | target:viewController 154 | selector:@selector(methodToBeExecutedOnMainThread:)]; 155 | ``` 156 | 157 | When 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... 158 | 159 | ``` 160 | notificationSelector 161 | Selector 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). 162 | ``` 163 | 164 | ### Tests 165 | 166 | Running the tests is as simple as executing the rakefile. 167 | 168 | ``` 169 | rake 170 | ``` 171 | 172 | ### Example 173 | 174 | To run the simple example, remember to install cocoa pods dependencies first. 175 | 176 | ``` 177 | rake test:cocoa_pods 178 | ``` 179 | 180 | ### Requirements 181 | 182 | LRNotificationObserver requires either iOS 6.0 or Mac OS X 10.8 and ARC. 183 | 184 | You can still use LRNotificationObserver in your non-arc project. Just set -fobjc-arc compiler flag in every source file. 185 | 186 | ### Contact 187 | 188 | LRNotificationObserver was created by Luis Recuenco: [@luisrecuenco](https://twitter.com/luisrecuenco). 189 | 190 | ### Contributing 191 | 192 | If you want to contribute to the project just follow this steps: 193 | 194 | 1. Fork the repository. 195 | 2. Clone your fork to your local machine. 196 | 3. Create your feature branch with the appropriate tests. 197 | 4. Commit your changes, run the tests, push to your fork and submit a pull request. 198 | 199 | ## License 200 | 201 | LRNotificationObserver is available under the MIT license. See the [LICENSE file](https://github.com/luisrecuenco/LRNotificationObserver/blob/master/LICENSE) for more info. 202 | -------------------------------------------------------------------------------- /LRNotificationObserver/LRNotificationObserver.m: -------------------------------------------------------------------------------- 1 | // LRNotificationObserver.m 2 | // 3 | // Copyright (c) 2013 Luis Recuenco 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LRNotificationObserver.h" 24 | #import 25 | 26 | #pragma mark - LRTargetAction 27 | 28 | @interface LRTargetAction : NSObject 29 | 30 | @property (nonatomic, weak) id target; 31 | @property (nonatomic) SEL action; 32 | 33 | + (instancetype)targetActionWithTarget:(id)target action:(SEL)action; 34 | 35 | @end 36 | 37 | @implementation LRTargetAction 38 | 39 | + (instancetype)targetActionWithTarget:(id)target action:(SEL)action 40 | { 41 | LRTargetAction *targetAction = [[self alloc] init]; 42 | targetAction.target = target; 43 | targetAction.action = action; 44 | 45 | return targetAction; 46 | } 47 | 48 | @end 49 | 50 | #pragma mark - LRNotificationObserver 51 | 52 | static SEL sNotificationFiredAction; 53 | 54 | @interface LRNotificationObserver () 55 | 56 | @property (nonatomic, strong) NSNotificationCenter *notificationCenter; 57 | 58 | @property (nonatomic, copy) NSString *name; 59 | @property (nonatomic, weak) id object; 60 | 61 | // Blocked based 62 | @property (nonatomic, copy) LRNotificationObserverBlock block; 63 | 64 | // Target - selector based 65 | @property (nonatomic, strong) LRTargetAction *targetAction; 66 | 67 | // Calback queues 68 | @property (nonatomic, strong) NSOperationQueue *operationQueue; 69 | @property (nonatomic, strong) dispatch_queue_t dispatchQueue; 70 | 71 | @end 72 | 73 | @implementation LRNotificationObserver 74 | 75 | + (void)initialize 76 | { 77 | if (self == [LRNotificationObserver class]) 78 | { 79 | sNotificationFiredAction = @selector(notificationFired:); 80 | } 81 | } 82 | 83 | - (instancetype)initWithNotificationCenter:(NSNotificationCenter *)notificationCenter 84 | { 85 | NSParameterAssert(notificationCenter); 86 | 87 | self = [super init]; 88 | if (self) 89 | { 90 | _notificationCenter = notificationCenter; 91 | } 92 | return self; 93 | } 94 | 95 | - (void)configureForName:(NSString *)name block:(LRNotificationObserverBlock)block 96 | { 97 | [self configureForName:name object:nil block:block]; 98 | } 99 | 100 | - (void)configureForName:(NSString *)name 101 | object:(id)object 102 | block:(LRNotificationObserverBlock)block 103 | { 104 | [self configureForName:name 105 | object:object 106 | operationQueue:nil 107 | dispatchQueue:nil 108 | block:block]; 109 | } 110 | 111 | - (void)configureForName:(NSString *)name 112 | operationQueue:(NSOperationQueue *)operationQueue 113 | block:(LRNotificationObserverBlock)block 114 | { 115 | [self configureForName:name 116 | object:nil 117 | operationQueue:operationQueue 118 | block:block]; 119 | } 120 | 121 | - (void)configureForName:(NSString *)name 122 | object:(id)object 123 | operationQueue:(NSOperationQueue *)operationQueue 124 | block:(LRNotificationObserverBlock)block 125 | { 126 | [self configureForName:name 127 | object:object 128 | operationQueue:operationQueue 129 | dispatchQueue:nil 130 | block:block]; 131 | } 132 | 133 | - (void)configureForName:(NSString *)name 134 | dispatchQueue:(dispatch_queue_t)dispatchQueue 135 | block:(LRNotificationObserverBlock)block 136 | { 137 | [self configureForName:name 138 | object:nil 139 | dispatchQueue:dispatchQueue 140 | block:block]; 141 | } 142 | 143 | - (void)configureForName:(NSString *)name 144 | object:(id)object 145 | dispatchQueue:(dispatch_queue_t)dispatchQueue 146 | block:(LRNotificationObserverBlock)block 147 | { 148 | [self configureForName:name 149 | object:object 150 | operationQueue:nil 151 | dispatchQueue:dispatchQueue 152 | block:block]; 153 | } 154 | 155 | - (void)configureForName:(NSString *)name 156 | object:(id)object 157 | operationQueue:(NSOperationQueue *)operationQueue 158 | dispatchQueue:(dispatch_queue_t)dispatchQueue 159 | block:(LRNotificationObserverBlock)block 160 | { 161 | NSParameterAssert(block); 162 | 163 | [self stopObserving]; 164 | 165 | self.name = name; 166 | self.object = object; 167 | self.operationQueue = operationQueue; 168 | self.dispatchQueue = dispatchQueue; 169 | self.block = block; 170 | 171 | [self.notificationCenter addObserver:self 172 | selector:sNotificationFiredAction 173 | name:name 174 | object:object]; 175 | } 176 | 177 | - (void)configureForName:(NSString *)name target:(id)target action:(SEL)action 178 | { 179 | [self configureForName:name 180 | object:nil 181 | target:target 182 | action:action]; 183 | } 184 | 185 | - (void)configureForName:(NSString *)name 186 | object:(id)object 187 | target:(id)target 188 | action:(SEL)action 189 | { 190 | [self configureForName:name 191 | object:object 192 | target:target 193 | action:action 194 | operationQueue:nil 195 | dispatchQueue:nil]; 196 | } 197 | 198 | - (void)configureForName:(NSString *)name 199 | operationQueue:(NSOperationQueue *)operationQueue 200 | target:(id)target 201 | action:(SEL)action 202 | { 203 | [self configureForName:name 204 | object:nil 205 | operationQueue:operationQueue 206 | target:target 207 | action:action]; 208 | } 209 | 210 | - (void)configureForName:(NSString *)name 211 | object:(id)object 212 | operationQueue:(NSOperationQueue *)operationQueue 213 | target:(id)target 214 | action:(SEL)action 215 | { 216 | [self configureForName:name 217 | object:object 218 | target:target 219 | action:action 220 | operationQueue:operationQueue 221 | dispatchQueue:nil]; 222 | } 223 | 224 | - (void)configureForName:(NSString *)name 225 | dispatchQueue:(dispatch_queue_t)dispatchQueue 226 | target:(id)target 227 | action:(SEL)action 228 | { 229 | [self configureForName:name 230 | object:nil 231 | target:target 232 | action:action 233 | operationQueue:nil 234 | dispatchQueue:dispatchQueue]; 235 | } 236 | 237 | - (void)configureForName:(NSString *)name 238 | object:(id)object 239 | dispatchQueue:(dispatch_queue_t)dispatchQueue 240 | target:(id)target 241 | action:(SEL)action 242 | { 243 | [self configureForName:name 244 | object:object 245 | target:target 246 | action:action 247 | operationQueue:nil 248 | dispatchQueue:dispatchQueue]; 249 | } 250 | 251 | - (void)configureForName:(NSString *)name 252 | object:(id)object 253 | target:(id)target 254 | action:(SEL)action 255 | operationQueue:(NSOperationQueue *)operationQueue 256 | dispatchQueue:(dispatch_queue_t)dispatchQueue 257 | { 258 | [self stopObserving]; 259 | 260 | self.name = name; 261 | self.object = object; 262 | self.operationQueue = operationQueue; 263 | self.dispatchQueue = dispatchQueue; 264 | self.targetAction = [LRTargetAction targetActionWithTarget:target action:action]; 265 | 266 | __unused NSUInteger selectorArgumentCount = LRSelectorArgumentCount(target, action); 267 | 268 | NSParameterAssert(selectorArgumentCount <= 1); 269 | 270 | [self.notificationCenter addObserver:self 271 | selector:sNotificationFiredAction 272 | name:name 273 | object:object]; 274 | } 275 | 276 | #pragma mark - Callbacks 277 | 278 | - (void)notificationFired:(NSNotification *)notification 279 | { 280 | dispatch_block_t notificationFiredBlock = ^{ 281 | if (self.block) 282 | { 283 | self.block(notification); 284 | } 285 | void (*action)(id, SEL, id) = (void (*)(id, SEL, id))objc_msgSend; 286 | action(self.targetAction.target, self.targetAction.action, notification); 287 | }; 288 | 289 | [self executeNotificationFiredBlock:notificationFiredBlock]; 290 | } 291 | 292 | - (void)executeNotificationFiredBlock:(dispatch_block_t)block 293 | { 294 | if (self.operationQueue) 295 | { 296 | if ([NSThread isMainThread] && self.operationQueue == [NSOperationQueue mainQueue]) 297 | { 298 | block(); 299 | } 300 | else 301 | { 302 | [self.operationQueue addOperationWithBlock:block]; 303 | } 304 | } 305 | else if (self.dispatchQueue) 306 | { 307 | if ([NSThread isMainThread] && self.dispatchQueue == dispatch_get_main_queue()) 308 | { 309 | block(); 310 | } 311 | else 312 | { 313 | dispatch_async(self.dispatchQueue, block); 314 | } 315 | } 316 | else 317 | { 318 | block(); 319 | } 320 | } 321 | 322 | - (void)stopObserving 323 | { 324 | [_notificationCenter removeObserver:self name:_name object:_object]; 325 | [self clear]; 326 | } 327 | 328 | - (void)clear 329 | { 330 | _block = nil; 331 | _targetAction = nil; 332 | _operationQueue = nil; 333 | _dispatchQueue = nil; 334 | } 335 | 336 | - (void)dealloc 337 | { 338 | [self stopObserving]; 339 | } 340 | 341 | NS_INLINE NSUInteger LRSelectorArgumentCount(id target, SEL selector) 342 | { 343 | Method method = class_getInstanceMethod([target class], selector); 344 | NSInteger arguments = method_getNumberOfArguments(method); 345 | 346 | NSCAssert(arguments >= 2, @"Oops, wrong arguments"); /* 2 = self + _cmd */ 347 | 348 | return arguments - 2; 349 | } 350 | 351 | @end 352 | -------------------------------------------------------------------------------- /Tests/LRNotificationObserverTests.m: -------------------------------------------------------------------------------- 1 | // LRNotificationObserverTests.m 2 | // 3 | // Copyright (c) 2013 Luis Recuenco 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "Kiwi.h" 24 | #import "LRNotificationObserver.h" 25 | 26 | static SEL sNoArgumentsSelector; 27 | static SEL sOneArgumentsSelector; 28 | 29 | static NSNotification *sNotification; 30 | 31 | static NSOperationQueue *sCallbackOperationQueue; 32 | 33 | static const void *sCallbackDispatchQueueTag = &sCallbackDispatchQueueTag; 34 | static const void *sCallbackDispatchQueueContext; 35 | 36 | 37 | @interface LRNotificationTarget : NSObject 38 | 39 | @end 40 | 41 | @implementation LRNotificationTarget 42 | 43 | + (void)initialize 44 | { 45 | if (self == [LRNotificationTarget class]) 46 | { 47 | sNoArgumentsSelector = @selector(notificationFired); 48 | sOneArgumentsSelector = @selector(notificationFired:); 49 | } 50 | } 51 | 52 | - (void)notificationFired 53 | { 54 | sCallbackOperationQueue = [NSOperationQueue currentQueue]; 55 | sCallbackDispatchQueueContext = dispatch_get_specific(sCallbackDispatchQueueTag); 56 | } 57 | 58 | - (void)notificationFired:(NSNotification *)aNotification 59 | { 60 | sNotification = aNotification; 61 | sCallbackOperationQueue = [NSOperationQueue currentQueue]; 62 | sCallbackDispatchQueueContext = dispatch_get_specific(sCallbackDispatchQueueTag); 63 | } 64 | 65 | @end 66 | 67 | SPEC_BEGIN(Test) 68 | 69 | describe(@"LRNotificationObserverTests", ^{ 70 | 71 | __block LRNotificationObserver *sut = nil; 72 | __block NSNotificationCenter *notificationCenter = nil; 73 | __block LRNotificationTarget *target = nil; 74 | 75 | context(@"With not valid notification center", ^{ 76 | 77 | it(@"block based notification observer should raise exception", ^{ 78 | 79 | #if !NS_BLOCK_ASSERTIONS 80 | [[theBlock(^{ 81 | sut = [[LRNotificationObserver alloc] initWithNotificationCenter:nil]; 82 | }) should] raise]; 83 | #else 84 | [[theBlock(^{ 85 | sut = [[LRNotificationObserver alloc] initWithNotificationCenter:nil]; 86 | }) shouldNot] raise]; 87 | #endif 88 | }); 89 | }); 90 | 91 | context(@"With valid notification center", ^{ 92 | 93 | beforeEach(^{ 94 | notificationCenter = [NSNotificationCenter defaultCenter]; 95 | sut = [[LRNotificationObserver alloc] 96 | initWithNotificationCenter:notificationCenter]; 97 | }); 98 | 99 | afterEach(^{ 100 | sut = nil; 101 | notificationCenter = nil; 102 | }); 103 | 104 | it(@"notificaton center created correctly", ^{ 105 | [[sut shouldNot] beNil]; 106 | }); 107 | 108 | context(@"Block based", ^{ 109 | 110 | it(@"sut block called sync", ^{ 111 | 112 | NSString *notificationName = @"aNotificationName"; 113 | 114 | __block BOOL completionBlockCalled = NO; 115 | 116 | [sut configureForName:notificationName 117 | block:^(NSNotification *note) { 118 | completionBlockCalled = YES; 119 | }]; 120 | 121 | [notificationCenter postNotificationName:notificationName object:nil]; 122 | 123 | [[theValue(completionBlockCalled) should] equal:theValue(YES)]; 124 | }); 125 | 126 | it(@"sut with operation queue block called async", ^{ 127 | 128 | NSString *notificationName = @"aNotificationName"; 129 | NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; 130 | __block BOOL completionBlockCalled = NO; 131 | 132 | [sut configureForName:notificationName 133 | operationQueue:opQueue 134 | block:^(NSNotification *note) { 135 | completionBlockCalled = YES; 136 | }]; 137 | 138 | [notificationCenter postNotificationName:notificationName object:nil]; 139 | 140 | [[theValue(completionBlockCalled) should] equal:theValue(NO)]; 141 | [[expectFutureValue(theValue(completionBlockCalled)) shouldEventually] equal:theValue(YES)]; 142 | }); 143 | 144 | it(@"sut with dispatch queue block called async", ^{ 145 | 146 | NSString *notificationName = @"aNotificationName"; 147 | dispatch_queue_t serialQueue = dispatch_queue_create("com.LRNotificationObserver.LRNotificationObserverTestsQueue", DISPATCH_QUEUE_SERIAL); 148 | __block BOOL completionBlockCalled = NO; 149 | 150 | [sut configureForName:notificationName 151 | dispatchQueue:serialQueue 152 | block:^(NSNotification *note) { 153 | completionBlockCalled = YES; 154 | }]; 155 | 156 | [notificationCenter postNotificationName:notificationName object:nil]; 157 | 158 | [[theValue(completionBlockCalled) should] equal:theValue(NO)]; 159 | [[expectFutureValue(theValue(completionBlockCalled)) shouldEventually] equal:theValue(YES)]; 160 | }); 161 | 162 | it(@"sut with wrong notification name block not called", ^{ 163 | 164 | NSString *notificationName = @"aNotificationName"; 165 | NSString *anotherNotificationName = @"anotherNotificationName"; 166 | 167 | __block BOOL completionBlockCalled = NO; 168 | 169 | [sut configureForName:notificationName 170 | block:^(NSNotification *note) { 171 | completionBlockCalled = YES; 172 | }]; 173 | 174 | [notificationCenter postNotificationName:anotherNotificationName object:nil]; 175 | 176 | [[theValue(completionBlockCalled) should] equal:theValue(NO)]; 177 | }); 178 | 179 | it(@"sut with nil block should raise exception", ^{ 180 | 181 | NSString *notificationName = @"aNotificationName"; 182 | #if !NS_BLOCK_ASSERTIONS 183 | [[theBlock(^{ 184 | [sut configureForName:notificationName 185 | block:nil]; 186 | }) should] raise]; 187 | #else 188 | [[theBlock(^{ 189 | [sut configureForName:notificationName 190 | block:nil]; 191 | }) shouldNot] raise]; 192 | #endif 193 | }); 194 | 195 | it(@"sut block parameter should be of class NSNotification", ^{ 196 | 197 | NSString *notificationName = @"aNotificationName"; 198 | 199 | __block NSNotification *notification = nil; 200 | 201 | [sut configureForName:notificationName 202 | block:^(NSNotification *note) { 203 | notification = note; 204 | }]; 205 | 206 | [notificationCenter postNotificationName:notificationName object:nil]; 207 | 208 | [[notification should] beKindOfClass:[NSNotification class]]; 209 | }); 210 | 211 | it(@"sut configure twice should call last configured block", ^{ 212 | 213 | NSString *notificationName = @"aNotificationName"; 214 | 215 | __block BOOL firstCompletionBlockCalled = NO; 216 | __block BOOL secondCompletionBlockCalled = NO; 217 | 218 | [sut configureForName:notificationName block:^(NSNotification *note) { 219 | firstCompletionBlockCalled = YES; 220 | }]; 221 | 222 | [sut configureForName:notificationName block:^(NSNotification *note) { 223 | secondCompletionBlockCalled = YES; 224 | }]; 225 | 226 | [notificationCenter postNotificationName:notificationName object:nil]; 227 | 228 | [[theValue(firstCompletionBlockCalled) should] equal:theValue(NO)]; 229 | [[theValue(secondCompletionBlockCalled) should] equal:theValue(YES)]; 230 | }); 231 | 232 | it(@"sut block not called after stopObserving", ^{ 233 | 234 | NSString *notificationName = @"aNotificationName"; 235 | 236 | __block BOOL completionBlockCalled = NO; 237 | 238 | [sut configureForName:notificationName 239 | block:^(NSNotification *note) { 240 | completionBlockCalled = YES; 241 | }]; 242 | 243 | [sut stopObserving]; 244 | 245 | [notificationCenter postNotificationName:notificationName object:nil]; 246 | 247 | [[theValue(completionBlockCalled) should] equal:theValue(NO)]; 248 | }); 249 | 250 | it(@"sut block should be called in correct operation queue", ^{ 251 | 252 | NSString *notificationName = @"aNotificationName"; 253 | 254 | __block NSOperationQueue *callbackQueue = NULL; 255 | 256 | NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; 257 | 258 | [sut configureForName:notificationName 259 | operationQueue:opQueue 260 | block:^(NSNotification *note) { 261 | callbackQueue = [NSOperationQueue currentQueue]; 262 | }]; 263 | 264 | [notificationCenter postNotificationName:notificationName object:nil]; 265 | 266 | [[expectFutureValue(callbackQueue) shouldEventually] beIdenticalTo:opQueue]; 267 | }); 268 | 269 | it(@"sut block should be called sync in main operation queue", ^{ 270 | 271 | NSString *notificationName = @"aNotificationName"; 272 | 273 | NSOperationQueue *opQueue = [NSOperationQueue mainQueue]; 274 | 275 | __block BOOL completionBlockCalled = NO; 276 | 277 | [sut configureForName:notificationName 278 | operationQueue:opQueue 279 | block:^(NSNotification *note) { 280 | completionBlockCalled = YES; 281 | }]; 282 | 283 | [notificationCenter postNotificationName:notificationName object:nil]; 284 | 285 | [[theValue(completionBlockCalled) should] equal:theValue(YES)]; 286 | }); 287 | 288 | it(@"sut block should be called in correct dispatch queue", ^{ 289 | 290 | NSString *notificationName = @"aNotificationName"; 291 | 292 | dispatch_queue_t serialQueue = dispatch_queue_create("com.LRNotificationObserver.LRNotificationObserverTestsQueue", DISPATCH_QUEUE_SERIAL); 293 | 294 | void *queueTag = &queueTag; 295 | void *queueContext = &queueContext; 296 | 297 | __block void *callbackQueueContext = NULL; 298 | 299 | dispatch_queue_set_specific(serialQueue, queueTag, queueContext, NULL); 300 | 301 | [sut configureForName:notificationName 302 | dispatchQueue:serialQueue 303 | block:^(NSNotification *note) { 304 | callbackQueueContext = dispatch_get_specific(queueTag); 305 | }]; 306 | 307 | [notificationCenter postNotificationName:notificationName object:nil]; 308 | 309 | [[expectFutureValue(theValue(queueContext == callbackQueueContext)) shouldEventually] beYes]; 310 | }); 311 | 312 | it(@"sut block should be called sync in main dispatch queue", ^{ 313 | 314 | NSString *notificationName = @"aNotificationName"; 315 | 316 | dispatch_queue_t dispatchQueue = dispatch_get_main_queue(); 317 | 318 | __block BOOL completionBlockCalled = NO; 319 | 320 | [sut configureForName:notificationName 321 | dispatchQueue:dispatchQueue 322 | block:^(NSNotification *note) { 323 | completionBlockCalled = YES; 324 | }]; 325 | 326 | [notificationCenter postNotificationName:notificationName object:nil]; 327 | 328 | [[theValue(completionBlockCalled) should] equal:theValue(YES)]; 329 | }); 330 | }); 331 | 332 | context(@"Target seletor based", ^{ 333 | 334 | beforeEach(^{ 335 | target = [[LRNotificationTarget alloc] init]; 336 | sNotification = nil; 337 | sCallbackOperationQueue = nil; 338 | sCallbackDispatchQueueContext = NULL; 339 | }); 340 | 341 | it(@"sut called sync", ^{ 342 | 343 | NSString *notificationName = @"aNotificationName"; 344 | 345 | [sut configureForName:notificationName 346 | target:target 347 | action:sNoArgumentsSelector]; 348 | 349 | [[target should] receive:sNoArgumentsSelector]; 350 | 351 | [notificationCenter postNotificationName:notificationName object:nil]; 352 | }); 353 | 354 | it(@"sut with operation queue called async", ^{ 355 | 356 | NSString *notificationName = @"aNotificationName"; 357 | NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; 358 | 359 | [sut configureForName:notificationName 360 | operationQueue:opQueue 361 | target:target 362 | action:sNoArgumentsSelector]; 363 | 364 | [[target shouldNot] receive:sNoArgumentsSelector]; 365 | [[target shouldEventually] receive:sNoArgumentsSelector]; 366 | 367 | [notificationCenter postNotificationName:notificationName object:nil]; 368 | }); 369 | 370 | it(@"sut with dispatch queue called async", ^{ 371 | 372 | NSString *notificationName = @"aNotificationName"; 373 | dispatch_queue_t serialQueue = dispatch_queue_create("com.LRNotificationObserver.LRNotificationObserverTestsQueue", DISPATCH_QUEUE_SERIAL); 374 | 375 | [sut configureForName:notificationName 376 | dispatchQueue:serialQueue 377 | target:target 378 | action:sNoArgumentsSelector]; 379 | 380 | [[target shouldNot] receive:sNoArgumentsSelector]; 381 | [[target shouldEventually] receive:sNoArgumentsSelector]; 382 | 383 | [notificationCenter postNotificationName:notificationName object:nil]; 384 | }); 385 | 386 | it(@"sut with wrong notification name selector not called", ^{ 387 | 388 | NSString *notificationName = @"aNotificationName"; 389 | NSString *anotherNotificationName = @"anotherNotificationName"; 390 | 391 | [sut configureForName:notificationName target:target action:sOneArgumentsSelector]; 392 | 393 | [notificationCenter postNotificationName:anotherNotificationName object:nil]; 394 | 395 | [[target shouldNot] receive:sOneArgumentsSelector]; 396 | }); 397 | 398 | it(@"sut with unknown selector should raise exception", ^{ 399 | 400 | NSString *notificationName = @"aNotificationName"; 401 | 402 | SEL unknownSelector = NSSelectorFromString(@"unknownSelector"); 403 | 404 | #if !NS_BLOCK_ASSERTIONS 405 | [[theBlock(^{ 406 | [sut configureForName:notificationName 407 | target:target 408 | action:unknownSelector]; 409 | }) should] raise]; 410 | #else 411 | [[theBlock(^{ 412 | [sut configureForName:notificationName 413 | target:target 414 | action:unknownSelector]; 415 | }) shouldNot] raise]; 416 | #endif 417 | }); 418 | 419 | it(@"sut with nil target should raise exception", ^{ 420 | 421 | NSString *notificationName = @"aNotificationName"; 422 | 423 | #if !NS_BLOCK_ASSERTIONS 424 | [[theBlock(^{ 425 | [sut configureForName:notificationName 426 | target:nil 427 | action:sOneArgumentsSelector]; 428 | }) should] raise]; 429 | #else 430 | [[theBlock(^{ 431 | [sut configureForName:notificationName 432 | target:nil 433 | action:sOneArgumentsSelector]; 434 | }) shouldNot] raise]; 435 | #endif 436 | }); 437 | 438 | it(@"sut selector parameter should be of class NSNotification", ^{ 439 | 440 | NSString *notificationName = @"aNotificationName"; 441 | 442 | [sut configureForName:notificationName target:target action:sOneArgumentsSelector]; 443 | 444 | [notificationCenter postNotificationName:notificationName object:nil]; 445 | 446 | [[sNotification should] beKindOfClass:[NSNotification class]]; 447 | }); 448 | 449 | 450 | it(@"sut configure twice should call last configured selector", ^{ 451 | 452 | NSString *notificationName = @"aNotificationName"; 453 | 454 | [sut configureForName:notificationName target:target action:sNoArgumentsSelector]; 455 | [sut configureForName:notificationName target:target action:sOneArgumentsSelector]; 456 | 457 | [[target shouldNot] receive:sNoArgumentsSelector]; 458 | [[target should] receive:sOneArgumentsSelector]; 459 | 460 | [notificationCenter postNotificationName:notificationName object:nil]; 461 | }); 462 | 463 | it(@"sut selector not called after stopObserving", ^{ 464 | 465 | NSString *notificationName = @"aNotificationName"; 466 | 467 | [sut configureForName:notificationName 468 | target:target 469 | action:sNoArgumentsSelector]; 470 | 471 | [sut stopObserving]; 472 | 473 | [[target shouldNot] receive:sNoArgumentsSelector]; 474 | 475 | [notificationCenter postNotificationName:notificationName object:nil]; 476 | }); 477 | 478 | it(@"sut selector should be called in correct operation queue", ^{ 479 | 480 | NSString *notificationName = @"aNotificationName"; 481 | 482 | NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; 483 | 484 | [sut configureForName:notificationName 485 | operationQueue:opQueue 486 | target:target 487 | action:sNoArgumentsSelector]; 488 | 489 | [notificationCenter postNotificationName:notificationName object:nil]; 490 | 491 | [[expectFutureValue(sCallbackOperationQueue) shouldEventually] beIdenticalTo:opQueue]; 492 | }); 493 | 494 | it(@"sut selector should be called in correct dispatch queue", ^{ 495 | 496 | NSString *notificationName = @"aNotificationName"; 497 | 498 | dispatch_queue_t serialQueue = dispatch_queue_create("com.LRNotificationObserver.LRNotificationObserverTestsQueue", DISPATCH_QUEUE_SERIAL); 499 | 500 | void *queueContext = &queueContext; 501 | 502 | dispatch_queue_set_specific(serialQueue, sCallbackDispatchQueueTag, queueContext, NULL); 503 | 504 | [sut configureForName:notificationName 505 | dispatchQueue:serialQueue 506 | target:target 507 | action:sNoArgumentsSelector]; 508 | 509 | [notificationCenter postNotificationName:notificationName object:nil]; 510 | 511 | [[expectFutureValue(theValue(sCallbackDispatchQueueContext == queueContext)) shouldEventually] beYes]; 512 | }); 513 | }); 514 | }); 515 | }); 516 | 517 | SPEC_END 518 | -------------------------------------------------------------------------------- /Example/LRNotificationObserverExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2CD4876018869067005DA81F /* LRNotificationObserver+Owner.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CD4875F18869067005DA81F /* LRNotificationObserver+Owner.m */; }; 11 | 2CD4876118869067005DA81F /* LRNotificationObserver+Owner.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CD4875F18869067005DA81F /* LRNotificationObserver+Owner.m */; }; 12 | 33000121183AE92E009DD610 /* LRNotificationObserverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 33000120183AE92E009DD610 /* LRNotificationObserverTests.m */; }; 13 | 3333C74518208D1C0036A1C4 /* LRNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 3333C74418208D1C0036A1C4 /* LRNotificationObserver.m */; }; 14 | 3333C74618208D1C0036A1C4 /* LRNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 3333C74418208D1C0036A1C4 /* LRNotificationObserver.m */; }; 15 | 33B24EB618208B7000E866E5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B24EB518208B7000E866E5 /* Foundation.framework */; }; 16 | 33B24EB818208B7000E866E5 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B24EB718208B7000E866E5 /* CoreGraphics.framework */; }; 17 | 33B24EBA18208B7000E866E5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B24EB918208B7000E866E5 /* UIKit.framework */; }; 18 | 33B24EC018208B7000E866E5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 33B24EBE18208B7000E866E5 /* InfoPlist.strings */; }; 19 | 33B24EC218208B7000E866E5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 33B24EC118208B7000E866E5 /* main.m */; }; 20 | 33B24EC618208B7000E866E5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 33B24EC518208B7000E866E5 /* AppDelegate.m */; }; 21 | 33B24EC818208B7000E866E5 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33B24EC718208B7000E866E5 /* Images.xcassets */; }; 22 | 33B24ECF18208B7000E866E5 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B24ECE18208B7000E866E5 /* XCTest.framework */; }; 23 | 33B24ED018208B7000E866E5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B24EB518208B7000E866E5 /* Foundation.framework */; }; 24 | 33B24ED118208B7000E866E5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B24EB918208B7000E866E5 /* UIKit.framework */; }; 25 | 33B24ED918208B7000E866E5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 33B24ED718208B7000E866E5 /* InfoPlist.strings */; }; 26 | 33BA2CBE188605A300695361 /* LRNotificationObserver+NSNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 33BA2CBD188605A300695361 /* LRNotificationObserver+NSNotificationCenter.m */; }; 27 | 33BA2CBF188605A300695361 /* LRNotificationObserver+NSNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 33BA2CBD188605A300695361 /* LRNotificationObserver+NSNotificationCenter.m */; }; 28 | 7167C33F94364271AD3C8EFA /* libPods-LRNotificationObserverExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB5CC8BA75804C65B7584705 /* libPods-LRNotificationObserverExampleTests.a */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | 33B24ED218208B7000E866E5 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 33B24EAA18208B7000E866E5 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 33B24EB118208B7000E866E5; 37 | remoteInfo = LRNotificationObserverExample; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 2CD4875E18869067005DA81F /* LRNotificationObserver+Owner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "LRNotificationObserver+Owner.h"; path = "../../LRNotificationObserver/LRNotificationObserver+Owner.h"; sourceTree = ""; }; 43 | 2CD4875F18869067005DA81F /* LRNotificationObserver+Owner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "LRNotificationObserver+Owner.m"; path = "../../LRNotificationObserver/LRNotificationObserver+Owner.m"; sourceTree = ""; }; 44 | 33000120183AE92E009DD610 /* LRNotificationObserverTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LRNotificationObserverTests.m; path = ../../Tests/LRNotificationObserverTests.m; sourceTree = ""; }; 45 | 3333C74318208D1C0036A1C4 /* LRNotificationObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LRNotificationObserver.h; path = ../../LRNotificationObserver/LRNotificationObserver.h; sourceTree = ""; }; 46 | 3333C74418208D1C0036A1C4 /* LRNotificationObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LRNotificationObserver.m; path = ../../LRNotificationObserver/LRNotificationObserver.m; sourceTree = ""; }; 47 | 33B24EB218208B7000E866E5 /* LRNotificationObserverExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LRNotificationObserverExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 33B24EB518208B7000E866E5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 49 | 33B24EB718208B7000E866E5 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 50 | 33B24EB918208B7000E866E5 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 51 | 33B24EBD18208B7000E866E5 /* LRNotificationObserverExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LRNotificationObserverExample-Info.plist"; sourceTree = ""; }; 52 | 33B24EBF18208B7000E866E5 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 53 | 33B24EC118208B7000E866E5 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 54 | 33B24EC318208B7000E866E5 /* LRNotificationObserverExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LRNotificationObserverExample-Prefix.pch"; sourceTree = ""; }; 55 | 33B24EC418208B7000E866E5 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 56 | 33B24EC518208B7000E866E5 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 57 | 33B24EC718208B7000E866E5 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 58 | 33B24ECD18208B7000E866E5 /* LRNotificationObserverExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LRNotificationObserverExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 33B24ECE18208B7000E866E5 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 60 | 33B24ED618208B7000E866E5 /* LRNotificationObserverExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "LRNotificationObserverExampleTests-Info.plist"; sourceTree = ""; }; 61 | 33B24ED818208B7000E866E5 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 62 | 33BA2CBC188605A300695361 /* LRNotificationObserver+NSNotificationCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "LRNotificationObserver+NSNotificationCenter.h"; path = "../../LRNotificationObserver/LRNotificationObserver+NSNotificationCenter.h"; sourceTree = ""; }; 63 | 33BA2CBD188605A300695361 /* LRNotificationObserver+NSNotificationCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "LRNotificationObserver+NSNotificationCenter.m"; path = "../../LRNotificationObserver/LRNotificationObserver+NSNotificationCenter.m"; sourceTree = ""; }; 64 | B8EB2E55DE9045319A1D1CD3 /* Pods-LRNotificationObserverExampleTests.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LRNotificationObserverExampleTests.xcconfig"; path = "Pods/Pods-LRNotificationObserverExampleTests.xcconfig"; sourceTree = ""; }; 65 | DB5CC8BA75804C65B7584705 /* libPods-LRNotificationObserverExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LRNotificationObserverExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | 33B24EAF18208B7000E866E5 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | 33B24EB818208B7000E866E5 /* CoreGraphics.framework in Frameworks */, 74 | 33B24EBA18208B7000E866E5 /* UIKit.framework in Frameworks */, 75 | 33B24EB618208B7000E866E5 /* Foundation.framework in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 33B24ECA18208B7000E866E5 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | 33B24ECF18208B7000E866E5 /* XCTest.framework in Frameworks */, 84 | 33B24ED118208B7000E866E5 /* UIKit.framework in Frameworks */, 85 | 33B24ED018208B7000E866E5 /* Foundation.framework in Frameworks */, 86 | 7167C33F94364271AD3C8EFA /* libPods-LRNotificationObserverExampleTests.a in Frameworks */, 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | /* End PBXFrameworksBuildPhase section */ 91 | 92 | /* Begin PBXGroup section */ 93 | 33B24EA918208B7000E866E5 = { 94 | isa = PBXGroup; 95 | children = ( 96 | 33B24EBB18208B7000E866E5 /* LRNotificationObserverExample */, 97 | 33B24ED418208B7000E866E5 /* LRNotificationObserverExampleTests */, 98 | 33B24EB418208B7000E866E5 /* Frameworks */, 99 | 33B24EB318208B7000E866E5 /* Products */, 100 | B8EB2E55DE9045319A1D1CD3 /* Pods-LRNotificationObserverExampleTests.xcconfig */, 101 | ); 102 | sourceTree = ""; 103 | }; 104 | 33B24EB318208B7000E866E5 /* Products */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 33B24EB218208B7000E866E5 /* LRNotificationObserverExample.app */, 108 | 33B24ECD18208B7000E866E5 /* LRNotificationObserverExampleTests.xctest */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 33B24EB418208B7000E866E5 /* Frameworks */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 33B24EB518208B7000E866E5 /* Foundation.framework */, 117 | 33B24EB718208B7000E866E5 /* CoreGraphics.framework */, 118 | 33B24EB918208B7000E866E5 /* UIKit.framework */, 119 | 33B24ECE18208B7000E866E5 /* XCTest.framework */, 120 | DB5CC8BA75804C65B7584705 /* libPods-LRNotificationObserverExampleTests.a */, 121 | ); 122 | name = Frameworks; 123 | sourceTree = ""; 124 | }; 125 | 33B24EBB18208B7000E866E5 /* LRNotificationObserverExample */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 33B24EE418208B9A00E866E5 /* LRNotificationObserver */, 129 | 33B24EC418208B7000E866E5 /* AppDelegate.h */, 130 | 33B24EC518208B7000E866E5 /* AppDelegate.m */, 131 | 33B24EC718208B7000E866E5 /* Images.xcassets */, 132 | 33B24EBC18208B7000E866E5 /* Supporting Files */, 133 | ); 134 | path = LRNotificationObserverExample; 135 | sourceTree = ""; 136 | }; 137 | 33B24EBC18208B7000E866E5 /* Supporting Files */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 33B24EBD18208B7000E866E5 /* LRNotificationObserverExample-Info.plist */, 141 | 33B24EBE18208B7000E866E5 /* InfoPlist.strings */, 142 | 33B24EC118208B7000E866E5 /* main.m */, 143 | 33B24EC318208B7000E866E5 /* LRNotificationObserverExample-Prefix.pch */, 144 | ); 145 | name = "Supporting Files"; 146 | sourceTree = ""; 147 | }; 148 | 33B24ED418208B7000E866E5 /* LRNotificationObserverExampleTests */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 33000120183AE92E009DD610 /* LRNotificationObserverTests.m */, 152 | 33B24ED518208B7000E866E5 /* Supporting Files */, 153 | ); 154 | path = LRNotificationObserverExampleTests; 155 | sourceTree = ""; 156 | }; 157 | 33B24ED518208B7000E866E5 /* Supporting Files */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 33B24ED618208B7000E866E5 /* LRNotificationObserverExampleTests-Info.plist */, 161 | 33B24ED718208B7000E866E5 /* InfoPlist.strings */, 162 | ); 163 | name = "Supporting Files"; 164 | sourceTree = ""; 165 | }; 166 | 33B24EE418208B9A00E866E5 /* LRNotificationObserver */ = { 167 | isa = PBXGroup; 168 | children = ( 169 | 3333C74318208D1C0036A1C4 /* LRNotificationObserver.h */, 170 | 3333C74418208D1C0036A1C4 /* LRNotificationObserver.m */, 171 | 33BA2CBC188605A300695361 /* LRNotificationObserver+NSNotificationCenter.h */, 172 | 33BA2CBD188605A300695361 /* LRNotificationObserver+NSNotificationCenter.m */, 173 | 2CD4875E18869067005DA81F /* LRNotificationObserver+Owner.h */, 174 | 2CD4875F18869067005DA81F /* LRNotificationObserver+Owner.m */, 175 | ); 176 | name = LRNotificationObserver; 177 | sourceTree = ""; 178 | }; 179 | /* End PBXGroup section */ 180 | 181 | /* Begin PBXNativeTarget section */ 182 | 33B24EB118208B7000E866E5 /* LRNotificationObserverExample */ = { 183 | isa = PBXNativeTarget; 184 | buildConfigurationList = 33B24EDE18208B7000E866E5 /* Build configuration list for PBXNativeTarget "LRNotificationObserverExample" */; 185 | buildPhases = ( 186 | 33B24EAE18208B7000E866E5 /* Sources */, 187 | 33B24EAF18208B7000E866E5 /* Frameworks */, 188 | 33B24EB018208B7000E866E5 /* Resources */, 189 | ); 190 | buildRules = ( 191 | ); 192 | dependencies = ( 193 | ); 194 | name = LRNotificationObserverExample; 195 | productName = LRNotificationObserverExample; 196 | productReference = 33B24EB218208B7000E866E5 /* LRNotificationObserverExample.app */; 197 | productType = "com.apple.product-type.application"; 198 | }; 199 | 33B24ECC18208B7000E866E5 /* LRNotificationObserverExampleTests */ = { 200 | isa = PBXNativeTarget; 201 | buildConfigurationList = 33B24EE118208B7000E866E5 /* Build configuration list for PBXNativeTarget "LRNotificationObserverExampleTests" */; 202 | buildPhases = ( 203 | C2211F5B3A4943CC84423738 /* Check Pods Manifest.lock */, 204 | 33B24EC918208B7000E866E5 /* Sources */, 205 | 33B24ECA18208B7000E866E5 /* Frameworks */, 206 | 33B24ECB18208B7000E866E5 /* Resources */, 207 | 90A2024AD0244749AAD6610A /* Copy Pods Resources */, 208 | ); 209 | buildRules = ( 210 | ); 211 | dependencies = ( 212 | 33B24ED318208B7000E866E5 /* PBXTargetDependency */, 213 | ); 214 | name = LRNotificationObserverExampleTests; 215 | productName = LRNotificationObserverExampleTests; 216 | productReference = 33B24ECD18208B7000E866E5 /* LRNotificationObserverExampleTests.xctest */; 217 | productType = "com.apple.product-type.bundle.unit-test"; 218 | }; 219 | /* End PBXNativeTarget section */ 220 | 221 | /* Begin PBXProject section */ 222 | 33B24EAA18208B7000E866E5 /* Project object */ = { 223 | isa = PBXProject; 224 | attributes = { 225 | LastUpgradeCheck = 0510; 226 | ORGANIZATIONNAME = "Luis Recuenco"; 227 | TargetAttributes = { 228 | 33B24ECC18208B7000E866E5 = { 229 | TestTargetID = 33B24EB118208B7000E866E5; 230 | }; 231 | }; 232 | }; 233 | buildConfigurationList = 33B24EAD18208B7000E866E5 /* Build configuration list for PBXProject "LRNotificationObserverExample" */; 234 | compatibilityVersion = "Xcode 3.2"; 235 | developmentRegion = English; 236 | hasScannedForEncodings = 0; 237 | knownRegions = ( 238 | en, 239 | ); 240 | mainGroup = 33B24EA918208B7000E866E5; 241 | productRefGroup = 33B24EB318208B7000E866E5 /* Products */; 242 | projectDirPath = ""; 243 | projectRoot = ""; 244 | targets = ( 245 | 33B24EB118208B7000E866E5 /* LRNotificationObserverExample */, 246 | 33B24ECC18208B7000E866E5 /* LRNotificationObserverExampleTests */, 247 | ); 248 | }; 249 | /* End PBXProject section */ 250 | 251 | /* Begin PBXResourcesBuildPhase section */ 252 | 33B24EB018208B7000E866E5 /* Resources */ = { 253 | isa = PBXResourcesBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | 33B24EC018208B7000E866E5 /* InfoPlist.strings in Resources */, 257 | 33B24EC818208B7000E866E5 /* Images.xcassets in Resources */, 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | 33B24ECB18208B7000E866E5 /* Resources */ = { 262 | isa = PBXResourcesBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | 33B24ED918208B7000E866E5 /* InfoPlist.strings in Resources */, 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | }; 269 | /* End PBXResourcesBuildPhase section */ 270 | 271 | /* Begin PBXShellScriptBuildPhase section */ 272 | 90A2024AD0244749AAD6610A /* Copy Pods Resources */ = { 273 | isa = PBXShellScriptBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | ); 277 | inputPaths = ( 278 | ); 279 | name = "Copy Pods Resources"; 280 | outputPaths = ( 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | shellPath = /bin/sh; 284 | shellScript = "\"${SRCROOT}/Pods/Pods-LRNotificationObserverExampleTests-resources.sh\"\n"; 285 | showEnvVarsInLog = 0; 286 | }; 287 | C2211F5B3A4943CC84423738 /* Check Pods Manifest.lock */ = { 288 | isa = PBXShellScriptBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | ); 292 | inputPaths = ( 293 | ); 294 | name = "Check Pods Manifest.lock"; 295 | outputPaths = ( 296 | ); 297 | runOnlyForDeploymentPostprocessing = 0; 298 | shellPath = /bin/sh; 299 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 300 | showEnvVarsInLog = 0; 301 | }; 302 | /* End PBXShellScriptBuildPhase section */ 303 | 304 | /* Begin PBXSourcesBuildPhase section */ 305 | 33B24EAE18208B7000E866E5 /* Sources */ = { 306 | isa = PBXSourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | 33B24EC618208B7000E866E5 /* AppDelegate.m in Sources */, 310 | 33BA2CBE188605A300695361 /* LRNotificationObserver+NSNotificationCenter.m in Sources */, 311 | 2CD4876018869067005DA81F /* LRNotificationObserver+Owner.m in Sources */, 312 | 33B24EC218208B7000E866E5 /* main.m in Sources */, 313 | 3333C74518208D1C0036A1C4 /* LRNotificationObserver.m in Sources */, 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | }; 317 | 33B24EC918208B7000E866E5 /* Sources */ = { 318 | isa = PBXSourcesBuildPhase; 319 | buildActionMask = 2147483647; 320 | files = ( 321 | 2CD4876118869067005DA81F /* LRNotificationObserver+Owner.m in Sources */, 322 | 33BA2CBF188605A300695361 /* LRNotificationObserver+NSNotificationCenter.m in Sources */, 323 | 33000121183AE92E009DD610 /* LRNotificationObserverTests.m in Sources */, 324 | 3333C74618208D1C0036A1C4 /* LRNotificationObserver.m in Sources */, 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | }; 328 | /* End PBXSourcesBuildPhase section */ 329 | 330 | /* Begin PBXTargetDependency section */ 331 | 33B24ED318208B7000E866E5 /* PBXTargetDependency */ = { 332 | isa = PBXTargetDependency; 333 | target = 33B24EB118208B7000E866E5 /* LRNotificationObserverExample */; 334 | targetProxy = 33B24ED218208B7000E866E5 /* PBXContainerItemProxy */; 335 | }; 336 | /* End PBXTargetDependency section */ 337 | 338 | /* Begin PBXVariantGroup section */ 339 | 33B24EBE18208B7000E866E5 /* InfoPlist.strings */ = { 340 | isa = PBXVariantGroup; 341 | children = ( 342 | 33B24EBF18208B7000E866E5 /* en */, 343 | ); 344 | name = InfoPlist.strings; 345 | sourceTree = ""; 346 | }; 347 | 33B24ED718208B7000E866E5 /* InfoPlist.strings */ = { 348 | isa = PBXVariantGroup; 349 | children = ( 350 | 33B24ED818208B7000E866E5 /* en */, 351 | ); 352 | name = InfoPlist.strings; 353 | sourceTree = ""; 354 | }; 355 | /* End PBXVariantGroup section */ 356 | 357 | /* Begin XCBuildConfiguration section */ 358 | 33B24EDC18208B7000E866E5 /* Debug */ = { 359 | isa = XCBuildConfiguration; 360 | buildSettings = { 361 | ALWAYS_SEARCH_USER_PATHS = NO; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BOOL_CONVERSION = YES; 367 | CLANG_WARN_CONSTANT_CONVERSION = YES; 368 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 369 | CLANG_WARN_EMPTY_BODY = YES; 370 | CLANG_WARN_ENUM_CONVERSION = YES; 371 | CLANG_WARN_INT_CONVERSION = YES; 372 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 373 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 374 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 375 | COPY_PHASE_STRIP = NO; 376 | GCC_C_LANGUAGE_STANDARD = gnu99; 377 | GCC_DYNAMIC_NO_PIC = NO; 378 | GCC_OPTIMIZATION_LEVEL = 0; 379 | GCC_PREPROCESSOR_DEFINITIONS = ( 380 | "DEBUG=1", 381 | "$(inherited)", 382 | ); 383 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 384 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 385 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 386 | GCC_WARN_UNDECLARED_SELECTOR = YES; 387 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 388 | GCC_WARN_UNUSED_FUNCTION = YES; 389 | GCC_WARN_UNUSED_VARIABLE = YES; 390 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 391 | ONLY_ACTIVE_ARCH = YES; 392 | SDKROOT = iphoneos; 393 | }; 394 | name = Debug; 395 | }; 396 | 33B24EDD18208B7000E866E5 /* Release */ = { 397 | isa = XCBuildConfiguration; 398 | buildSettings = { 399 | ALWAYS_SEARCH_USER_PATHS = NO; 400 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 401 | CLANG_CXX_LIBRARY = "libc++"; 402 | CLANG_ENABLE_MODULES = YES; 403 | CLANG_ENABLE_OBJC_ARC = YES; 404 | CLANG_WARN_BOOL_CONVERSION = YES; 405 | CLANG_WARN_CONSTANT_CONVERSION = YES; 406 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 407 | CLANG_WARN_EMPTY_BODY = YES; 408 | CLANG_WARN_ENUM_CONVERSION = YES; 409 | CLANG_WARN_INT_CONVERSION = YES; 410 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 411 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 412 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 413 | COPY_PHASE_STRIP = YES; 414 | ENABLE_NS_ASSERTIONS = NO; 415 | GCC_C_LANGUAGE_STANDARD = gnu99; 416 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 417 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 418 | GCC_WARN_UNDECLARED_SELECTOR = YES; 419 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 420 | GCC_WARN_UNUSED_FUNCTION = YES; 421 | GCC_WARN_UNUSED_VARIABLE = YES; 422 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 423 | SDKROOT = iphoneos; 424 | VALIDATE_PRODUCT = YES; 425 | }; 426 | name = Release; 427 | }; 428 | 33B24EDF18208B7000E866E5 /* Debug */ = { 429 | isa = XCBuildConfiguration; 430 | buildSettings = { 431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 432 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 433 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 434 | GCC_PREFIX_HEADER = "LRNotificationObserverExample/LRNotificationObserverExample-Prefix.pch"; 435 | INFOPLIST_FILE = "LRNotificationObserverExample/LRNotificationObserverExample-Info.plist"; 436 | OTHER_LDFLAGS = ""; 437 | PRODUCT_NAME = "$(TARGET_NAME)"; 438 | WRAPPER_EXTENSION = app; 439 | }; 440 | name = Debug; 441 | }; 442 | 33B24EE018208B7000E866E5 /* Release */ = { 443 | isa = XCBuildConfiguration; 444 | buildSettings = { 445 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 446 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 447 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 448 | GCC_PREFIX_HEADER = "LRNotificationObserverExample/LRNotificationObserverExample-Prefix.pch"; 449 | INFOPLIST_FILE = "LRNotificationObserverExample/LRNotificationObserverExample-Info.plist"; 450 | OTHER_LDFLAGS = ""; 451 | PRODUCT_NAME = "$(TARGET_NAME)"; 452 | WRAPPER_EXTENSION = app; 453 | }; 454 | name = Release; 455 | }; 456 | 33B24EE218208B7000E866E5 /* Debug */ = { 457 | isa = XCBuildConfiguration; 458 | baseConfigurationReference = B8EB2E55DE9045319A1D1CD3 /* Pods-LRNotificationObserverExampleTests.xcconfig */; 459 | buildSettings = { 460 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LRNotificationObserverExample.app/LRNotificationObserverExample"; 461 | FRAMEWORK_SEARCH_PATHS = ( 462 | "$(SDKROOT)/Developer/Library/Frameworks", 463 | "$(inherited)", 464 | "$(DEVELOPER_FRAMEWORKS_DIR)", 465 | ); 466 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 467 | GCC_PREFIX_HEADER = "LRNotificationObserverExample/LRNotificationObserverExample-Prefix.pch"; 468 | GCC_PREPROCESSOR_DEFINITIONS = ( 469 | "DEBUG=1", 470 | "$(inherited)", 471 | ); 472 | INFOPLIST_FILE = "LRNotificationObserverExampleTests/LRNotificationObserverExampleTests-Info.plist"; 473 | OTHER_LDFLAGS = ( 474 | "-ObjC", 475 | "-framework", 476 | XCTest, 477 | ); 478 | PRODUCT_NAME = "$(TARGET_NAME)"; 479 | TEST_HOST = "$(BUNDLE_LOADER)"; 480 | WRAPPER_EXTENSION = xctest; 481 | }; 482 | name = Debug; 483 | }; 484 | 33B24EE318208B7000E866E5 /* Release */ = { 485 | isa = XCBuildConfiguration; 486 | baseConfigurationReference = B8EB2E55DE9045319A1D1CD3 /* Pods-LRNotificationObserverExampleTests.xcconfig */; 487 | buildSettings = { 488 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/LRNotificationObserverExample.app/LRNotificationObserverExample"; 489 | FRAMEWORK_SEARCH_PATHS = ( 490 | "$(SDKROOT)/Developer/Library/Frameworks", 491 | "$(inherited)", 492 | "$(DEVELOPER_FRAMEWORKS_DIR)", 493 | ); 494 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 495 | GCC_PREFIX_HEADER = "LRNotificationObserverExample/LRNotificationObserverExample-Prefix.pch"; 496 | INFOPLIST_FILE = "LRNotificationObserverExampleTests/LRNotificationObserverExampleTests-Info.plist"; 497 | OTHER_LDFLAGS = ( 498 | "-ObjC", 499 | "-framework", 500 | XCTest, 501 | ); 502 | PRODUCT_NAME = "$(TARGET_NAME)"; 503 | TEST_HOST = "$(BUNDLE_LOADER)"; 504 | WRAPPER_EXTENSION = xctest; 505 | }; 506 | name = Release; 507 | }; 508 | /* End XCBuildConfiguration section */ 509 | 510 | /* Begin XCConfigurationList section */ 511 | 33B24EAD18208B7000E866E5 /* Build configuration list for PBXProject "LRNotificationObserverExample" */ = { 512 | isa = XCConfigurationList; 513 | buildConfigurations = ( 514 | 33B24EDC18208B7000E866E5 /* Debug */, 515 | 33B24EDD18208B7000E866E5 /* Release */, 516 | ); 517 | defaultConfigurationIsVisible = 0; 518 | defaultConfigurationName = Release; 519 | }; 520 | 33B24EDE18208B7000E866E5 /* Build configuration list for PBXNativeTarget "LRNotificationObserverExample" */ = { 521 | isa = XCConfigurationList; 522 | buildConfigurations = ( 523 | 33B24EDF18208B7000E866E5 /* Debug */, 524 | 33B24EE018208B7000E866E5 /* Release */, 525 | ); 526 | defaultConfigurationIsVisible = 0; 527 | defaultConfigurationName = Release; 528 | }; 529 | 33B24EE118208B7000E866E5 /* Build configuration list for PBXNativeTarget "LRNotificationObserverExampleTests" */ = { 530 | isa = XCConfigurationList; 531 | buildConfigurations = ( 532 | 33B24EE218208B7000E866E5 /* Debug */, 533 | 33B24EE318208B7000E866E5 /* Release */, 534 | ); 535 | defaultConfigurationIsVisible = 0; 536 | defaultConfigurationName = Release; 537 | }; 538 | /* End XCConfigurationList section */ 539 | }; 540 | rootObject = 33B24EAA18208B7000E866E5 /* Project object */; 541 | } 542 | --------------------------------------------------------------------------------