├── .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 | [](https://travis-ci.org/luisrecuenco/LRNotificationObserver)
5 | [](http://cocoadocs.org/docsets/LRNotificationObserver/)
6 | [](http://cocoadocs.org/docsets/LRNotificationObserver/)
7 | [](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 |
--------------------------------------------------------------------------------