├── .gitignore ├── LICENSE ├── RCTRemotePushManager.h ├── RCTRemotePushManager.m ├── RCTRemotePushManager.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── RCTRemotePushManager.xccheckout │ └── xcuserdata │ │ └── minch.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── minch.xcuserdatad │ └── xcschemes │ ├── RCTRemotePushManager.xcscheme │ └── xcschememanagement.plist ├── README.md ├── RemotePushDelegate.h ├── RemotePushDelegate.m ├── RemotePushIOS.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # node.js 26 | # 27 | node_modules/ 28 | npm-debug.log 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Daryl Rowland 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /RCTRemotePushManager.h: -------------------------------------------------------------------------------- 1 | #import "RCTBridgeModule.h" 2 | 3 | @interface RCTRemotePushManager: NSObject 4 | 5 | - (void)requestPermissions; 6 | - (void) registeredForRemoteNotifications:(NSNotification *) notification; 7 | 8 | @end -------------------------------------------------------------------------------- /RCTRemotePushManager.m: -------------------------------------------------------------------------------- 1 | #import "RCTRemotePushManager.h" 2 | #import "RCTBridge.h" 3 | #import "RCTEventDispatcher.h" 4 | 5 | @implementation RCTRemotePushManager 6 | 7 | RCT_EXPORT_MODULE() 8 | 9 | @synthesize bridge = _bridge; 10 | 11 | NSDictionary *startupNotification; 12 | 13 | - (id) init 14 | { 15 | self = [super init]; 16 | if (!self) return nil; 17 | 18 | // Registered for remote notifications 19 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registeredForRemoteNotifications:) name:@"registeredForRemoteNotifications" object:nil]; 20 | 21 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registeredForRemoteNotifications:) name:@"registeredForRemoteNotificationsError" object:nil]; 22 | 23 | // Received remote notification 24 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedRemoteNotification:) name:@"receivedRemoteNotification" object:nil]; 25 | 26 | // Received remote notification 27 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedRemoteNotificationOnStart:) name:@"receivedRemoteNotificationOnStart" object:nil]; 28 | 29 | return self; 30 | } 31 | 32 | - (void) dealloc 33 | { 34 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 35 | } 36 | 37 | RCT_EXPORT_METHOD(requestPermissions) 38 | { 39 | 40 | //Register for remote notifications straightaway 41 | [[UIApplication sharedApplication] registerForRemoteNotifications]; 42 | 43 | // Now register for user notifications 44 | UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert; 45 | UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; 46 | [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings]; 47 | 48 | 49 | } 50 | 51 | - (void) registeredForRemoteNotifications:(NSNotification *) notification { 52 | NSDictionary *userInfo = notification.userInfo; 53 | NSData *deviceToken = [userInfo objectForKey:@"deviceToken"]; 54 | 55 | NSString *deviceTokenStr = [[[[deviceToken description] 56 | stringByReplacingOccurrencesOfString: @"<" withString: @""] 57 | stringByReplacingOccurrencesOfString: @">" withString: @""] 58 | stringByReplacingOccurrencesOfString: @" " withString: @""]; 59 | 60 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"registeredForRemoteNotifications" 61 | body:@{@"token": deviceTokenStr}]; 62 | 63 | } 64 | 65 | - (void) registeredForRemoteNotificationsError:(NSNotification *) notification { 66 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"registeredForRemoteNotifications" 67 | body:@{@"error": @"Could not register for remote noticiations"}]; 68 | } 69 | 70 | - (void) receivedRemoteNotification:(NSNotification *) notification { 71 | NSDictionary *userInfo = notification.userInfo; 72 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"receivedRemoteNotification" body: userInfo]; 73 | } 74 | 75 | - (void) receivedRemoteNotificationOnStart:(NSNotification *) notification { 76 | startupNotification = notification.userInfo; 77 | } 78 | 79 | RCT_EXPORT_METHOD(getStartupNotifications: (RCTResponseSenderBlock)callback) 80 | { 81 | 82 | if (startupNotification) { 83 | callback(@[[NSNull null], startupNotification]); 84 | } else { 85 | callback(@[[NSNull null], [NSNull null]]); 86 | } 87 | } 88 | 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /RCTRemotePushManager.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 48DDA26E1B0A1157004C75B0 /* RCTRemotePushManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 48DDA26D1B0A1157004C75B0 /* RCTRemotePushManager.h */; }; 11 | 48DDA2701B0A1157004C75B0 /* RCTRemotePushManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 48DDA26F1B0A1157004C75B0 /* RCTRemotePushManager.m */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | 48DDA2681B0A1157004C75B0 /* CopyFiles */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = "include/$(PRODUCT_NAME)"; 19 | dstSubfolderSpec = 16; 20 | files = ( 21 | 48DDA26E1B0A1157004C75B0 /* RCTRemotePushManager.h in CopyFiles */, 22 | ); 23 | runOnlyForDeploymentPostprocessing = 0; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 48DDA26A1B0A1157004C75B0 /* libRCTRemotePushManager.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTRemotePushManager.a; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 48DDA26D1B0A1157004C75B0 /* RCTRemotePushManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTRemotePushManager.h; sourceTree = ""; }; 30 | 48DDA26F1B0A1157004C75B0 /* RCTRemotePushManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTRemotePushManager.m; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | 48DDA2671B0A1157004C75B0 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 48DDA2611B0A1157004C75B0 = { 45 | isa = PBXGroup; 46 | children = ( 47 | 48DDA26D1B0A1157004C75B0 /* RCTRemotePushManager.h */, 48 | 48DDA26F1B0A1157004C75B0 /* RCTRemotePushManager.m */, 49 | 48DDA26B1B0A1157004C75B0 /* Products */, 50 | ); 51 | sourceTree = ""; 52 | }; 53 | 48DDA26B1B0A1157004C75B0 /* Products */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | 48DDA26A1B0A1157004C75B0 /* libRCTRemotePushManager.a */, 57 | ); 58 | name = Products; 59 | sourceTree = ""; 60 | }; 61 | /* End PBXGroup section */ 62 | 63 | /* Begin PBXNativeTarget section */ 64 | 48DDA2691B0A1157004C75B0 /* RCTRemotePushManager */ = { 65 | isa = PBXNativeTarget; 66 | buildConfigurationList = 48DDA27E1B0A1157004C75B0 /* Build configuration list for PBXNativeTarget "RCTRemotePushManager" */; 67 | buildPhases = ( 68 | 48DDA2661B0A1157004C75B0 /* Sources */, 69 | 48DDA2671B0A1157004C75B0 /* Frameworks */, 70 | 48DDA2681B0A1157004C75B0 /* CopyFiles */, 71 | ); 72 | buildRules = ( 73 | ); 74 | dependencies = ( 75 | ); 76 | name = RCTRemotePushManager; 77 | productName = RCTRemotePushManager; 78 | productReference = 48DDA26A1B0A1157004C75B0 /* libRCTRemotePushManager.a */; 79 | productType = "com.apple.product-type.library.static"; 80 | }; 81 | /* End PBXNativeTarget section */ 82 | 83 | /* Begin PBXProject section */ 84 | 48DDA2621B0A1157004C75B0 /* Project object */ = { 85 | isa = PBXProject; 86 | attributes = { 87 | LastUpgradeCheck = 0630; 88 | ORGANIZATIONNAME = "Min Chen"; 89 | TargetAttributes = { 90 | 48DDA2691B0A1157004C75B0 = { 91 | CreatedOnToolsVersion = 6.3.1; 92 | }; 93 | }; 94 | }; 95 | buildConfigurationList = 48DDA2651B0A1157004C75B0 /* Build configuration list for PBXProject "RCTRemotePushManager" */; 96 | compatibilityVersion = "Xcode 3.2"; 97 | developmentRegion = English; 98 | hasScannedForEncodings = 0; 99 | knownRegions = ( 100 | en, 101 | ); 102 | mainGroup = 48DDA2611B0A1157004C75B0; 103 | productRefGroup = 48DDA26B1B0A1157004C75B0 /* Products */; 104 | projectDirPath = ""; 105 | projectRoot = ""; 106 | targets = ( 107 | 48DDA2691B0A1157004C75B0 /* RCTRemotePushManager */, 108 | ); 109 | }; 110 | /* End PBXProject section */ 111 | 112 | /* Begin PBXSourcesBuildPhase section */ 113 | 48DDA2661B0A1157004C75B0 /* Sources */ = { 114 | isa = PBXSourcesBuildPhase; 115 | buildActionMask = 2147483647; 116 | files = ( 117 | 48DDA2701B0A1157004C75B0 /* RCTRemotePushManager.m in Sources */, 118 | ); 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | /* End PBXSourcesBuildPhase section */ 122 | 123 | /* Begin XCBuildConfiguration section */ 124 | 48DDA27C1B0A1157004C75B0 /* Debug */ = { 125 | isa = XCBuildConfiguration; 126 | buildSettings = { 127 | ALWAYS_SEARCH_USER_PATHS = NO; 128 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 129 | CLANG_CXX_LIBRARY = "libc++"; 130 | CLANG_ENABLE_MODULES = YES; 131 | CLANG_ENABLE_OBJC_ARC = YES; 132 | CLANG_WARN_BOOL_CONVERSION = YES; 133 | CLANG_WARN_CONSTANT_CONVERSION = YES; 134 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 135 | CLANG_WARN_EMPTY_BODY = YES; 136 | CLANG_WARN_ENUM_CONVERSION = YES; 137 | CLANG_WARN_INT_CONVERSION = YES; 138 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 139 | CLANG_WARN_UNREACHABLE_CODE = YES; 140 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 141 | COPY_PHASE_STRIP = NO; 142 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 143 | ENABLE_STRICT_OBJC_MSGSEND = YES; 144 | GCC_C_LANGUAGE_STANDARD = gnu99; 145 | GCC_DYNAMIC_NO_PIC = NO; 146 | GCC_NO_COMMON_BLOCKS = YES; 147 | GCC_OPTIMIZATION_LEVEL = 0; 148 | GCC_PREPROCESSOR_DEFINITIONS = ( 149 | "DEBUG=1", 150 | "$(inherited)", 151 | ); 152 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 153 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 154 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 155 | GCC_WARN_UNDECLARED_SELECTOR = YES; 156 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 157 | GCC_WARN_UNUSED_FUNCTION = YES; 158 | GCC_WARN_UNUSED_VARIABLE = YES; 159 | HEADER_SEARCH_PATHS = ( 160 | "$(inherited)", 161 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 162 | ); 163 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 164 | MTL_ENABLE_DEBUG_INFO = YES; 165 | ONLY_ACTIVE_ARCH = YES; 166 | SDKROOT = iphoneos; 167 | }; 168 | name = Debug; 169 | }; 170 | 48DDA27D1B0A1157004C75B0 /* Release */ = { 171 | isa = XCBuildConfiguration; 172 | buildSettings = { 173 | ALWAYS_SEARCH_USER_PATHS = NO; 174 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 175 | CLANG_CXX_LIBRARY = "libc++"; 176 | CLANG_ENABLE_MODULES = YES; 177 | CLANG_ENABLE_OBJC_ARC = YES; 178 | CLANG_WARN_BOOL_CONVERSION = YES; 179 | CLANG_WARN_CONSTANT_CONVERSION = YES; 180 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 181 | CLANG_WARN_EMPTY_BODY = YES; 182 | CLANG_WARN_ENUM_CONVERSION = YES; 183 | CLANG_WARN_INT_CONVERSION = YES; 184 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 185 | CLANG_WARN_UNREACHABLE_CODE = YES; 186 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 187 | COPY_PHASE_STRIP = NO; 188 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 189 | ENABLE_NS_ASSERTIONS = NO; 190 | ENABLE_STRICT_OBJC_MSGSEND = YES; 191 | GCC_C_LANGUAGE_STANDARD = gnu99; 192 | GCC_NO_COMMON_BLOCKS = YES; 193 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 194 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 195 | GCC_WARN_UNDECLARED_SELECTOR = YES; 196 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 197 | GCC_WARN_UNUSED_FUNCTION = YES; 198 | GCC_WARN_UNUSED_VARIABLE = YES; 199 | HEADER_SEARCH_PATHS = ( 200 | "$(inherited)", 201 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 202 | ); 203 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 204 | MTL_ENABLE_DEBUG_INFO = NO; 205 | SDKROOT = iphoneos; 206 | VALIDATE_PRODUCT = YES; 207 | }; 208 | name = Release; 209 | }; 210 | 48DDA27F1B0A1157004C75B0 /* Debug */ = { 211 | isa = XCBuildConfiguration; 212 | buildSettings = { 213 | HEADER_SEARCH_PATHS = ( 214 | "$(inherited)", 215 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 216 | "$(SRCROOT)/../react-native/React/**", 217 | ); 218 | OTHER_LDFLAGS = "-ObjC"; 219 | PRODUCT_NAME = "$(TARGET_NAME)"; 220 | SKIP_INSTALL = YES; 221 | }; 222 | name = Debug; 223 | }; 224 | 48DDA2801B0A1157004C75B0 /* Release */ = { 225 | isa = XCBuildConfiguration; 226 | buildSettings = { 227 | HEADER_SEARCH_PATHS = ( 228 | "$(inherited)", 229 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 230 | "$(SRCROOT)/../react-native/React/**", 231 | ); 232 | OTHER_LDFLAGS = "-ObjC"; 233 | PRODUCT_NAME = "$(TARGET_NAME)"; 234 | SKIP_INSTALL = YES; 235 | }; 236 | name = Release; 237 | }; 238 | /* End XCBuildConfiguration section */ 239 | 240 | /* Begin XCConfigurationList section */ 241 | 48DDA2651B0A1157004C75B0 /* Build configuration list for PBXProject "RCTRemotePushManager" */ = { 242 | isa = XCConfigurationList; 243 | buildConfigurations = ( 244 | 48DDA27C1B0A1157004C75B0 /* Debug */, 245 | 48DDA27D1B0A1157004C75B0 /* Release */, 246 | ); 247 | defaultConfigurationIsVisible = 0; 248 | defaultConfigurationName = Release; 249 | }; 250 | 48DDA27E1B0A1157004C75B0 /* Build configuration list for PBXNativeTarget "RCTRemotePushManager" */ = { 251 | isa = XCConfigurationList; 252 | buildConfigurations = ( 253 | 48DDA27F1B0A1157004C75B0 /* Debug */, 254 | 48DDA2801B0A1157004C75B0 /* Release */, 255 | ); 256 | defaultConfigurationIsVisible = 0; 257 | defaultConfigurationName = Release; 258 | }; 259 | /* End XCConfigurationList section */ 260 | }; 261 | rootObject = 48DDA2621B0A1157004C75B0 /* Project object */; 262 | } 263 | -------------------------------------------------------------------------------- /RCTRemotePushManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RCTRemotePushManager.xcodeproj/project.xcworkspace/xcshareddata/RCTRemotePushManager.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | E1A53E75-47D8-4BDE-90A6-6B601682AB74 9 | IDESourceControlProjectName 10 | RCTRemotePushManager 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 6641E9F8FE34E27C4F8FBDDEDD4238BA470AFD12 14 | github.com:minchnew/react-native-remote-push.git 15 | 16 | IDESourceControlProjectPath 17 | RCTRemotePushManager.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 6641E9F8FE34E27C4F8FBDDEDD4238BA470AFD12 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | github.com:minchnew/react-native-remote-push.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 6641E9F8FE34E27C4F8FBDDEDD4238BA470AFD12 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 6641E9F8FE34E27C4F8FBDDEDD4238BA470AFD12 36 | IDESourceControlWCCName 37 | react-native-remote-push 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /RCTRemotePushManager.xcodeproj/project.xcworkspace/xcuserdata/minch.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darylrowland/react-native-remote-push/c6b324e0add6108610c7ac4c1682a45ad41f1263/RCTRemotePushManager.xcodeproj/project.xcworkspace/xcuserdata/minch.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /RCTRemotePushManager.xcodeproj/xcuserdata/minch.xcuserdatad/xcschemes/RCTRemotePushManager.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /RCTRemotePushManager.xcodeproj/xcuserdata/minch.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RCTRemotePushManager.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 48DDA2691B0A1157004C75B0 16 | 17 | primary 18 | 19 | 20 | 48DDA2741B0A1157004C75B0 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-remote-push 2 | React Native module that allows you to: 3 | 1. Request push notification permissions 4 | 2. Get the device token back from the request 5 | 3. Subscribe to remote push notifications 6 | 7 | It's very basic code for now, but provides functionality above and beyond the PushNotificationIOS class that is provided as standard in react native. 8 | 9 | It borrows heavily from the way that the Cordova Push Plugin works, so massive thanks to those guys, over here: https://github.com/phonegap-build/PushPlugin 10 | 11 | ... more to come! 12 | 13 | Thanks to @jhen0409 this is now available as an NPM module: 14 | npm install react-native-remote-push 15 | 16 | 17 | ## Examples 18 | ### Getting started 19 | Copy all of the files to your XCode directory, and add them to your project. Then, when you want to use the module, require the RemotePushIOS class, e.g. 20 | 21 | ``` 22 | var RemotePushIOS = require("./../RemotePush/RemotePushIOS"); 23 | ``` 24 | 25 | Note: you'll also need to add the following line to your AppDelegate.m: 26 | 27 | ``` 28 | #import "RemotePushDelegate.h" 29 | ``` 30 | 31 | And then also add this method (this is VERY important - your app won't start unless you do this) 32 | ``` 33 | - (id) init { 34 | return self; 35 | } 36 | ``` 37 | 38 | ### Registering For Push Notifications 39 | 40 | ``` 41 | RemotePushIOS.requestPermissions(function(err, data) { 42 | if (err) { 43 | console.log("Could not register for push"); 44 | } else { 45 | // On success, data will contain your device token. You're probably going to want to send this to your server. 46 | console.log(data.token); 47 | } 48 | }); 49 | ``` 50 | 51 | ### Adding a notification listener 52 | RemotePushIOS will listen out for remote notifications on startup or when your application is active. To receive these notifications in your code, you need to set a listener. Ideally you should set this on your top-level react component. 53 | 54 | You can add a listener in the following way: 55 | 56 | ``` 57 | componentWillMount: function() { 58 | // Add the listener when the component mounts 59 | RemotePushIOS.setListenerForNotifications(this.receiveRemoteNotification); 60 | }, 61 | 62 | receiveRemoteNotification: function(notification) { 63 | // Your code to run when the alert fires 64 | 65 | // Determine whether notification was received on startup. Note that it will return false if the app was running in the background. To determine if the app was open or not, you'll need to keep track of the appState separately. 66 | console.log(notification.startup); 67 | 68 | AlertIOS.alert( 69 | 'Notification received', 70 | notification.aps.alert, 71 | [ 72 | {text: 'OK', onPress: () => console.log('Ok pressed!')} 73 | ] 74 | ); 75 | 76 | } 77 | ``` 78 | 79 | The notification will contain an aps object with your alert as well as any custom payload data you have. 80 | 81 | 82 | -------------------------------------------------------------------------------- /RemotePushDelegate.h: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @interface AppDelegate(RemotePushDelegate) 4 | 5 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken; 6 | 7 | @end -------------------------------------------------------------------------------- /RemotePushDelegate.m: -------------------------------------------------------------------------------- 1 | #import "RemotePushDelegate.h" 2 | #import 3 | 4 | @implementation AppDelegate(RemotePushDelegate) 5 | 6 | NSDictionary *launchNotification; 7 | 8 | 9 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 10 | NSDictionary *userInfo = [NSDictionary dictionaryWithObject:deviceToken forKey:@"deviceToken"]; 11 | 12 | [[NSNotificationCenter defaultCenter] 13 | postNotificationName:@"registeredForRemoteNotifications" 14 | object:self userInfo:userInfo]; 15 | } 16 | 17 | + (void)load 18 | { 19 | Method original, swizzled; 20 | 21 | original = class_getInstanceMethod(self, @selector(init)); 22 | swizzled = class_getInstanceMethod(self, @selector(swizzled_init)); 23 | method_exchangeImplementations(original, swizzled); 24 | } 25 | 26 | - (AppDelegate *)swizzled_init 27 | { 28 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(createNotificationChecker:) name:@"UIApplicationDidFinishLaunchingNotification" object:nil]; 29 | 30 | // This actually calls the original init method over in AppDelegate. Equivilent to calling super 31 | // on an overrided method, this is not recursive, although it appears that way. neat huh? 32 | return [self swizzled_init]; 33 | } 34 | 35 | - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { 36 | // TODO Handle this on Manager side 37 | NSDictionary *userInfo = [NSDictionary dictionaryWithObject:error forKey:@"deviceToken"]; 38 | 39 | [[NSNotificationCenter defaultCenter] 40 | postNotificationName:@"registeredForRemoteNotificationsError" 41 | object:self userInfo:userInfo]; 42 | } 43 | 44 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { 45 | UIApplicationState appState = UIApplicationStateActive; 46 | if ([application respondsToSelector:@selector(applicationState)]) { 47 | appState = application.applicationState; 48 | } 49 | 50 | if (appState == UIApplicationStateActive) { 51 | [[NSNotificationCenter defaultCenter] 52 | postNotificationName:@"receivedRemoteNotification" 53 | object:self userInfo:userInfo]; 54 | 55 | } else { 56 | //save it for later 57 | launchNotification = userInfo; 58 | } 59 | } 60 | 61 | - (void)applicationDidBecomeActive:(UIApplication *)application { 62 | if (launchNotification) { 63 | [[NSNotificationCenter defaultCenter] 64 | postNotificationName:@"receivedRemoteNotification" 65 | object:self userInfo:launchNotification]; 66 | 67 | launchNotification = nil; 68 | } 69 | } 70 | 71 | - (void)createNotificationChecker:(NSNotification *)notification 72 | { 73 | if (notification) 74 | { 75 | NSDictionary *launchOptions = [notification userInfo]; 76 | if (launchOptions) { 77 | launchNotification = [launchOptions objectForKey: @"UIApplicationLaunchOptionsRemoteNotificationKey"]; 78 | 79 | [[NSNotificationCenter defaultCenter] 80 | postNotificationName:@"receivedRemoteNotificationOnStart" 81 | object:self userInfo:launchNotification]; 82 | } 83 | } 84 | } 85 | 86 | @end -------------------------------------------------------------------------------- /RemotePushIOS.js: -------------------------------------------------------------------------------- 1 | var React = require("react-native"); 2 | 3 | var { 4 | NativeModules, 5 | DeviceEventEmitter 6 | } = React; 7 | 8 | const REGISTERED_FOR_REMOTE = "registeredForRemoteNotifications"; 9 | const REGISTERED_FOR_REMOTE_ERROR = "registeredForRemoteNotificationsError"; 10 | const RECEIVED_REMOTE = "receivedRemoteNotification"; 11 | 12 | module.exports = { 13 | requestPermissions: function(callback) { 14 | NativeModules.RemotePushManager.requestPermissions(); 15 | 16 | DeviceEventEmitter.addListener( 17 | REGISTERED_FOR_REMOTE, function(notification) { 18 | callback(null, notification); 19 | } 20 | ); 21 | 22 | DeviceEventEmitter.addListener( 23 | REGISTERED_FOR_REMOTE_ERROR, function(error) { 24 | callback("Couldn't register for notifications"); 25 | } 26 | ) 27 | }, 28 | 29 | setListenerForNotifications: function(callback) { 30 | NativeModules.RemotePushManager.getStartupNotifications(function(err, startupNotification) { 31 | if (startupNotification) { 32 | startupNotification.startup = true; 33 | callback(startupNotification); 34 | } 35 | 36 | }); 37 | 38 | DeviceEventEmitter.addListener( 39 | RECEIVED_REMOTE, function(notification) { 40 | notification.startup = false; 41 | callback(notification); 42 | } 43 | ); 44 | } 45 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-remote-push", 3 | "version": "1.0.3", 4 | "description": "React Native Remote Push Notifications Component", 5 | "main": "RemotePushIOS.js", 6 | "scripts": { 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/darylrowland/react-native-remote-push.git" 11 | }, 12 | "author": "", 13 | "license": "", 14 | "bugs": { 15 | "url": "https://github.com/darylrowland/react-native-remote-push/issues" 16 | }, 17 | "peerDependencies": { 18 | "react-native": "*" 19 | } 20 | } 21 | --------------------------------------------------------------------------------