├── .travis.yml ├── Examples ├── NotificationsTest.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ ├── NotificationsTest (OS X).xcscheme │ │ └── NotificationsTest (iOS).xcscheme └── NotificationsTest │ ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json │ ├── OS X │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── MainMenu.xib │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── NotificationsTest-Info.plist │ ├── NotificationsTest-Prefix.pch │ ├── WindowController.h │ ├── WindowController.m │ ├── WindowController.xib │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m │ └── iOS │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ └── Main.storyboard │ ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json │ ├── NotificationsTest-Info.plist │ ├── NotificationsTest-Prefix.pch │ ├── ViewController.h │ ├── ViewController.m │ ├── en.lproj │ └── InfoPlist.strings │ └── main.m ├── FXNotifications.podspec.json ├── FXNotifications.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── FXNotifications-OSX.xcscheme │ ├── FXNotifications-iOS.xcscheme │ ├── FXNotifications-tvOS.xcscheme │ └── FXNotifications-watchOS.xcscheme ├── FXNotifications ├── FXNotifications.h └── FXNotifications.m ├── Info.plist ├── LICENCE.md ├── README.md └── module.modulemap /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | os: osx 3 | osx_image: xcode7.3 4 | env: 5 | matrix: 6 | - TEST_TYPE=iOS 7 | - TEST_TYPE=CocoaPods 8 | - TEST_TYPE=Carthage 9 | install: 10 | - | 11 | if [ "$TEST_TYPE" = "iOS" ]; then 12 | gem install xcpretty -N --no-ri --no-rdoc 13 | gem update cocoapods 14 | elif [ "$TEST_TYPE" = Carthage ]; then 15 | brew install carthage || brew upgrade carthage 16 | fi 17 | script: 18 | - | 19 | if [ "$TEST_TYPE" = "iOS" ]; then 20 | set -o pipefail 21 | xcodebuild build -project FXNotifications.xcodeproj -scheme FXNotifications-iOS -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 4s" | xcpretty -c 22 | elif [ "$TEST_TYPE" = CocoaPods ]; then 23 | pod lib lint FXNotifications.podspec.json 24 | pod lib lint --use-libraries FXNotifications.podspec.json 25 | elif [ "$TEST_TYPE" = Carthage ]; then 26 | carthage build --no-skip-current 27 | fi 28 | -------------------------------------------------------------------------------- /Examples/NotificationsTest.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 010F3395183CC2780036FF0C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 010F3394183CC2780036FF0C /* Foundation.framework */; }; 11 | 010F3397183CC2780036FF0C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 010F3396183CC2780036FF0C /* CoreGraphics.framework */; }; 12 | 010F3399183CC2780036FF0C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 010F3398183CC2780036FF0C /* UIKit.framework */; }; 13 | 010F339F183CC2780036FF0C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 010F339D183CC2780036FF0C /* InfoPlist.strings */; }; 14 | 010F33A1183CC2780036FF0C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 010F33A0183CC2780036FF0C /* main.m */; }; 15 | 010F33A5183CC2780036FF0C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 010F33A4183CC2780036FF0C /* AppDelegate.m */; }; 16 | 010F33AB183CC2780036FF0C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 010F33AA183CC2780036FF0C /* ViewController.m */; }; 17 | 010F33AD183CC2780036FF0C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 010F33AC183CC2780036FF0C /* Images.xcassets */; }; 18 | 010F33D1183CC9DE0036FF0C /* FXNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 010F33D0183CC9DE0036FF0C /* FXNotifications.m */; }; 19 | 1A0283DE18D0255700DCEB95 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A0283DD18D0255700DCEB95 /* Cocoa.framework */; }; 20 | 1A0283E818D0255700DCEB95 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1A0283E618D0255700DCEB95 /* InfoPlist.strings */; }; 21 | 1A0283EA18D0255700DCEB95 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0283E918D0255700DCEB95 /* main.m */; }; 22 | 1A0283F118D0255700DCEB95 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0283F018D0255700DCEB95 /* AppDelegate.m */; }; 23 | 1A0283F418D0255700DCEB95 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1A0283F218D0255700DCEB95 /* MainMenu.xib */; }; 24 | 1A0283F618D0255700DCEB95 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A0283F518D0255700DCEB95 /* Images.xcassets */; }; 25 | 1A0283FC18D0255700DCEB95 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 010F33B3183CC2780036FF0C /* XCTest.framework */; }; 26 | 1A0283FD18D0255700DCEB95 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A0283DD18D0255700DCEB95 /* Cocoa.framework */; }; 27 | 1A02841718D02BC200DCEB95 /* WindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A02841518D02BC200DCEB95 /* WindowController.m */; }; 28 | 1A02841818D02BC200DCEB95 /* WindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1A02841618D02BC200DCEB95 /* WindowController.xib */; }; 29 | 1A02841918D0375800DCEB95 /* FXNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 010F33D0183CC9DE0036FF0C /* FXNotifications.m */; }; 30 | 1AD9155918D0210B006E1635 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1AD9155B18D0210B006E1635 /* Main.storyboard */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXContainerItemProxy section */ 34 | 1A0283FE18D0255700DCEB95 /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = 010F3389183CC2780036FF0C /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = 1A0283DB18D0255700DCEB95; 39 | remoteInfo = NotificationsTest; 40 | }; 41 | /* End PBXContainerItemProxy section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 010F3391183CC2780036FF0C /* NotificationsTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NotificationsTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 010F3394183CC2780036FF0C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 46 | 010F3396183CC2780036FF0C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 47 | 010F3398183CC2780036FF0C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 48 | 010F339C183CC2780036FF0C /* NotificationsTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "NotificationsTest-Info.plist"; sourceTree = ""; }; 49 | 010F339E183CC2780036FF0C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 50 | 010F33A0183CC2780036FF0C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 51 | 010F33A2183CC2780036FF0C /* NotificationsTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NotificationsTest-Prefix.pch"; sourceTree = ""; }; 52 | 010F33A3183CC2780036FF0C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 53 | 010F33A4183CC2780036FF0C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 54 | 010F33A9183CC2780036FF0C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 55 | 010F33AA183CC2780036FF0C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 56 | 010F33AC183CC2780036FF0C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 57 | 010F33B3183CC2780036FF0C /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 58 | 010F33CF183CC9DE0036FF0C /* FXNotifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FXNotifications.h; sourceTree = ""; }; 59 | 010F33D0183CC9DE0036FF0C /* FXNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FXNotifications.m; sourceTree = ""; }; 60 | 1A0283DC18D0255700DCEB95 /* NotificationsTest (OS X).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "NotificationsTest (OS X).app"; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 1A0283DD18D0255700DCEB95 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; 62 | 1A0283E018D0255700DCEB95 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 63 | 1A0283E118D0255700DCEB95 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 64 | 1A0283E218D0255700DCEB95 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 65 | 1A0283E518D0255700DCEB95 /* NotificationsTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "NotificationsTest-Info.plist"; sourceTree = ""; }; 66 | 1A0283E718D0255700DCEB95 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 67 | 1A0283E918D0255700DCEB95 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 68 | 1A0283EB18D0255700DCEB95 /* NotificationsTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NotificationsTest-Prefix.pch"; sourceTree = ""; }; 69 | 1A0283EF18D0255700DCEB95 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 70 | 1A0283F018D0255700DCEB95 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 71 | 1A0283F318D0255700DCEB95 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 72 | 1A0283F518D0255700DCEB95 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 73 | 1A0283FB18D0255700DCEB95 /* NotificationsTestTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NotificationsTestTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | 1A02841418D02BC200DCEB95 /* WindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowController.h; sourceTree = ""; }; 75 | 1A02841518D02BC200DCEB95 /* WindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WindowController.m; sourceTree = ""; }; 76 | 1A02841618D02BC200DCEB95 /* WindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WindowController.xib; sourceTree = ""; }; 77 | 1AD9155A18D0210B006E1635 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 78 | /* End PBXFileReference section */ 79 | 80 | /* Begin PBXFrameworksBuildPhase section */ 81 | 010F338E183CC2780036FF0C /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | 010F3397183CC2780036FF0C /* CoreGraphics.framework in Frameworks */, 86 | 010F3399183CC2780036FF0C /* UIKit.framework in Frameworks */, 87 | 010F3395183CC2780036FF0C /* Foundation.framework in Frameworks */, 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | 1A0283D918D0255700DCEB95 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | 1A0283DE18D0255700DCEB95 /* Cocoa.framework in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | 1A0283F818D0255700DCEB95 /* Frameworks */ = { 100 | isa = PBXFrameworksBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | 1A0283FD18D0255700DCEB95 /* Cocoa.framework in Frameworks */, 104 | 1A0283FC18D0255700DCEB95 /* XCTest.framework in Frameworks */, 105 | ); 106 | runOnlyForDeploymentPostprocessing = 0; 107 | }; 108 | /* End PBXFrameworksBuildPhase section */ 109 | 110 | /* Begin PBXGroup section */ 111 | 010F3388183CC2780036FF0C = { 112 | isa = PBXGroup; 113 | children = ( 114 | 010F33CE183CC9DE0036FF0C /* FXNotifications */, 115 | 010F339A183CC2780036FF0C /* NotificationsTest */, 116 | 010F3393183CC2780036FF0C /* Frameworks */, 117 | 010F3392183CC2780036FF0C /* Products */, 118 | ); 119 | sourceTree = ""; 120 | }; 121 | 010F3392183CC2780036FF0C /* Products */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 010F3391183CC2780036FF0C /* NotificationsTest.app */, 125 | 1A0283DC18D0255700DCEB95 /* NotificationsTest (OS X).app */, 126 | 1A0283FB18D0255700DCEB95 /* NotificationsTestTests.xctest */, 127 | ); 128 | name = Products; 129 | sourceTree = ""; 130 | }; 131 | 010F3393183CC2780036FF0C /* Frameworks */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 010F3394183CC2780036FF0C /* Foundation.framework */, 135 | 010F3396183CC2780036FF0C /* CoreGraphics.framework */, 136 | 010F3398183CC2780036FF0C /* UIKit.framework */, 137 | 010F33B3183CC2780036FF0C /* XCTest.framework */, 138 | 1A0283DD18D0255700DCEB95 /* Cocoa.framework */, 139 | 1A0283DF18D0255700DCEB95 /* Other Frameworks */, 140 | ); 141 | name = Frameworks; 142 | sourceTree = ""; 143 | }; 144 | 010F339A183CC2780036FF0C /* NotificationsTest */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 1AD9155618D01F79006E1635 /* iOS */, 148 | 1A02840E18D025E700DCEB95 /* OS X */, 149 | ); 150 | path = NotificationsTest; 151 | sourceTree = ""; 152 | }; 153 | 010F339B183CC2780036FF0C /* Supporting Files */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 010F339C183CC2780036FF0C /* NotificationsTest-Info.plist */, 157 | 010F339D183CC2780036FF0C /* InfoPlist.strings */, 158 | 010F33A0183CC2780036FF0C /* main.m */, 159 | 010F33A2183CC2780036FF0C /* NotificationsTest-Prefix.pch */, 160 | ); 161 | name = "Supporting Files"; 162 | sourceTree = ""; 163 | }; 164 | 010F33CE183CC9DE0036FF0C /* FXNotifications */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 010F33CF183CC9DE0036FF0C /* FXNotifications.h */, 168 | 010F33D0183CC9DE0036FF0C /* FXNotifications.m */, 169 | ); 170 | name = FXNotifications; 171 | path = ../FXNotifications; 172 | sourceTree = ""; 173 | }; 174 | 1A0283DF18D0255700DCEB95 /* Other Frameworks */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 1A0283E018D0255700DCEB95 /* AppKit.framework */, 178 | 1A0283E118D0255700DCEB95 /* CoreData.framework */, 179 | 1A0283E218D0255700DCEB95 /* Foundation.framework */, 180 | ); 181 | name = "Other Frameworks"; 182 | sourceTree = ""; 183 | }; 184 | 1A0283E418D0255700DCEB95 /* Supporting Files */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | 1A0283E518D0255700DCEB95 /* NotificationsTest-Info.plist */, 188 | 1A0283E618D0255700DCEB95 /* InfoPlist.strings */, 189 | 1A0283E918D0255700DCEB95 /* main.m */, 190 | 1A0283EB18D0255700DCEB95 /* NotificationsTest-Prefix.pch */, 191 | ); 192 | name = "Supporting Files"; 193 | sourceTree = ""; 194 | }; 195 | 1A02840E18D025E700DCEB95 /* OS X */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | 1A0283EF18D0255700DCEB95 /* AppDelegate.h */, 199 | 1A0283F018D0255700DCEB95 /* AppDelegate.m */, 200 | 1A0283F218D0255700DCEB95 /* MainMenu.xib */, 201 | 1A02841418D02BC200DCEB95 /* WindowController.h */, 202 | 1A02841518D02BC200DCEB95 /* WindowController.m */, 203 | 1A02841618D02BC200DCEB95 /* WindowController.xib */, 204 | 1A0283F518D0255700DCEB95 /* Images.xcassets */, 205 | 1A0283E418D0255700DCEB95 /* Supporting Files */, 206 | ); 207 | path = "OS X"; 208 | sourceTree = ""; 209 | }; 210 | 1AD9155618D01F79006E1635 /* iOS */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | 010F33A3183CC2780036FF0C /* AppDelegate.h */, 214 | 010F33A4183CC2780036FF0C /* AppDelegate.m */, 215 | 010F33A9183CC2780036FF0C /* ViewController.h */, 216 | 010F33AA183CC2780036FF0C /* ViewController.m */, 217 | 1AD9155B18D0210B006E1635 /* Main.storyboard */, 218 | 010F33AC183CC2780036FF0C /* Images.xcassets */, 219 | 010F339B183CC2780036FF0C /* Supporting Files */, 220 | ); 221 | path = iOS; 222 | sourceTree = ""; 223 | }; 224 | /* End PBXGroup section */ 225 | 226 | /* Begin PBXNativeTarget section */ 227 | 010F3390183CC2780036FF0C /* NotificationsTest (iOS) */ = { 228 | isa = PBXNativeTarget; 229 | buildConfigurationList = 010F33C3183CC2780036FF0C /* Build configuration list for PBXNativeTarget "NotificationsTest (iOS)" */; 230 | buildPhases = ( 231 | 010F338D183CC2780036FF0C /* Sources */, 232 | 010F338E183CC2780036FF0C /* Frameworks */, 233 | 010F338F183CC2780036FF0C /* Resources */, 234 | ); 235 | buildRules = ( 236 | ); 237 | dependencies = ( 238 | ); 239 | name = "NotificationsTest (iOS)"; 240 | productName = NotificationsTesr; 241 | productReference = 010F3391183CC2780036FF0C /* NotificationsTest.app */; 242 | productType = "com.apple.product-type.application"; 243 | }; 244 | 1A0283DB18D0255700DCEB95 /* NotificationsTest (OS X) */ = { 245 | isa = PBXNativeTarget; 246 | buildConfigurationList = 1A02840818D0255800DCEB95 /* Build configuration list for PBXNativeTarget "NotificationsTest (OS X)" */; 247 | buildPhases = ( 248 | 1A0283D818D0255700DCEB95 /* Sources */, 249 | 1A0283D918D0255700DCEB95 /* Frameworks */, 250 | 1A0283DA18D0255700DCEB95 /* Resources */, 251 | ); 252 | buildRules = ( 253 | ); 254 | dependencies = ( 255 | ); 256 | name = "NotificationsTest (OS X)"; 257 | productName = NotificationsTest; 258 | productReference = 1A0283DC18D0255700DCEB95 /* NotificationsTest (OS X).app */; 259 | productType = "com.apple.product-type.application"; 260 | }; 261 | 1A0283FA18D0255700DCEB95 /* NotificationsTestTests */ = { 262 | isa = PBXNativeTarget; 263 | buildConfigurationList = 1A02840B18D0255800DCEB95 /* Build configuration list for PBXNativeTarget "NotificationsTestTests" */; 264 | buildPhases = ( 265 | 1A0283F718D0255700DCEB95 /* Sources */, 266 | 1A0283F818D0255700DCEB95 /* Frameworks */, 267 | 1A0283F918D0255700DCEB95 /* Resources */, 268 | ); 269 | buildRules = ( 270 | ); 271 | dependencies = ( 272 | 1A0283FF18D0255700DCEB95 /* PBXTargetDependency */, 273 | ); 274 | name = NotificationsTestTests; 275 | productName = NotificationsTestTests; 276 | productReference = 1A0283FB18D0255700DCEB95 /* NotificationsTestTests.xctest */; 277 | productType = "com.apple.product-type.bundle.unit-test"; 278 | }; 279 | /* End PBXNativeTarget section */ 280 | 281 | /* Begin PBXProject section */ 282 | 010F3389183CC2780036FF0C /* Project object */ = { 283 | isa = PBXProject; 284 | attributes = { 285 | LastUpgradeCheck = 0730; 286 | ORGANIZATIONNAME = "Charcoal Design"; 287 | TargetAttributes = { 288 | 1A0283FA18D0255700DCEB95 = { 289 | TestTargetID = 010F3390183CC2780036FF0C; 290 | }; 291 | }; 292 | }; 293 | buildConfigurationList = 010F338C183CC2780036FF0C /* Build configuration list for PBXProject "NotificationsTest" */; 294 | compatibilityVersion = "Xcode 3.2"; 295 | developmentRegion = English; 296 | hasScannedForEncodings = 0; 297 | knownRegions = ( 298 | en, 299 | Base, 300 | ); 301 | mainGroup = 010F3388183CC2780036FF0C; 302 | productRefGroup = 010F3392183CC2780036FF0C /* Products */; 303 | projectDirPath = ""; 304 | projectRoot = ""; 305 | targets = ( 306 | 010F3390183CC2780036FF0C /* NotificationsTest (iOS) */, 307 | 1A0283DB18D0255700DCEB95 /* NotificationsTest (OS X) */, 308 | 1A0283FA18D0255700DCEB95 /* NotificationsTestTests */, 309 | ); 310 | }; 311 | /* End PBXProject section */ 312 | 313 | /* Begin PBXResourcesBuildPhase section */ 314 | 010F338F183CC2780036FF0C /* Resources */ = { 315 | isa = PBXResourcesBuildPhase; 316 | buildActionMask = 2147483647; 317 | files = ( 318 | 1AD9155918D0210B006E1635 /* Main.storyboard in Resources */, 319 | 010F33AD183CC2780036FF0C /* Images.xcassets in Resources */, 320 | 010F339F183CC2780036FF0C /* InfoPlist.strings in Resources */, 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | }; 324 | 1A0283DA18D0255700DCEB95 /* Resources */ = { 325 | isa = PBXResourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | 1A0283E818D0255700DCEB95 /* InfoPlist.strings in Resources */, 329 | 1A0283F618D0255700DCEB95 /* Images.xcassets in Resources */, 330 | 1A02841818D02BC200DCEB95 /* WindowController.xib in Resources */, 331 | 1A0283F418D0255700DCEB95 /* MainMenu.xib in Resources */, 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | }; 335 | 1A0283F918D0255700DCEB95 /* Resources */ = { 336 | isa = PBXResourcesBuildPhase; 337 | buildActionMask = 2147483647; 338 | files = ( 339 | ); 340 | runOnlyForDeploymentPostprocessing = 0; 341 | }; 342 | /* End PBXResourcesBuildPhase section */ 343 | 344 | /* Begin PBXSourcesBuildPhase section */ 345 | 010F338D183CC2780036FF0C /* Sources */ = { 346 | isa = PBXSourcesBuildPhase; 347 | buildActionMask = 2147483647; 348 | files = ( 349 | 010F33AB183CC2780036FF0C /* ViewController.m in Sources */, 350 | 010F33A5183CC2780036FF0C /* AppDelegate.m in Sources */, 351 | 010F33A1183CC2780036FF0C /* main.m in Sources */, 352 | 010F33D1183CC9DE0036FF0C /* FXNotifications.m in Sources */, 353 | ); 354 | runOnlyForDeploymentPostprocessing = 0; 355 | }; 356 | 1A0283D818D0255700DCEB95 /* Sources */ = { 357 | isa = PBXSourcesBuildPhase; 358 | buildActionMask = 2147483647; 359 | files = ( 360 | 1A02841918D0375800DCEB95 /* FXNotifications.m in Sources */, 361 | 1A0283F118D0255700DCEB95 /* AppDelegate.m in Sources */, 362 | 1A02841718D02BC200DCEB95 /* WindowController.m in Sources */, 363 | 1A0283EA18D0255700DCEB95 /* main.m in Sources */, 364 | ); 365 | runOnlyForDeploymentPostprocessing = 0; 366 | }; 367 | 1A0283F718D0255700DCEB95 /* Sources */ = { 368 | isa = PBXSourcesBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | ); 372 | runOnlyForDeploymentPostprocessing = 0; 373 | }; 374 | /* End PBXSourcesBuildPhase section */ 375 | 376 | /* Begin PBXTargetDependency section */ 377 | 1A0283FF18D0255700DCEB95 /* PBXTargetDependency */ = { 378 | isa = PBXTargetDependency; 379 | target = 1A0283DB18D0255700DCEB95 /* NotificationsTest (OS X) */; 380 | targetProxy = 1A0283FE18D0255700DCEB95 /* PBXContainerItemProxy */; 381 | }; 382 | /* End PBXTargetDependency section */ 383 | 384 | /* Begin PBXVariantGroup section */ 385 | 010F339D183CC2780036FF0C /* InfoPlist.strings */ = { 386 | isa = PBXVariantGroup; 387 | children = ( 388 | 010F339E183CC2780036FF0C /* en */, 389 | ); 390 | name = InfoPlist.strings; 391 | sourceTree = ""; 392 | }; 393 | 1A0283E618D0255700DCEB95 /* InfoPlist.strings */ = { 394 | isa = PBXVariantGroup; 395 | children = ( 396 | 1A0283E718D0255700DCEB95 /* en */, 397 | ); 398 | name = InfoPlist.strings; 399 | sourceTree = ""; 400 | }; 401 | 1A0283F218D0255700DCEB95 /* MainMenu.xib */ = { 402 | isa = PBXVariantGroup; 403 | children = ( 404 | 1A0283F318D0255700DCEB95 /* Base */, 405 | ); 406 | name = MainMenu.xib; 407 | sourceTree = ""; 408 | }; 409 | 1AD9155B18D0210B006E1635 /* Main.storyboard */ = { 410 | isa = PBXVariantGroup; 411 | children = ( 412 | 1AD9155A18D0210B006E1635 /* Base */, 413 | ); 414 | name = Main.storyboard; 415 | sourceTree = ""; 416 | }; 417 | /* End PBXVariantGroup section */ 418 | 419 | /* Begin XCBuildConfiguration section */ 420 | 010F33C1183CC2780036FF0C /* Debug */ = { 421 | isa = XCBuildConfiguration; 422 | buildSettings = { 423 | ALWAYS_SEARCH_USER_PATHS = NO; 424 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 425 | CLANG_CXX_LIBRARY = "libc++"; 426 | CLANG_ENABLE_MODULES = NO; 427 | CLANG_ENABLE_OBJC_ARC = YES; 428 | CLANG_WARN_BOOL_CONVERSION = YES; 429 | CLANG_WARN_CONSTANT_CONVERSION = YES; 430 | CLANG_WARN_CXX0X_EXTENSIONS = YES; 431 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 432 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 433 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 434 | CLANG_WARN_EMPTY_BODY = YES; 435 | CLANG_WARN_ENUM_CONVERSION = YES; 436 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; 437 | CLANG_WARN_INT_CONVERSION = YES; 438 | CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES; 439 | CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; 440 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 441 | CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; 442 | CLANG_WARN_OBJC_RECEIVER_WEAK = YES; 443 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; 444 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 445 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; 446 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 447 | CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; 448 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 449 | COPY_PHASE_STRIP = NO; 450 | ENABLE_TESTABILITY = YES; 451 | GCC_C_LANGUAGE_STANDARD = gnu99; 452 | GCC_DYNAMIC_NO_PIC = NO; 453 | GCC_OPTIMIZATION_LEVEL = 0; 454 | GCC_PREPROCESSOR_DEFINITIONS = ( 455 | "DEBUG=1", 456 | "$(inherited)", 457 | ); 458 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 459 | GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; 460 | GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; 461 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 462 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; 463 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 464 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 465 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 466 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; 467 | GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; 468 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 469 | GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; 470 | GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; 471 | GCC_WARN_PEDANTIC = YES; 472 | GCC_WARN_SHADOW = YES; 473 | GCC_WARN_SIGN_COMPARE = YES; 474 | GCC_WARN_STRICT_SELECTOR_MATCH = YES; 475 | GCC_WARN_UNDECLARED_SELECTOR = YES; 476 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 477 | GCC_WARN_UNKNOWN_PRAGMAS = YES; 478 | GCC_WARN_UNUSED_FUNCTION = YES; 479 | GCC_WARN_UNUSED_LABEL = YES; 480 | GCC_WARN_UNUSED_PARAMETER = YES; 481 | GCC_WARN_UNUSED_VARIABLE = YES; 482 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 483 | MACOSX_DEPLOYMENT_TARGET = 10.8; 484 | ONLY_ACTIVE_ARCH = YES; 485 | SDKROOT = iphoneos; 486 | WARNING_CFLAGS = ( 487 | "-Weverything", 488 | "-Wno-objc-missing-property-synthesis", 489 | ); 490 | }; 491 | name = Debug; 492 | }; 493 | 010F33C2183CC2780036FF0C /* Release */ = { 494 | isa = XCBuildConfiguration; 495 | buildSettings = { 496 | ALWAYS_SEARCH_USER_PATHS = NO; 497 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 498 | CLANG_CXX_LIBRARY = "libc++"; 499 | CLANG_ENABLE_MODULES = NO; 500 | CLANG_ENABLE_OBJC_ARC = YES; 501 | CLANG_WARN_BOOL_CONVERSION = YES; 502 | CLANG_WARN_CONSTANT_CONVERSION = YES; 503 | CLANG_WARN_CXX0X_EXTENSIONS = YES; 504 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 505 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 506 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 507 | CLANG_WARN_EMPTY_BODY = YES; 508 | CLANG_WARN_ENUM_CONVERSION = YES; 509 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; 510 | CLANG_WARN_INT_CONVERSION = YES; 511 | CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES; 512 | CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; 513 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 514 | CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES; 515 | CLANG_WARN_OBJC_RECEIVER_WEAK = YES; 516 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES; 517 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 518 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; 519 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 520 | CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES; 521 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 522 | COPY_PHASE_STRIP = YES; 523 | ENABLE_NS_ASSERTIONS = NO; 524 | GCC_C_LANGUAGE_STANDARD = gnu99; 525 | GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; 526 | GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; 527 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 528 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; 529 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 530 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 531 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 532 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; 533 | GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; 534 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 535 | GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; 536 | GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; 537 | GCC_WARN_PEDANTIC = YES; 538 | GCC_WARN_SHADOW = YES; 539 | GCC_WARN_SIGN_COMPARE = YES; 540 | GCC_WARN_STRICT_SELECTOR_MATCH = YES; 541 | GCC_WARN_UNDECLARED_SELECTOR = YES; 542 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 543 | GCC_WARN_UNKNOWN_PRAGMAS = YES; 544 | GCC_WARN_UNUSED_FUNCTION = YES; 545 | GCC_WARN_UNUSED_LABEL = YES; 546 | GCC_WARN_UNUSED_PARAMETER = YES; 547 | GCC_WARN_UNUSED_VARIABLE = YES; 548 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 549 | MACOSX_DEPLOYMENT_TARGET = 10.8; 550 | SDKROOT = iphoneos; 551 | VALIDATE_PRODUCT = YES; 552 | WARNING_CFLAGS = ( 553 | "-Weverything", 554 | "-Wno-objc-missing-property-synthesis", 555 | ); 556 | }; 557 | name = Release; 558 | }; 559 | 010F33C4183CC2780036FF0C /* Debug */ = { 560 | isa = XCBuildConfiguration; 561 | buildSettings = { 562 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 563 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 564 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 565 | GCC_PREFIX_HEADER = "NotificationsTest/iOS/NotificationsTest-Prefix.pch"; 566 | INFOPLIST_FILE = "NotificationsTest/iOS/NotificationsTest-Info.plist"; 567 | PRODUCT_BUNDLE_IDENTIFIER = "com.charcoaldesign.${PRODUCT_NAME:rfc1034identifier}"; 568 | PRODUCT_NAME = NotificationsTest; 569 | WRAPPER_EXTENSION = app; 570 | }; 571 | name = Debug; 572 | }; 573 | 010F33C5183CC2780036FF0C /* Release */ = { 574 | isa = XCBuildConfiguration; 575 | buildSettings = { 576 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 577 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 578 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 579 | GCC_PREFIX_HEADER = "NotificationsTest/iOS/NotificationsTest-Prefix.pch"; 580 | INFOPLIST_FILE = "NotificationsTest/iOS/NotificationsTest-Info.plist"; 581 | PRODUCT_BUNDLE_IDENTIFIER = "com.charcoaldesign.${PRODUCT_NAME:rfc1034identifier}"; 582 | PRODUCT_NAME = NotificationsTest; 583 | WRAPPER_EXTENSION = app; 584 | }; 585 | name = Release; 586 | }; 587 | 1A02840918D0255800DCEB95 /* Debug */ = { 588 | isa = XCBuildConfiguration; 589 | buildSettings = { 590 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 591 | COMBINE_HIDPI_IMAGES = YES; 592 | FRAMEWORK_SEARCH_PATHS = ( 593 | "$(inherited)", 594 | "$(DEVELOPER_FRAMEWORKS_DIR)", 595 | ); 596 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 597 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 598 | GCC_PREFIX_HEADER = "NotificationsTest/OS X/NotificationsTest-Prefix.pch"; 599 | GCC_PREPROCESSOR_DEFINITIONS = ( 600 | "DEBUG=1", 601 | "$(inherited)", 602 | ); 603 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 604 | INFOPLIST_FILE = "NotificationsTest/OS X/NotificationsTest-Info.plist"; 605 | MACOSX_DEPLOYMENT_TARGET = 10.8; 606 | PRODUCT_BUNDLE_IDENTIFIER = "com.caffeineandcocoa.${PRODUCT_NAME:rfc1034identifier}"; 607 | PRODUCT_NAME = "$(TARGET_NAME)"; 608 | SDKROOT = macosx; 609 | WRAPPER_EXTENSION = app; 610 | }; 611 | name = Debug; 612 | }; 613 | 1A02840A18D0255800DCEB95 /* Release */ = { 614 | isa = XCBuildConfiguration; 615 | buildSettings = { 616 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 617 | COMBINE_HIDPI_IMAGES = YES; 618 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 619 | FRAMEWORK_SEARCH_PATHS = ( 620 | "$(inherited)", 621 | "$(DEVELOPER_FRAMEWORKS_DIR)", 622 | ); 623 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 624 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 625 | GCC_PREFIX_HEADER = "NotificationsTest/OS X/NotificationsTest-Prefix.pch"; 626 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 627 | INFOPLIST_FILE = "NotificationsTest/OS X/NotificationsTest-Info.plist"; 628 | MACOSX_DEPLOYMENT_TARGET = 10.8; 629 | PRODUCT_BUNDLE_IDENTIFIER = "com.caffeineandcocoa.${PRODUCT_NAME:rfc1034identifier}"; 630 | PRODUCT_NAME = "$(TARGET_NAME)"; 631 | SDKROOT = macosx; 632 | WRAPPER_EXTENSION = app; 633 | }; 634 | name = Release; 635 | }; 636 | 1A02840C18D0255800DCEB95 /* Debug */ = { 637 | isa = XCBuildConfiguration; 638 | buildSettings = { 639 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/NotificationsTest.app/NotificationsTest"; 640 | COMBINE_HIDPI_IMAGES = YES; 641 | FRAMEWORK_SEARCH_PATHS = ( 642 | "$(DEVELOPER_FRAMEWORKS_DIR)", 643 | "$(inherited)", 644 | ); 645 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 646 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 647 | GCC_PREFIX_HEADER = "NotificationsTest/NotificationsTest-Prefix.pch"; 648 | GCC_PREPROCESSOR_DEFINITIONS = ( 649 | "DEBUG=1", 650 | "$(inherited)", 651 | ); 652 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 653 | INFOPLIST_FILE = "NotificationsTestTests/NotificationsTestTests-Info.plist"; 654 | MACOSX_DEPLOYMENT_TARGET = 10.9; 655 | PRODUCT_NAME = "$(TARGET_NAME)"; 656 | SDKROOT = macosx; 657 | TEST_HOST = "$(BUNDLE_LOADER)"; 658 | WRAPPER_EXTENSION = xctest; 659 | }; 660 | name = Debug; 661 | }; 662 | 1A02840D18D0255800DCEB95 /* Release */ = { 663 | isa = XCBuildConfiguration; 664 | buildSettings = { 665 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/NotificationsTest.app/NotificationsTest"; 666 | COMBINE_HIDPI_IMAGES = YES; 667 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 668 | FRAMEWORK_SEARCH_PATHS = ( 669 | "$(DEVELOPER_FRAMEWORKS_DIR)", 670 | "$(inherited)", 671 | ); 672 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 673 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 674 | GCC_PREFIX_HEADER = "NotificationsTest/NotificationsTest-Prefix.pch"; 675 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 676 | INFOPLIST_FILE = "NotificationsTestTests/NotificationsTestTests-Info.plist"; 677 | MACOSX_DEPLOYMENT_TARGET = 10.9; 678 | PRODUCT_NAME = "$(TARGET_NAME)"; 679 | SDKROOT = macosx; 680 | TEST_HOST = "$(BUNDLE_LOADER)"; 681 | WRAPPER_EXTENSION = xctest; 682 | }; 683 | name = Release; 684 | }; 685 | /* End XCBuildConfiguration section */ 686 | 687 | /* Begin XCConfigurationList section */ 688 | 010F338C183CC2780036FF0C /* Build configuration list for PBXProject "NotificationsTest" */ = { 689 | isa = XCConfigurationList; 690 | buildConfigurations = ( 691 | 010F33C1183CC2780036FF0C /* Debug */, 692 | 010F33C2183CC2780036FF0C /* Release */, 693 | ); 694 | defaultConfigurationIsVisible = 0; 695 | defaultConfigurationName = Release; 696 | }; 697 | 010F33C3183CC2780036FF0C /* Build configuration list for PBXNativeTarget "NotificationsTest (iOS)" */ = { 698 | isa = XCConfigurationList; 699 | buildConfigurations = ( 700 | 010F33C4183CC2780036FF0C /* Debug */, 701 | 010F33C5183CC2780036FF0C /* Release */, 702 | ); 703 | defaultConfigurationIsVisible = 0; 704 | defaultConfigurationName = Release; 705 | }; 706 | 1A02840818D0255800DCEB95 /* Build configuration list for PBXNativeTarget "NotificationsTest (OS X)" */ = { 707 | isa = XCConfigurationList; 708 | buildConfigurations = ( 709 | 1A02840918D0255800DCEB95 /* Debug */, 710 | 1A02840A18D0255800DCEB95 /* Release */, 711 | ); 712 | defaultConfigurationIsVisible = 0; 713 | defaultConfigurationName = Release; 714 | }; 715 | 1A02840B18D0255800DCEB95 /* Build configuration list for PBXNativeTarget "NotificationsTestTests" */ = { 716 | isa = XCConfigurationList; 717 | buildConfigurations = ( 718 | 1A02840C18D0255800DCEB95 /* Debug */, 719 | 1A02840D18D0255800DCEB95 /* Release */, 720 | ); 721 | defaultConfigurationIsVisible = 0; 722 | defaultConfigurationName = Release; 723 | }; 724 | /* End XCConfigurationList section */ 725 | }; 726 | rootObject = 010F3389183CC2780036FF0C /* Project object */; 727 | } 728 | -------------------------------------------------------------------------------- /Examples/NotificationsTest.xcodeproj/xcshareddata/xcschemes/NotificationsTest (OS X).xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Examples/NotificationsTest.xcodeproj/xcshareddata/xcschemes/NotificationsTest (iOS).xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/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 | } -------------------------------------------------------------------------------- /Examples/NotificationsTest/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 | } -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // NotificationsTest 4 | // 5 | // Created by James Clarke on 3/11/14. 6 | // Copyright (c) 2014 Caffeine and Cocoa. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | @property (nonatomic, strong) IBOutlet NSWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // NotificationsTest 4 | // 5 | // Created by James Clarke on 3/11/14. 6 | // Copyright (c) 2014 Caffeine and Cocoa. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | #import "WindowController.h" 12 | 13 | 14 | @interface AppDelegate () 15 | 16 | @property (nonatomic, strong) WindowController *windowController; 17 | 18 | @end 19 | 20 | @implementation AppDelegate 21 | 22 | - (IBAction)showSheet:(__unused id)sender 23 | { 24 | WindowController *windowController = [[WindowController alloc] initWithWindowNibName:@"WindowController"]; 25 | 26 | [NSApp beginSheet:(NSWindow *__nonnull)windowController.window 27 | modalForWindow:self.window 28 | modalDelegate:self 29 | didEndSelector:@selector(didEndSheet:returnCode:contextInfo:) 30 | contextInfo:nil]; 31 | 32 | self.windowController = windowController; 33 | } 34 | 35 | - (void)didEndSheet:(NSWindow *)sheet returnCode:(__unused NSInteger)returnCode contextInfo:(__unused void *)contextInfo 36 | { 37 | self.windowController = nil; 38 | [sheet orderOut:nil]; 39 | } 40 | 41 | - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(__unused NSApplication *)sender 42 | { 43 | return YES; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | Default 539 | 540 | 541 | 542 | 543 | 544 | 545 | Left to Right 546 | 547 | 548 | 549 | 550 | 551 | 552 | Right to Left 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | Default 564 | 565 | 566 | 567 | 568 | 569 | 570 | Left to Right 571 | 572 | 573 | 574 | 575 | 576 | 577 | Right to Left 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | Press the button below to show the sheet. The purpose of this is to create a transient controller to be the observer so that when it is released we can check that the observer cleanup is working. 684 | 685 | 686 | 687 | 688 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/NotificationsTest-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2014 Caffeine and Cocoa. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/NotificationsTest-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 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/WindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WindowController.h 3 | // NotificationsTest 4 | // 5 | // Created by James Clarke on 3/11/14. 6 | // Copyright (c) 2014 Caffeine and Cocoa. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WindowController : NSWindowController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/WindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // WindowController.m 3 | // NotificationsTest 4 | // 5 | // Created by James Clarke on 3/11/14. 6 | // Copyright (c) 2014 Caffeine and Cocoa. All rights reserved. 7 | // 8 | 9 | #import "WindowController.h" 10 | #import "FXNotifications.h" 11 | 12 | 13 | static NSString *const IncrementCountNotification = @"IncrementCountNotification"; 14 | 15 | 16 | @interface WindowController () 17 | 18 | @property (nonatomic, assign) NSInteger count; 19 | @property (nonatomic, weak) IBOutlet NSTextField *label; 20 | 21 | @end 22 | 23 | @implementation WindowController 24 | 25 | - (void)windowDidLoad 26 | { 27 | [super windowDidLoad]; 28 | [self addObserver:nil]; 29 | } 30 | 31 | - (IBAction)closeSheet:(__unused id)sender 32 | { 33 | [NSApp endSheet:(NSWindow *__nonnull)self.window]; 34 | } 35 | 36 | - (IBAction)increment:(__unused id)sender 37 | { 38 | [[NSNotificationCenter defaultCenter] postNotificationName:IncrementCountNotification object:self.label]; 39 | } 40 | 41 | - (IBAction)addObserver:(__unused id)sender 42 | { 43 | //using the built-in method (in a naive way), we would leak like hell 44 | // [[NSNotificationCenter defaultCenter] addObserverForName:IncrementCountNotification 45 | // object:nil 46 | // queue:[NSOperationQueue mainQueue] 47 | // usingBlock:^(NSNotification *note) { 48 | // 49 | // NSTextField *label = note.object; 50 | // label.text = [NSString stringWithFormat:@"Presses: %@", @(++self.count)]; 51 | // }]; 52 | 53 | //using the FXNotifications method, this approach doesn't leak and just works as expected 54 | [[NSNotificationCenter defaultCenter] addObserver:self 55 | forName:IncrementCountNotification 56 | object:self.label 57 | queue:[NSOperationQueue mainQueue] 58 | usingBlock:^(NSNotification *note, WindowController *observer) { 59 | 60 | NSTextField *label = note.object; 61 | label.stringValue = [NSString stringWithFormat:@"Presses: %@", @(++observer.count)]; 62 | }]; 63 | } 64 | 65 | - (IBAction)removeObserver:(__unused id)sender 66 | { 67 | [[NSNotificationCenter defaultCenter] removeObserver:self name:IncrementCountNotification object:self.label]; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/WindowController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 37 | 48 | 59 | 60 | 61 | 62 | 63 | 64 | The increment button is connected to the label via a notification and observer. There are many opportunities here for retain cycles, but if you use the leaks tool you'll see that there are none. 65 | 66 | 67 | 68 | 69 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/OS X/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // NotificationsTest 4 | // 5 | // Created by James Clarke on 3/11/14. 6 | // Copyright (c) 2014 Caffeine and Cocoa. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) 12 | { 13 | return NSApplicationMain(argc, argv); 14 | } 15 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // NotificationsTest 4 | // 5 | // Created by Nick Lockwood on 20/11/2013. 6 | // Copyright (c) 2013 Charcoal Design. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // NotificationsTest 4 | // 5 | // Created by Nick Lockwood on 20/11/2013. 6 | // Copyright (c) 2013 Charcoal Design. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(__unused UIApplication *)application didFinishLaunchingWithOptions:(__unused NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 24 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 63 | 74 | 85 | 91 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/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 | } -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/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 | } -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/NotificationsTest-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/NotificationsTest-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_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // NotificationsTest 4 | // 5 | // Created by Nick Lockwood on 20/11/2013. 6 | // Copyright (c) 2013 Charcoal Design. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // NotificationsTest 4 | // 5 | // Created by Nick Lockwood on 20/11/2013. 6 | // Copyright (c) 2013 Charcoal Design. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "FXNotifications.h" 11 | 12 | 13 | static NSString *const IncrementCountNotification = @"IncrementCountNotification"; 14 | 15 | 16 | @interface ViewController () 17 | 18 | @property (nonatomic, strong) IBOutlet UILabel *label; 19 | @property (nonatomic, assign) NSInteger count; 20 | 21 | @end 22 | 23 | 24 | @implementation ViewController 25 | 26 | - (void)viewDidLoad 27 | { 28 | [super viewDidLoad]; 29 | [self addObserver]; 30 | } 31 | 32 | - (IBAction)increment 33 | { 34 | [[NSNotificationCenter defaultCenter] postNotificationName:IncrementCountNotification object:self.label]; 35 | } 36 | 37 | - (IBAction)addObserver 38 | { 39 | //using the built-in method (in a naive way), we would leak like hell 40 | // [[NSNotificationCenter defaultCenter] addObserverForName:IncrementCountNotification 41 | // object:nil 42 | // queue:[NSOperationQueue mainQueue] 43 | // usingBlock:^(NSNotification *note) { 44 | // 45 | // UILabel *label = note.object; 46 | // label.text = [NSString stringWithFormat:@"Presses: %@", @(++self.count)]; 47 | // }]; 48 | 49 | //using the FXNotifications method, this approach doesn't leak and just works as expected 50 | [[NSNotificationCenter defaultCenter] addObserver:self 51 | forName:IncrementCountNotification 52 | object:self.label 53 | queue:[NSOperationQueue mainQueue] 54 | usingBlock:^(NSNotification *note, ViewController *observer) { 55 | 56 | UILabel *label = note.object; 57 | label.text = [NSString stringWithFormat:@"Presses: %@", @(++observer.count)]; 58 | }]; 59 | } 60 | 61 | - (IBAction)removeObserver 62 | { 63 | [[NSNotificationCenter defaultCenter] removeObserver:self name:IncrementCountNotification object:self.label]; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Examples/NotificationsTest/iOS/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // NotificationsTest 4 | // 5 | // Created by Nick Lockwood on 20/11/2013. 6 | // Copyright (c) 2013 Charcoal Design. 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 | -------------------------------------------------------------------------------- /FXNotifications.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FXNotifications", 3 | "version": "1.1.1", 4 | "license": "zlib", 5 | "summary": "An alternative API for NSNotificationCenter that doesn't suck.", 6 | "authors": { 7 | "Nick Lockwood": "http://charcoaldesign.co.uk/" 8 | }, 9 | "source": { 10 | "git": "https://github.com/nicklockwood/FXNotifications.git", 11 | "tag": "1.1.1" 12 | }, 13 | "homepage": "http://github.com/nicklockwood/FXNotifications", 14 | "source_files": "FXNotifications", 15 | "requires_arc": true, 16 | "platforms": { 17 | "ios": "5.0", 18 | "osx": "10.7", 19 | "tvos": "9.0", 20 | "watchos": "2.0" 21 | } 22 | } -------------------------------------------------------------------------------- /FXNotifications.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4628F1521CD200B500EF0E20 /* FXNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 4628F1511CD200B500EF0E20 /* FXNotifications.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 4628F15A1CD2011100EF0E20 /* FXNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 4628F1591CD2011100EF0E20 /* FXNotifications.m */; }; 12 | 4628F1691CD2044900EF0E20 /* FXNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 4628F1511CD200B500EF0E20 /* FXNotifications.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 4628F16A1CD2044D00EF0E20 /* FXNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 4628F1591CD2011100EF0E20 /* FXNotifications.m */; }; 14 | 4628F1861CD20C2100EF0E20 /* FXNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 4628F1511CD200B500EF0E20 /* FXNotifications.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 4628F1871CD20C2200EF0E20 /* FXNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 4628F1511CD200B500EF0E20 /* FXNotifications.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | 4628F1881CD20C2800EF0E20 /* FXNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 4628F1591CD2011100EF0E20 /* FXNotifications.m */; }; 17 | 4628F1891CD20C2800EF0E20 /* FXNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 4628F1591CD2011100EF0E20 /* FXNotifications.m */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 4628F14E1CD200B500EF0E20 /* FXNotifications.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FXNotifications.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 4628F1511CD200B500EF0E20 /* FXNotifications.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FXNotifications.h; sourceTree = ""; }; 23 | 4628F1531CD200B500EF0E20 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../Info.plist; sourceTree = ""; }; 24 | 4628F1591CD2011100EF0E20 /* FXNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FXNotifications.m; sourceTree = ""; }; 25 | 4628F1601CD201CF00EF0E20 /* FXNotifications.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FXNotifications.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | 4628F1711CD2050C00EF0E20 /* FXNotifications.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FXNotifications.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 4628F17E1CD205CC00EF0E20 /* FXNotifications.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FXNotifications.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | /* End PBXFileReference section */ 29 | 30 | /* Begin PBXFrameworksBuildPhase section */ 31 | 4628F14A1CD200B500EF0E20 /* Frameworks */ = { 32 | isa = PBXFrameworksBuildPhase; 33 | buildActionMask = 2147483647; 34 | files = ( 35 | ); 36 | runOnlyForDeploymentPostprocessing = 0; 37 | }; 38 | 4628F15C1CD201CF00EF0E20 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | 4628F16D1CD2050C00EF0E20 /* Frameworks */ = { 46 | isa = PBXFrameworksBuildPhase; 47 | buildActionMask = 2147483647; 48 | files = ( 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | 4628F17A1CD205CC00EF0E20 /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | /* End PBXFrameworksBuildPhase section */ 60 | 61 | /* Begin PBXGroup section */ 62 | 4628F1441CD200B500EF0E20 = { 63 | isa = PBXGroup; 64 | children = ( 65 | 4628F1501CD200B500EF0E20 /* FXNotifications */, 66 | 4628F14F1CD200B500EF0E20 /* Products */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | 4628F14F1CD200B500EF0E20 /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 4628F14E1CD200B500EF0E20 /* FXNotifications.framework */, 74 | 4628F1601CD201CF00EF0E20 /* FXNotifications.framework */, 75 | 4628F1711CD2050C00EF0E20 /* FXNotifications.framework */, 76 | 4628F17E1CD205CC00EF0E20 /* FXNotifications.framework */, 77 | ); 78 | name = Products; 79 | sourceTree = ""; 80 | }; 81 | 4628F1501CD200B500EF0E20 /* FXNotifications */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 4628F1511CD200B500EF0E20 /* FXNotifications.h */, 85 | 4628F1591CD2011100EF0E20 /* FXNotifications.m */, 86 | 4628F1531CD200B500EF0E20 /* Info.plist */, 87 | ); 88 | path = FXNotifications; 89 | sourceTree = ""; 90 | }; 91 | /* End PBXGroup section */ 92 | 93 | /* Begin PBXHeadersBuildPhase section */ 94 | 4628F14B1CD200B500EF0E20 /* Headers */ = { 95 | isa = PBXHeadersBuildPhase; 96 | buildActionMask = 2147483647; 97 | files = ( 98 | 4628F1521CD200B500EF0E20 /* FXNotifications.h in Headers */, 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | 4628F15D1CD201CF00EF0E20 /* Headers */ = { 103 | isa = PBXHeadersBuildPhase; 104 | buildActionMask = 2147483647; 105 | files = ( 106 | 4628F1691CD2044900EF0E20 /* FXNotifications.h in Headers */, 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | 4628F16E1CD2050C00EF0E20 /* Headers */ = { 111 | isa = PBXHeadersBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | 4628F1861CD20C2100EF0E20 /* FXNotifications.h in Headers */, 115 | ); 116 | runOnlyForDeploymentPostprocessing = 0; 117 | }; 118 | 4628F17B1CD205CC00EF0E20 /* Headers */ = { 119 | isa = PBXHeadersBuildPhase; 120 | buildActionMask = 2147483647; 121 | files = ( 122 | 4628F1871CD20C2200EF0E20 /* FXNotifications.h in Headers */, 123 | ); 124 | runOnlyForDeploymentPostprocessing = 0; 125 | }; 126 | /* End PBXHeadersBuildPhase section */ 127 | 128 | /* Begin PBXNativeTarget section */ 129 | 4628F14D1CD200B500EF0E20 /* FXNotifications-iOS */ = { 130 | isa = PBXNativeTarget; 131 | buildConfigurationList = 4628F1561CD200B500EF0E20 /* Build configuration list for PBXNativeTarget "FXNotifications-iOS" */; 132 | buildPhases = ( 133 | 4628F1491CD200B500EF0E20 /* Sources */, 134 | 4628F14A1CD200B500EF0E20 /* Frameworks */, 135 | 4628F14B1CD200B500EF0E20 /* Headers */, 136 | 4628F14C1CD200B500EF0E20 /* Resources */, 137 | ); 138 | buildRules = ( 139 | ); 140 | dependencies = ( 141 | ); 142 | name = "FXNotifications-iOS"; 143 | productName = FXNotifications; 144 | productReference = 4628F14E1CD200B500EF0E20 /* FXNotifications.framework */; 145 | productType = "com.apple.product-type.framework"; 146 | }; 147 | 4628F15F1CD201CF00EF0E20 /* FXNotifications-OSX */ = { 148 | isa = PBXNativeTarget; 149 | buildConfigurationList = 4628F1651CD201CF00EF0E20 /* Build configuration list for PBXNativeTarget "FXNotifications-OSX" */; 150 | buildPhases = ( 151 | 4628F15B1CD201CF00EF0E20 /* Sources */, 152 | 4628F15C1CD201CF00EF0E20 /* Frameworks */, 153 | 4628F15D1CD201CF00EF0E20 /* Headers */, 154 | 4628F15E1CD201CF00EF0E20 /* Resources */, 155 | ); 156 | buildRules = ( 157 | ); 158 | dependencies = ( 159 | ); 160 | name = "FXNotifications-OSX"; 161 | productName = "FXNotifications-OSX"; 162 | productReference = 4628F1601CD201CF00EF0E20 /* FXNotifications.framework */; 163 | productType = "com.apple.product-type.framework"; 164 | }; 165 | 4628F1701CD2050C00EF0E20 /* FXNotifications-watchOS */ = { 166 | isa = PBXNativeTarget; 167 | buildConfigurationList = 4628F1761CD2050C00EF0E20 /* Build configuration list for PBXNativeTarget "FXNotifications-watchOS" */; 168 | buildPhases = ( 169 | 4628F16C1CD2050C00EF0E20 /* Sources */, 170 | 4628F16D1CD2050C00EF0E20 /* Frameworks */, 171 | 4628F16E1CD2050C00EF0E20 /* Headers */, 172 | 4628F16F1CD2050C00EF0E20 /* Resources */, 173 | ); 174 | buildRules = ( 175 | ); 176 | dependencies = ( 177 | ); 178 | name = "FXNotifications-watchOS"; 179 | productName = "FXNotifications-watchOS"; 180 | productReference = 4628F1711CD2050C00EF0E20 /* FXNotifications.framework */; 181 | productType = "com.apple.product-type.framework"; 182 | }; 183 | 4628F17D1CD205CC00EF0E20 /* FXNotifications-tvOS */ = { 184 | isa = PBXNativeTarget; 185 | buildConfigurationList = 4628F1831CD205CC00EF0E20 /* Build configuration list for PBXNativeTarget "FXNotifications-tvOS" */; 186 | buildPhases = ( 187 | 4628F1791CD205CC00EF0E20 /* Sources */, 188 | 4628F17A1CD205CC00EF0E20 /* Frameworks */, 189 | 4628F17B1CD205CC00EF0E20 /* Headers */, 190 | 4628F17C1CD205CC00EF0E20 /* Resources */, 191 | ); 192 | buildRules = ( 193 | ); 194 | dependencies = ( 195 | ); 196 | name = "FXNotifications-tvOS"; 197 | productName = "FXNotifications-tvOS"; 198 | productReference = 4628F17E1CD205CC00EF0E20 /* FXNotifications.framework */; 199 | productType = "com.apple.product-type.framework"; 200 | }; 201 | /* End PBXNativeTarget section */ 202 | 203 | /* Begin PBXProject section */ 204 | 4628F1451CD200B500EF0E20 /* Project object */ = { 205 | isa = PBXProject; 206 | attributes = { 207 | CLASSPREFIX = FX; 208 | LastUpgradeCheck = 0730; 209 | ORGANIZATIONNAME = "Nick Lockwood"; 210 | TargetAttributes = { 211 | 4628F14D1CD200B500EF0E20 = { 212 | CreatedOnToolsVersion = 7.3; 213 | }; 214 | 4628F15F1CD201CF00EF0E20 = { 215 | CreatedOnToolsVersion = 7.3; 216 | }; 217 | 4628F1701CD2050C00EF0E20 = { 218 | CreatedOnToolsVersion = 7.3; 219 | }; 220 | 4628F17D1CD205CC00EF0E20 = { 221 | CreatedOnToolsVersion = 7.3; 222 | }; 223 | }; 224 | }; 225 | buildConfigurationList = 4628F1481CD200B500EF0E20 /* Build configuration list for PBXProject "FXNotifications" */; 226 | compatibilityVersion = "Xcode 3.2"; 227 | developmentRegion = English; 228 | hasScannedForEncodings = 0; 229 | knownRegions = ( 230 | en, 231 | ); 232 | mainGroup = 4628F1441CD200B500EF0E20; 233 | productRefGroup = 4628F14F1CD200B500EF0E20 /* Products */; 234 | projectDirPath = ""; 235 | projectRoot = ""; 236 | targets = ( 237 | 4628F14D1CD200B500EF0E20 /* FXNotifications-iOS */, 238 | 4628F15F1CD201CF00EF0E20 /* FXNotifications-OSX */, 239 | 4628F1701CD2050C00EF0E20 /* FXNotifications-watchOS */, 240 | 4628F17D1CD205CC00EF0E20 /* FXNotifications-tvOS */, 241 | ); 242 | }; 243 | /* End PBXProject section */ 244 | 245 | /* Begin PBXResourcesBuildPhase section */ 246 | 4628F14C1CD200B500EF0E20 /* Resources */ = { 247 | isa = PBXResourcesBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | }; 253 | 4628F15E1CD201CF00EF0E20 /* Resources */ = { 254 | isa = PBXResourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | }; 260 | 4628F16F1CD2050C00EF0E20 /* Resources */ = { 261 | isa = PBXResourcesBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | 4628F17C1CD205CC00EF0E20 /* Resources */ = { 268 | isa = PBXResourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | /* End PBXResourcesBuildPhase section */ 275 | 276 | /* Begin PBXSourcesBuildPhase section */ 277 | 4628F1491CD200B500EF0E20 /* Sources */ = { 278 | isa = PBXSourcesBuildPhase; 279 | buildActionMask = 2147483647; 280 | files = ( 281 | 4628F15A1CD2011100EF0E20 /* FXNotifications.m in Sources */, 282 | ); 283 | runOnlyForDeploymentPostprocessing = 0; 284 | }; 285 | 4628F15B1CD201CF00EF0E20 /* Sources */ = { 286 | isa = PBXSourcesBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | 4628F16A1CD2044D00EF0E20 /* FXNotifications.m in Sources */, 290 | ); 291 | runOnlyForDeploymentPostprocessing = 0; 292 | }; 293 | 4628F16C1CD2050C00EF0E20 /* Sources */ = { 294 | isa = PBXSourcesBuildPhase; 295 | buildActionMask = 2147483647; 296 | files = ( 297 | 4628F1881CD20C2800EF0E20 /* FXNotifications.m in Sources */, 298 | ); 299 | runOnlyForDeploymentPostprocessing = 0; 300 | }; 301 | 4628F1791CD205CC00EF0E20 /* Sources */ = { 302 | isa = PBXSourcesBuildPhase; 303 | buildActionMask = 2147483647; 304 | files = ( 305 | 4628F1891CD20C2800EF0E20 /* FXNotifications.m in Sources */, 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | /* End PBXSourcesBuildPhase section */ 310 | 311 | /* Begin XCBuildConfiguration section */ 312 | 4628F1541CD200B500EF0E20 /* Debug */ = { 313 | isa = XCBuildConfiguration; 314 | buildSettings = { 315 | ALWAYS_SEARCH_USER_PATHS = NO; 316 | CLANG_ANALYZER_NONNULL = YES; 317 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 318 | CLANG_CXX_LIBRARY = "libc++"; 319 | CLANG_ENABLE_MODULES = YES; 320 | CLANG_ENABLE_OBJC_ARC = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 324 | CLANG_WARN_EMPTY_BODY = YES; 325 | CLANG_WARN_ENUM_CONVERSION = YES; 326 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; 327 | CLANG_WARN_INT_CONVERSION = YES; 328 | CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES; 329 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 330 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; 331 | CLANG_WARN_UNREACHABLE_CODE = YES; 332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 333 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 334 | COPY_PHASE_STRIP = NO; 335 | DEBUG_INFORMATION_FORMAT = dwarf; 336 | ENABLE_STRICT_OBJC_MSGSEND = YES; 337 | ENABLE_TESTABILITY = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu99; 339 | GCC_DYNAMIC_NO_PIC = NO; 340 | GCC_NO_COMMON_BLOCKS = YES; 341 | GCC_OPTIMIZATION_LEVEL = 0; 342 | GCC_PREPROCESSOR_DEFINITIONS = ( 343 | "DEBUG=1", 344 | "$(inherited)", 345 | ); 346 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 347 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 348 | GCC_WARN_PEDANTIC = YES; 349 | GCC_WARN_SHADOW = YES; 350 | GCC_WARN_UNDECLARED_SELECTOR = YES; 351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 352 | GCC_WARN_UNUSED_FUNCTION = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | MODULEMAP_FILE = module.modulemap; 355 | MTL_ENABLE_DEBUG_INFO = YES; 356 | ONLY_ACTIVE_ARCH = YES; 357 | RUN_CLANG_STATIC_ANALYZER = YES; 358 | SDKROOT = iphoneos; 359 | TARGETED_DEVICE_FAMILY = "1,2"; 360 | }; 361 | name = Debug; 362 | }; 363 | 4628F1551CD200B500EF0E20 /* Release */ = { 364 | isa = XCBuildConfiguration; 365 | buildSettings = { 366 | ALWAYS_SEARCH_USER_PATHS = NO; 367 | CLANG_ANALYZER_NONNULL = YES; 368 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 369 | CLANG_CXX_LIBRARY = "libc++"; 370 | CLANG_ENABLE_MODULES = YES; 371 | CLANG_ENABLE_OBJC_ARC = YES; 372 | CLANG_WARN_BOOL_CONVERSION = YES; 373 | CLANG_WARN_CONSTANT_CONVERSION = YES; 374 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 375 | CLANG_WARN_EMPTY_BODY = YES; 376 | CLANG_WARN_ENUM_CONVERSION = YES; 377 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES; 378 | CLANG_WARN_INT_CONVERSION = YES; 379 | CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES; 380 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 381 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; 382 | CLANG_WARN_UNREACHABLE_CODE = YES; 383 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 384 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 385 | COPY_PHASE_STRIP = NO; 386 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 387 | ENABLE_NS_ASSERTIONS = NO; 388 | ENABLE_STRICT_OBJC_MSGSEND = YES; 389 | GCC_C_LANGUAGE_STANDARD = gnu99; 390 | GCC_NO_COMMON_BLOCKS = YES; 391 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 392 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 393 | GCC_WARN_PEDANTIC = YES; 394 | GCC_WARN_SHADOW = YES; 395 | GCC_WARN_UNDECLARED_SELECTOR = YES; 396 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 397 | GCC_WARN_UNUSED_FUNCTION = YES; 398 | GCC_WARN_UNUSED_VARIABLE = YES; 399 | MODULEMAP_FILE = module.modulemap; 400 | MTL_ENABLE_DEBUG_INFO = NO; 401 | RUN_CLANG_STATIC_ANALYZER = YES; 402 | SDKROOT = iphoneos; 403 | TARGETED_DEVICE_FAMILY = "1,2"; 404 | VALIDATE_PRODUCT = YES; 405 | }; 406 | name = Release; 407 | }; 408 | 4628F1571CD200B500EF0E20 /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | buildSettings = { 411 | APPLICATION_EXTENSION_API_ONLY = YES; 412 | DEFINES_MODULE = YES; 413 | DYLIB_COMPATIBILITY_VERSION = 1; 414 | DYLIB_CURRENT_VERSION = 1; 415 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 416 | INFOPLIST_FILE = Info.plist; 417 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 418 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 419 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 420 | PRODUCT_BUNDLE_IDENTIFIER = uk.co.charcoaldesign.FXNotifications; 421 | PRODUCT_NAME = FXNotifications; 422 | SKIP_INSTALL = YES; 423 | TVOS_DEPLOYMENT_TARGET = 9.0; 424 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 425 | }; 426 | name = Debug; 427 | }; 428 | 4628F1581CD200B500EF0E20 /* Release */ = { 429 | isa = XCBuildConfiguration; 430 | buildSettings = { 431 | APPLICATION_EXTENSION_API_ONLY = YES; 432 | DEFINES_MODULE = YES; 433 | DYLIB_COMPATIBILITY_VERSION = 1; 434 | DYLIB_CURRENT_VERSION = 1; 435 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 436 | INFOPLIST_FILE = Info.plist; 437 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 438 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 439 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 440 | PRODUCT_BUNDLE_IDENTIFIER = uk.co.charcoaldesign.FXNotifications; 441 | PRODUCT_NAME = FXNotifications; 442 | SKIP_INSTALL = YES; 443 | TVOS_DEPLOYMENT_TARGET = 9.0; 444 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 445 | }; 446 | name = Release; 447 | }; 448 | 4628F1661CD201CF00EF0E20 /* Debug */ = { 449 | isa = XCBuildConfiguration; 450 | buildSettings = { 451 | APPLICATION_EXTENSION_API_ONLY = YES; 452 | CODE_SIGN_IDENTITY = "-"; 453 | COMBINE_HIDPI_IMAGES = YES; 454 | DEFINES_MODULE = YES; 455 | DYLIB_COMPATIBILITY_VERSION = 1; 456 | DYLIB_CURRENT_VERSION = 1; 457 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 458 | FRAMEWORK_VERSION = A; 459 | INFOPLIST_FILE = Info.plist; 460 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 461 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 462 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 463 | MACOSX_DEPLOYMENT_TARGET = 10.7; 464 | PRODUCT_BUNDLE_IDENTIFIER = uk.co.charcoaldesign.FXNotifications; 465 | PRODUCT_NAME = FXNotifications; 466 | SDKROOT = macosx; 467 | SKIP_INSTALL = YES; 468 | }; 469 | name = Debug; 470 | }; 471 | 4628F1671CD201CF00EF0E20 /* Release */ = { 472 | isa = XCBuildConfiguration; 473 | buildSettings = { 474 | APPLICATION_EXTENSION_API_ONLY = YES; 475 | CODE_SIGN_IDENTITY = "-"; 476 | COMBINE_HIDPI_IMAGES = YES; 477 | DEFINES_MODULE = YES; 478 | DYLIB_COMPATIBILITY_VERSION = 1; 479 | DYLIB_CURRENT_VERSION = 1; 480 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 481 | FRAMEWORK_VERSION = A; 482 | INFOPLIST_FILE = Info.plist; 483 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 484 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 485 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 486 | MACOSX_DEPLOYMENT_TARGET = 10.7; 487 | PRODUCT_BUNDLE_IDENTIFIER = uk.co.charcoaldesign.FXNotifications; 488 | PRODUCT_NAME = FXNotifications; 489 | SDKROOT = macosx; 490 | SKIP_INSTALL = YES; 491 | }; 492 | name = Release; 493 | }; 494 | 4628F1771CD2050C00EF0E20 /* Debug */ = { 495 | isa = XCBuildConfiguration; 496 | buildSettings = { 497 | APPLICATION_EXTENSION_API_ONLY = YES; 498 | DEFINES_MODULE = YES; 499 | DYLIB_COMPATIBILITY_VERSION = 1; 500 | DYLIB_CURRENT_VERSION = 1; 501 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 502 | INFOPLIST_FILE = Info.plist; 503 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 504 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 505 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 506 | PRODUCT_BUNDLE_IDENTIFIER = uk.co.charcoaldesign.FXNotifications; 507 | PRODUCT_NAME = FXNotifications; 508 | SDKROOT = watchos; 509 | SKIP_INSTALL = YES; 510 | TARGETED_DEVICE_FAMILY = 4; 511 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 512 | }; 513 | name = Debug; 514 | }; 515 | 4628F1781CD2050C00EF0E20 /* Release */ = { 516 | isa = XCBuildConfiguration; 517 | buildSettings = { 518 | APPLICATION_EXTENSION_API_ONLY = YES; 519 | DEFINES_MODULE = YES; 520 | DYLIB_COMPATIBILITY_VERSION = 1; 521 | DYLIB_CURRENT_VERSION = 1; 522 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 523 | INFOPLIST_FILE = Info.plist; 524 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 525 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 526 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 527 | PRODUCT_BUNDLE_IDENTIFIER = uk.co.charcoaldesign.FXNotifications; 528 | PRODUCT_NAME = FXNotifications; 529 | SDKROOT = watchos; 530 | SKIP_INSTALL = YES; 531 | TARGETED_DEVICE_FAMILY = 4; 532 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 533 | }; 534 | name = Release; 535 | }; 536 | 4628F1841CD205CC00EF0E20 /* Debug */ = { 537 | isa = XCBuildConfiguration; 538 | buildSettings = { 539 | APPLICATION_EXTENSION_API_ONLY = YES; 540 | DEFINES_MODULE = YES; 541 | DYLIB_COMPATIBILITY_VERSION = 1; 542 | DYLIB_CURRENT_VERSION = 1; 543 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 544 | INFOPLIST_FILE = Info.plist; 545 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 546 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 547 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 548 | PRODUCT_BUNDLE_IDENTIFIER = uk.co.charcoaldesign.FXNotifications; 549 | PRODUCT_NAME = FXNotifications; 550 | SDKROOT = appletvos; 551 | SKIP_INSTALL = YES; 552 | TARGETED_DEVICE_FAMILY = 3; 553 | TVOS_DEPLOYMENT_TARGET = 9.0; 554 | }; 555 | name = Debug; 556 | }; 557 | 4628F1851CD205CC00EF0E20 /* Release */ = { 558 | isa = XCBuildConfiguration; 559 | buildSettings = { 560 | APPLICATION_EXTENSION_API_ONLY = YES; 561 | DEFINES_MODULE = YES; 562 | DYLIB_COMPATIBILITY_VERSION = 1; 563 | DYLIB_CURRENT_VERSION = 1; 564 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 565 | INFOPLIST_FILE = Info.plist; 566 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 567 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 568 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 569 | PRODUCT_BUNDLE_IDENTIFIER = uk.co.charcoaldesign.FXNotifications; 570 | PRODUCT_NAME = FXNotifications; 571 | SDKROOT = appletvos; 572 | SKIP_INSTALL = YES; 573 | TARGETED_DEVICE_FAMILY = 3; 574 | TVOS_DEPLOYMENT_TARGET = 9.0; 575 | }; 576 | name = Release; 577 | }; 578 | /* End XCBuildConfiguration section */ 579 | 580 | /* Begin XCConfigurationList section */ 581 | 4628F1481CD200B500EF0E20 /* Build configuration list for PBXProject "FXNotifications" */ = { 582 | isa = XCConfigurationList; 583 | buildConfigurations = ( 584 | 4628F1541CD200B500EF0E20 /* Debug */, 585 | 4628F1551CD200B500EF0E20 /* Release */, 586 | ); 587 | defaultConfigurationIsVisible = 0; 588 | defaultConfigurationName = Release; 589 | }; 590 | 4628F1561CD200B500EF0E20 /* Build configuration list for PBXNativeTarget "FXNotifications-iOS" */ = { 591 | isa = XCConfigurationList; 592 | buildConfigurations = ( 593 | 4628F1571CD200B500EF0E20 /* Debug */, 594 | 4628F1581CD200B500EF0E20 /* Release */, 595 | ); 596 | defaultConfigurationIsVisible = 0; 597 | defaultConfigurationName = Release; 598 | }; 599 | 4628F1651CD201CF00EF0E20 /* Build configuration list for PBXNativeTarget "FXNotifications-OSX" */ = { 600 | isa = XCConfigurationList; 601 | buildConfigurations = ( 602 | 4628F1661CD201CF00EF0E20 /* Debug */, 603 | 4628F1671CD201CF00EF0E20 /* Release */, 604 | ); 605 | defaultConfigurationIsVisible = 0; 606 | }; 607 | 4628F1761CD2050C00EF0E20 /* Build configuration list for PBXNativeTarget "FXNotifications-watchOS" */ = { 608 | isa = XCConfigurationList; 609 | buildConfigurations = ( 610 | 4628F1771CD2050C00EF0E20 /* Debug */, 611 | 4628F1781CD2050C00EF0E20 /* Release */, 612 | ); 613 | defaultConfigurationIsVisible = 0; 614 | }; 615 | 4628F1831CD205CC00EF0E20 /* Build configuration list for PBXNativeTarget "FXNotifications-tvOS" */ = { 616 | isa = XCConfigurationList; 617 | buildConfigurations = ( 618 | 4628F1841CD205CC00EF0E20 /* Debug */, 619 | 4628F1851CD205CC00EF0E20 /* Release */, 620 | ); 621 | defaultConfigurationIsVisible = 0; 622 | }; 623 | /* End XCConfigurationList section */ 624 | }; 625 | rootObject = 4628F1451CD200B500EF0E20 /* Project object */; 626 | } 627 | -------------------------------------------------------------------------------- /FXNotifications.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FXNotifications.xcodeproj/xcshareddata/xcschemes/FXNotifications-OSX.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /FXNotifications.xcodeproj/xcshareddata/xcschemes/FXNotifications-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /FXNotifications.xcodeproj/xcshareddata/xcschemes/FXNotifications-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /FXNotifications.xcodeproj/xcshareddata/xcschemes/FXNotifications-watchOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /FXNotifications/FXNotifications.h: -------------------------------------------------------------------------------- 1 | // 2 | // FXNotifications.h 3 | // 4 | // Version 1.1.1 5 | // 6 | // Created by Nick Lockwood on 20/11/2013. 7 | // Copyright (c) 2013 Charcoal Design 8 | // 9 | // Distributed under the permissive zlib license 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/nicklockwood/FXNotifications 13 | // 14 | // This software is provided 'as-is', without any express or implied 15 | // warranty. In no event will the authors be held liable for any damages 16 | // arising from the use of this software. 17 | // 18 | // Permission is granted to anyone to use this software for any purpose, 19 | // including commercial applications, and to alter it and redistribute it 20 | // freely, subject to the following restrictions: 21 | // 22 | // 1. The origin of this software must not be misrepresented; you must not 23 | // claim that you wrote the original software. If you use this software 24 | // in a product, an acknowledgment in the product documentation would be 25 | // appreciated but is not required. 26 | // 27 | // 2. Altered source versions must be plainly marked as such, and must not be 28 | // misrepresented as being the original software. 29 | // 30 | // 3. This notice may not be removed or altered from any source distribution. 31 | // 32 | 33 | #import 34 | 35 | NS_ASSUME_NONNULL_BEGIN 36 | 37 | #pragma GCC diagnostic push 38 | #pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" 39 | 40 | @interface NSNotificationCenter (FXNotifications) 41 | 42 | - (id)addObserver:(id)observer 43 | forName:(nullable NSString *)name 44 | object:(nullable id)object 45 | queue:(nullable NSOperationQueue *)queue 46 | usingBlock:(void (^)(NSNotification *note, id observer))block; 47 | 48 | @end 49 | 50 | #pragma GCC diagnostic pop 51 | 52 | NS_ASSUME_NONNULL_END 53 | -------------------------------------------------------------------------------- /FXNotifications/FXNotifications.m: -------------------------------------------------------------------------------- 1 | // 2 | // FXNotifications.m 3 | // 4 | // Version 1.1.1 5 | // 6 | // Created by Nick Lockwood on 20/11/2013. 7 | // Copyright (c) 2013 Charcoal Design 8 | // 9 | // Distributed under the permissive zlib license 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/nicklockwood/FXNotifications 13 | // 14 | // This software is provided 'as-is', without any express or implied 15 | // warranty. In no event will the authors be held liable for any damages 16 | // arising from the use of this software. 17 | // 18 | // Permission is granted to anyone to use this software for any purpose, 19 | // including commercial applications, and to alter it and redistribute it 20 | // freely, subject to the following restrictions: 21 | // 22 | // 1. The origin of this software must not be misrepresented; you must not 23 | // claim that you wrote the original software. If you use this software 24 | // in a product, an acknowledgment in the product documentation would be 25 | // appreciated but is not required. 26 | // 27 | // 2. Altered source versions must be plainly marked as such, and must not be 28 | // misrepresented as being the original software. 29 | // 30 | // 3. This notice may not be removed or altered from any source distribution. 31 | // 32 | 33 | 34 | #import "FXNotifications.h" 35 | #import 36 | 37 | 38 | #pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" 39 | #pragma GCC diagnostic ignored "-Wselector" 40 | #pragma GCC diagnostic ignored "-Wgnu" 41 | 42 | 43 | #import 44 | #if !__has_feature(objc_arc) || !__has_feature(objc_arc_weak) 45 | #error This class requires automatic reference counting and weak references 46 | #endif 47 | 48 | 49 | typedef void (^FXNotificationBlock)(NSNotification *note, id observer); 50 | 51 | 52 | static NSMutableArray *FXNotificationsGetObservers(id object, BOOL create) 53 | { 54 | @synchronized(object) 55 | { 56 | static void *key = &key; 57 | NSMutableArray *wrappers = objc_getAssociatedObject(object, key); 58 | if (!wrappers && create) 59 | { 60 | wrappers = [NSMutableArray array]; 61 | objc_setAssociatedObject(object, key, wrappers, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 62 | } 63 | return wrappers; 64 | } 65 | } 66 | 67 | 68 | @interface FXNotificationObserver : NSObject 69 | 70 | @property (nonatomic, weak) NSObject *observer; 71 | @property (nonatomic, weak) NSObject *object; 72 | @property (nonatomic, copy) NSString *name; 73 | @property (nonatomic, copy) FXNotificationBlock block; 74 | @property (nonatomic, strong) NSOperationQueue *queue; 75 | @property (nonatomic, weak) NSNotificationCenter *center; 76 | 77 | - (void)action:(NSNotification *)note; 78 | 79 | @end 80 | 81 | 82 | @implementation FXNotificationObserver 83 | 84 | - (void)action:(NSNotification *)note 85 | { 86 | __strong id strongObserver = self.observer; 87 | if (self.block && strongObserver) 88 | { 89 | if (!self.queue || [NSOperationQueue currentQueue] == self.queue) 90 | { 91 | self.block(note, strongObserver); 92 | } 93 | else 94 | { 95 | [self.queue addOperationWithBlock:^{ 96 | self.block(note, strongObserver); 97 | }]; 98 | } 99 | } 100 | } 101 | 102 | - (void)dealloc 103 | { 104 | __strong NSNotificationCenter *strongCenter = _center; 105 | [strongCenter removeObserver:self]; 106 | } 107 | 108 | @end 109 | 110 | 111 | @implementation NSNotificationCenter (FXNotifications) 112 | 113 | + (void)load 114 | { 115 | SEL original = @selector(removeObserver:name:object:); 116 | SEL replacement = @selector(FXNotification_removeObserver:name:object:); 117 | method_exchangeImplementations(class_getInstanceMethod(self, original), 118 | class_getInstanceMethod(self, replacement)); 119 | } 120 | 121 | - (id)addObserver:(id)observer 122 | forName:(nullable NSString *)name 123 | object:(nullable id)object 124 | queue:(nullable NSOperationQueue *)queue 125 | usingBlock:(FXNotificationBlock)block 126 | { 127 | FXNotificationObserver *container = [[FXNotificationObserver alloc] init]; 128 | container.observer = observer; 129 | container.object = object; 130 | container.name = name; 131 | container.block = block; 132 | container.queue = queue; 133 | container.center = self; 134 | 135 | [FXNotificationsGetObservers(observer, YES) addObject:container]; 136 | [self addObserver:container selector:@selector(action:) name:name object:object]; 137 | return container; 138 | } 139 | 140 | - (void)FXNotification_removeObserver:(id)observer name:(NSString *)name object:(id)object 141 | { 142 | for (FXNotificationObserver *container in [FXNotificationsGetObservers(observer, NO) reverseObjectEnumerator]) 143 | { 144 | __strong id strongObject = container.object; 145 | if (container.center == self && 146 | (!container.name || !name || [container.name isEqualToString:name]) && 147 | (!strongObject || !object || strongObject == object)) 148 | { 149 | [FXNotificationsGetObservers(observer, NO) removeObject:container]; 150 | } 151 | } 152 | if (object_getClass(observer) == [FXNotificationObserver class]) 153 | { 154 | FXNotificationObserver *container = observer; 155 | __strong NSObject *strongObserver = container.observer; 156 | [FXNotificationsGetObservers(strongObserver, NO) removeObject:container]; 157 | } 158 | [self FXNotification_removeObserver:observer name:name object:object]; 159 | } 160 | 161 | @end 162 | 163 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.1.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © 2013 Nick Lockwood. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /LICENCE.md: -------------------------------------------------------------------------------- 1 | FXNotifications 2 | 3 | Version 1.1.1, April 27th, 2016 4 | 5 | Copyright (C) 2013 Nick Lockwood 6 | 7 | This software is provided 'as-is', without any express or implied 8 | warranty. In no event will the authors be held liable for any damages 9 | arising from the use of this software. 10 | 11 | Permission is granted to anyone to use this software for any purpose, 12 | including commercial applications, and to alter it and redistribute it 13 | freely, subject to the following restrictions: 14 | 15 | 1. The origin of this software must not be misrepresented; you must not 16 | claim that you wrote the original software. If you use this software 17 | in a product, an acknowledgment in the product documentation would be 18 | appreciated but is not required. 19 | 2. Altered source versions must be plainly marked as such, and must not be 20 | misrepresented as being the original software. 21 | 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Purpose 2 | -------------- 3 | 4 | FXNotifications is a category on `NSNotificationCenter` that provides an improved block-based API that is simpler and easier to use, and avoids the various retain cycle and memory leak pitfalls of the official API. 5 | 6 | For more details, see this article: http://sealedabstract.com/code/nsnotificationcenter-with-blocks-considered-harmful/ and this gist: https://gist.github.com/nicklockwood/7559729 7 | 8 | 9 | Supported iOS & SDK Versions 10 | ----------------------------- 11 | 12 | * Supported build target - iOS 9.3 / Mac OS 10.11 (Xcode 7.3, Apple LLVM compiler 7.0) 13 | * Earliest supported deployment target - iOS 7.0 / Mac OS 10.10 14 | * Earliest compatible deployment target - iOS 5.0 / Mac OS 10.7 15 | 16 | NOTE: 'Supported' means that the library has been tested with this version. 'Compatible' means that the library should work on this iOS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly. 17 | 18 | 19 | ARC Compatibility 20 | ------------------ 21 | 22 | FXNotifications requires ARC and uses weak references. 23 | 24 | 25 | Thread Safety 26 | -------------- 27 | 28 | It is safe to add and remove observers concurrently on different threads using the FXNotification methods. Callback blocks will be executed on the specified queue. 29 | 30 | 31 | Installation & Usage 32 | -------------------- 33 | 34 | To use FXNotifications, just drag the FXNotifications.h and .m files into your project and import the header file in your class. 35 | 36 | 37 | Methods 38 | ------------ 39 | 40 | FXNotifications extends NSNotificationCenter with a single method 41 | 42 | - (id)addObserver:(id)observer 43 | forName:(nullable NSString *)name 44 | object:(nullable id)object 45 | queue:(NSOperationQueue *)queue 46 | usingBlock:(void (^)(NSNotification *note, id observer))block; 47 | 48 | This method is a hybrid of the two built-in notification observer methods. The observer parameter is required, and represents the owner of the block argument. When the observer is released, the block will be released as well. 49 | 50 | The name, object, queue and block arguments work as they do in the normal block-based observer method. The queue parameter is optional - if nil is passed then the block will be executed on whichever queue the notification is posted from. To avoid retain cycles in your block, you can refer to the weak observer parameter that is passed as a second argument. 51 | 52 | The method returns a token value that can be used to stop observing the notification, use the standard `-removeObserver:` method of `NSNotificationCenter`, e.g. 53 | 54 | [[NSNotificationCenter defaultCenter] removeObserver:token]; 55 | 56 | However, you can simply discard this token and the token will be deregistered automatically when the observer is released. There is no need to call removeObserver: in the observer's dealloc method; this is done automatically. 57 | 58 | Also, if you wish, you can deregister the observer itself using the `-removeObserver:` or `-removeObserver:name:object:` methods of `NSNotificationCenter`, so the only reason to store the token is if you wish to distinguish between multiple registrations of the same observer with the same selector. 59 | 60 | A typical usage might be: 61 | 62 | [[NSNotificationCenter defaultCenter] addObserver:self 63 | forName:NSSomeNotificationName 64 | object:nil 65 | queue:[NSOperationQueue mainQueue] 66 | usingBlock:^(NSNotification *note, id observer) { 67 | NSLog(@"self: %@", observer); // look, no leaks! 68 | }]; 69 | 70 | 71 | Release Notes 72 | ------------------- 73 | 74 | Version 1.1.1 75 | 76 | - Removed implicit assumption that observers are NSObject subclasses (fixes issues with Swift) 77 | - Added nullability annotations 78 | 79 | Version 1.1 80 | 81 | - FXNotifications no longer captures the current queue if nil is passed as the queue parameter. Instead, the block will simply be executed on whichever queue the notification is posted on. 82 | - Observer is no longer passed as a weak parameter to the block, which means that it is guaranteed not to be released during the block's execution 83 | - addObserver method now returns a unique token each time it is called, allowing it to be used in the same way as the standard implementation for fine-grained reregistration (use of the token is optional however, you can safely discard it if not needed) 84 | - Now conforms to `-Weverything` warning level 85 | 86 | Version 1.0.2 87 | 88 | - Fixed bug where observer could not be re-attached after being removed 89 | 90 | Version 1.0.1 91 | 92 | - Fixed bug where removing the observer didn't work 93 | - The queue parameter now defaults to `[NSOperationQueue currentQueue]` if nil 94 | - Added CocoaPods podspec 95 | 96 | Version 1.0 97 | 98 | - Initial release 99 | -------------------------------------------------------------------------------- /module.modulemap: -------------------------------------------------------------------------------- 1 | framework module FXNotifications { 2 | header "FXNotifications.h" 3 | } 4 | --------------------------------------------------------------------------------