├── Orbiter.xcworkspace ├── xcuserdata │ └── datou.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── contents.xcworkspacedata ├── Orbiter.podspec ├── LICENSE ├── README.md └── Orbiter ├── Orbiter.h └── Orbiter.m /Orbiter.xcworkspace/xcuserdata/datou.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/polydice/Orbiter/master/Orbiter.xcworkspace/xcuserdata/datou.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Orbiter.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 9 | 10 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Orbiter.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Orbiter' 3 | s.version = '2.1.0' 4 | s.license = 'MIT' 5 | s.summary = 'Push Notification Registration for iOS.' 6 | s.homepage = 'https://github.com/mattt/Orbiter' 7 | s.social_media_url = 'https://twitter.com/mattt' 8 | s.authors = { 'Mattt Thompson' => 'm@mattt.me' } 9 | s.source = { :git => 'https://github.com/mattt/Orbiter.git', :tag => '2.1.0' } 10 | s.source_files = 'Orbiter' 11 | 12 | s.requires_arc = true 13 | 14 | s.ios.deployment_target = '6.0' 15 | s.osx.deployment_target = '10.9' 16 | 17 | s.dependency 'AFNetworking' 18 | end 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Mattt Thompson (http://mattt.me/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Orbiter 2 | ======= 3 | **Push Notification Registration for iOS** 4 | 5 | For most iOS client / server applications, push notifications are negotiated through an intermediary service provider, such as [Urban Airship](http://urbanairship.com). The service provider exposes APIs to register a device token, as well as APIs to send push notifications to devices meeting some specified criteria. 6 | 7 | Orbiter is a small library that provides simple interfaces to register (and unregister) for Push Notifications with [Urban Airship](http://urbanairship.com) (without needing to include their SDK), as well as [Helios](http://helios.io) apps. 8 | 9 | > Orbiter is named for the [orbital space craft of the Space Shuttle program](http://en.wikipedia.org/wiki/Space_Shuttle_orbiter), which houses the flight crew and electronics used to communicate with mission control. 10 | 11 | > This project is part of a series of open source libraries covering the mission-critical aspects of an iOS app's infrastructure. Be sure to check out its sister projects: [GroundControl](https://github.com/mattt/GroundControl), [SkyLab](https://github.com/mattt/SkyLab), [CargoBay](https://github.com/mattt/CargoBay), and [houston](https://github.com/mattt/houston). 12 | 13 | ## Example Usage 14 | 15 | ### Urban Airship Registration 16 | 17 | ```objective-c 18 | - (void)application:(UIApplication *)application 19 | didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 20 | { 21 | [[UrbanAirshipOrbiter urbanAirshipManagerWithApplicationKey:@"..." applicationSecret:@"..."] registerDeviceToken:deviceToken withAlias:nil success:^(id responseObject) { 22 | NSLog(@"Registration Success: %@", responseObject); 23 | } failure:^(NSError *error) { 24 | NSLog(@"Registration Error: %@", error); 25 | }]; 26 | } 27 | ``` 28 | 29 | ### Helios Registration 30 | 31 | ```objective-c 32 | - (void)application:(UIApplication *)application 33 | didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 34 | { 35 | NSURL *serverURL = [NSURL URLWithString:@"http://raging-notification-3556.herokuapp.com/"]; 36 | Orbiter *orbiter = [[Orbiter alloc] initWithBaseURL:serverURL credential:nil]; 37 | [orbiter registerDeviceToken:deviceToken withAlias:nil success:^(id responseObject) { 38 | NSLog(@"Registration Success: %@", responseObject); 39 | } failure:^(NSError *error) { 40 | NSLog(@"Registration Error: %@", error); 41 | }]; 42 | } 43 | ``` 44 | 45 | ## Contact 46 | 47 | Mattt Thompson 48 | 49 | - http://github.com/mattt 50 | - http://twitter.com/mattt 51 | 52 | ## License 53 | 54 | Orbiter is available under the MIT license. See the LICENSE file for more info. 55 | -------------------------------------------------------------------------------- /Orbiter/Orbiter.h: -------------------------------------------------------------------------------- 1 | // Orbiter.h 2 | // 3 | // Copyright (c) 2012-2014 Mattt Thompson (http://mattt.me/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | /** 26 | Orbiter provides simple interfaces to register (and unregister) for Push Notifications with Urban Airship and Parse (without needing to include their SDKs), as well as Helios apps. 27 | */ 28 | @interface Orbiter : NSObject 29 | 30 | /** 31 | Initializes an Orbiter with the specified base URL and default credential. 32 | 33 | @param baseURL The base URL to be used to construct requests. 34 | @param credential The default credential to used for authentication challenges. 35 | */ 36 | - (id)initWithBaseURL:(NSURL *)baseURL 37 | credential:(NSURLCredential *)credential; 38 | 39 | ///---------------------------------- 40 | /// @name Registering / Unregistering 41 | ///---------------------------------- 42 | 43 | /** 44 | Register a given device token with specified alias to receive push notifications.. 45 | 46 | @param deviceToken The device token. This can be either an `NSString` or `NSData` representation. 47 | @param alias The alias to be associated with the device token, such as a username or email address. 48 | @param success A block to be executed after successfully registering the device token for push notifications. The block has no return value and takes a single argument: the response object returned by the web service. 49 | @param failure A block to be executed after failing to register the device token for push notifications. The block has no return value and takes a single argument: the error encountered. 50 | */ 51 | - (void)registerDeviceToken:(id)deviceToken 52 | withAlias:(NSString *)alias 53 | success:(void (^)(id responseObject))success 54 | failure:(void (^)(NSError *error))failure; 55 | 56 | /** 57 | Register a given device token with specified alias to receive push notifications. 58 | 59 | @param deviceToken The device token. This can be either an `NSString` or `NSData` representation. 60 | @param payload The associated data to be passed along with the request. 61 | @param success A block to be executed after successfully registering the device token for push notifications. The block has no return value and takes a single argument: the response object returned by the web service. 62 | @param failure A block to be executed after failing to register the device token for push notifications. The block has no return value and takes a single argument: the error encountered. 63 | */ 64 | - (void)registerDeviceToken:(id)deviceToken 65 | withPayload:(NSDictionary *)payload 66 | success:(void (^)(id responseObject))success 67 | failure:(void (^)(NSError *error))failure; 68 | 69 | /** 70 | Unregister a given device token with specified alias for push notifications. 71 | 72 | @param deviceToken The device token. This can be either an `NSString` or `NSData` representation. 73 | @param success A block to be executed after successfully unregistering the device token for push notifications. The block has no return value and takes no arguments. 74 | @param failure A block to be executed after failing to unregister the device token for push notifications. The block has no return value and takes a single argument: the error encountered. 75 | */ 76 | - (void)unregisterDeviceToken:(id)deviceToken 77 | success:(void (^)())success 78 | failure:(void (^)(NSError *error))failure; 79 | 80 | ///------------------------ 81 | /// @name Creating Requests 82 | ///------------------------ 83 | 84 | /** 85 | Creates a request for the registration of the specified device token with an optional payload. 86 | 87 | @param deviceToken The device token. This can be either an `NSString` or `NSData` representation. 88 | @param payload The associated data to be passed along with the request. 89 | 90 | @return The constructed push notification registration request. 91 | */ 92 | - (NSURLRequest *)requestForRegistrationOfDeviceToken:(id)deviceToken 93 | withPayload:(NSDictionary *)payload; 94 | 95 | /** 96 | Creates a request for the unregistration of the specified device token. 97 | 98 | @param deviceToken The device token. This can be either an `NSString` or `NSData` representation. 99 | 100 | @return The constructed push notification unregistration request. 101 | */ 102 | - (NSURLRequest *)requestForUnregistrationOfDeviceToken:(id)deviceToken; 103 | 104 | @end 105 | 106 | #pragma mark - 107 | 108 | /** 109 | A subclass of Orbiter for communicating with the Urban Airship push notification service. 110 | 111 | @see http://docs.urbanairship.com 112 | */ 113 | @interface UrbanAirshipOrbiter : Orbiter 114 | 115 | /** 116 | Initializes an Urban Airship Orbiter with the specified API credentials. 117 | 118 | @param key Urban Airship generated string identifying the app setup. (e.g. -XurP5jfDUF1w01U9UUbNN) 119 | @param secret Urban Airship generated string identifying the app setup secret. (e.g. kFixrCslEgTUQHBOzXFFVN) 120 | */ 121 | + (instancetype)urbanAirshipManagerWithApplicationKey:(NSString *)key 122 | applicationSecret:(NSString *)secret; 123 | 124 | /** 125 | Register a given device token to receive push notifications. 126 | 127 | @param deviceToken The device token. This can be either an `NSString` or `NSData` representation. 128 | @param alias The alias to be associated with the device token, such as a username or email address. 129 | @param badge The badge count. 130 | @param tags The tags to be associated with the registration 131 | @param timeZone The time zone for this device 132 | @param quietTimeStartComponents The date components representing the daily start time for not receiving notifications. 133 | @param quietTimeEndComponents The date components representing the daily end time for not receiving notifications. 134 | @param success A block to be executed after successfully registering the device token for push notifications. The block has no return value and takes a single argument: the response object returned by the web service. 135 | @param failure A block to be executed after failing to register the device token for push notifications. The block has no return value and takes a single argument: the error encountered. 136 | */ 137 | - (void)registerDeviceToken:(id)deviceToken 138 | withAlias:(NSString *)alias 139 | badge:(NSNumber *)badge 140 | tags:(NSSet *)tags 141 | timeZone:(NSTimeZone *)timeZone 142 | quietTimeStart:(NSDateComponents *)quietTimeStartComponents 143 | quietTimeEnd:(NSDateComponents *)quietTimeEndComponents 144 | success:(void (^)(id responseObject))success 145 | failure:(void (^)(NSError *error))failure; 146 | 147 | @end 148 | 149 | #pragma mark - 150 | 151 | /** 152 | A subclass of Orbiter for communicating with the Parse push notification service. 153 | 154 | @see https://parse.com/docs/push_guide 155 | */ 156 | @interface ParseOrbiter : Orbiter 157 | 158 | /** 159 | Initializes a Parse Orbiter with the specified API credentials. 160 | 161 | @param applicationID The application identifier. 162 | @param RESTAPIKey The REST API key. 163 | */ 164 | + (instancetype)parseManagerWithApplicationID:(NSString *)applicationID 165 | RESTAPIKey:(NSString *)RESTAPIKey; 166 | 167 | /** 168 | Register a given device token to receive push notifications. 169 | 170 | @param deviceToken The device token. This can be either an `NSString` or `NSData` representation. 171 | @param alias The alias to be associated with the device token, such as a username or email address. 172 | @param badge The badge count. 173 | @param channels The channels to be associated with the registration 174 | @param success A block to be executed after successfully registering the device token for push notifications. The block has no return value and takes a single argument: the response object returned by the web service. 175 | @param failure A block to be executed after failing to register the device token for push notifications. The block has no return value and takes a single argument: the error encountered. 176 | */ 177 | - (void)registerDeviceToken:(id)deviceToken 178 | withAlias:(NSString *)alias 179 | badge:(NSNumber *)badge 180 | channels:(NSSet *)channels 181 | timeZone:(NSTimeZone *)timeZone 182 | success:(void (^)(id responseObject))success 183 | failure:(void (^)(NSError *error))failure; 184 | 185 | @end 186 | -------------------------------------------------------------------------------- /Orbiter/Orbiter.m: -------------------------------------------------------------------------------- 1 | // Orbiter.m 2 | // 3 | // Copyright (c) 2012-2014 Mattt Thompson (http://mattt.me/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "Orbiter.h" 24 | #import 25 | 26 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 27 | #import 28 | #endif 29 | 30 | static NSString * AFNormalizedDeviceTokenStringWithDeviceToken(id deviceToken) { 31 | if ([deviceToken isKindOfClass:[NSData class]]) { 32 | const unsigned *bytes = [(NSData *)deviceToken bytes]; 33 | return [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x", ntohl(bytes[0]), ntohl(bytes[1]), ntohl(bytes[2]), ntohl(bytes[3]), ntohl(bytes[4]), ntohl(bytes[5]), ntohl(bytes[6]), ntohl(bytes[7])]; 34 | } else { 35 | return [[[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""]; 36 | } 37 | } 38 | 39 | @interface Orbiter () 40 | @property (nonatomic, weak) NSString *tokenType; 41 | @property (readwrite, nonatomic, strong) AFHTTPSessionManager *SessionManager; 42 | @end 43 | 44 | @implementation Orbiter 45 | 46 | #ifdef __CORELOCATION__ 47 | + (CLLocationManager *)sharedLocationManager { 48 | static CLLocationManager *_sharedLocationManager = nil; 49 | static dispatch_once_t onceToken; 50 | dispatch_once(&onceToken, ^{ 51 | if ([CLLocationManager locationServicesEnabled]) { 52 | _sharedLocationManager = [[CLLocationManager alloc] init]; 53 | _sharedLocationManager.desiredAccuracy = kCLLocationAccuracyKilometer; 54 | [_sharedLocationManager startUpdatingLocation]; 55 | } 56 | }); 57 | 58 | return _sharedLocationManager; 59 | } 60 | #endif 61 | 62 | - (id)initWithBaseURL:(NSURL *)baseURL 63 | credential:(NSURLCredential *)credential 64 | { 65 | self = [super init]; 66 | if (!self) { 67 | return nil; 68 | } 69 | 70 | self.SessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL]; 71 | 72 | AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer]; 73 | [requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 74 | self.SessionManager.requestSerializer = requestSerializer; 75 | 76 | self.SessionManager.responseSerializer = [AFHTTPResponseSerializer serializer]; 77 | [self.SessionManager.responseSerializer setAcceptableContentTypes:[NSSet setWithObjects:@"application/json", @"text/plain", nil]]; 78 | 79 | return self; 80 | } 81 | 82 | - (NSURLRequest *)requestForRegistrationOfDeviceToken:(id)deviceToken 83 | withPayload:(NSDictionary *)payload 84 | { 85 | NSString *path = [NSString stringWithFormat:@"devices/%@", AFNormalizedDeviceTokenStringWithDeviceToken(deviceToken)]; 86 | NSString *urlString = [[self.SessionManager.baseURL URLByAppendingPathComponent:path] absoluteString]; 87 | return [self.SessionManager.requestSerializer requestWithMethod:@"PUT" URLString:urlString parameters:payload error:nil]; 88 | } 89 | 90 | - (NSURLRequest *)requestForUnregistrationOfDeviceToken:(id)deviceToken { 91 | NSString *path = [NSString stringWithFormat:@"devices/%@", AFNormalizedDeviceTokenStringWithDeviceToken(deviceToken)]; 92 | NSString *urlString = [[self.SessionManager.baseURL URLByAppendingPathComponent:path] absoluteString]; 93 | return [self.SessionManager.requestSerializer requestWithMethod:@"DELETE" URLString:urlString parameters:nil error:nil]; 94 | } 95 | 96 | #pragma mark - 97 | 98 | - (void)registerDeviceToken:(NSString *)deviceToken 99 | withAlias:(NSString *)alias 100 | success:(void (^)(id responseObject))success 101 | failure:(void (^)(NSError *error))failure 102 | { 103 | NSMutableDictionary *mutablePayload = [NSMutableDictionary dictionary]; 104 | [mutablePayload setValue:[[NSLocale currentLocale] localeIdentifier] forKey:@"locale"]; 105 | [mutablePayload setValue:[[NSLocale preferredLanguages] objectAtIndex:0] forKey:@"language"]; 106 | [mutablePayload setValue:[[NSTimeZone defaultTimeZone] name] forKey:@"timezone"]; 107 | 108 | #ifdef __CORELOCATION__ 109 | CLLocation *location = [[[self class] sharedLocationManager] location]; 110 | if (location) { 111 | [mutablePayload setValue:[[NSNumber numberWithDouble:location.coordinate.latitude] stringValue] forKey:@"lat"]; 112 | [mutablePayload setValue:[[NSNumber numberWithDouble:location.coordinate.longitude] stringValue] forKey:@"lng"]; 113 | } 114 | #endif 115 | 116 | NSMutableSet *mutableTags = [NSMutableSet set]; 117 | [mutableTags addObject:[NSString stringWithFormat:@"v%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]]; 118 | 119 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 120 | [mutableTags addObject:[[UIDevice currentDevice] model]]; 121 | [mutableTags addObject:[NSString stringWithFormat:@"%@ %@", [[UIDevice currentDevice] systemName], [[UIDevice currentDevice] systemVersion]]]; 122 | #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) 123 | [mutableTags addObject:[[NSProcessInfo processInfo] operatingSystemVersionString]]; 124 | #endif 125 | 126 | [mutablePayload setValue:[mutableTags allObjects] forKey:@"tags"]; 127 | 128 | if (alias) { 129 | [mutablePayload setValue:alias forKey:@"alias"]; 130 | } 131 | 132 | [self registerDeviceToken:deviceToken withPayload:mutablePayload success:success failure:failure]; 133 | } 134 | 135 | - (void)registerDeviceToken:(NSString *)deviceToken 136 | withPayload:(NSDictionary *)payload 137 | success:(void (^)(id responseObject))success 138 | failure:(void (^)(NSError *error))failure 139 | { 140 | NSURLRequest *request = [self requestForRegistrationOfDeviceToken:deviceToken withPayload:payload]; 141 | 142 | NSURLSessionDataTask *dataTask = [self.SessionManager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { 143 | if (error && failure) { 144 | failure(error); 145 | }else{ 146 | if (success) { 147 | success(responseObject); 148 | } 149 | } 150 | }]; 151 | 152 | [dataTask resume]; 153 | } 154 | 155 | - (void)unregisterDeviceToken:(NSString *)deviceToken 156 | success:(void (^)())success 157 | failure:(void (^)(NSError *error))failure 158 | { 159 | NSURLRequest *request = [self requestForUnregistrationOfDeviceToken:deviceToken]; 160 | 161 | NSURLSessionDataTask *dataTask = [self.SessionManager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { 162 | if (error && failure) { 163 | failure(error); 164 | }else{ 165 | if (success) { 166 | success(responseObject); 167 | } 168 | } 169 | }]; 170 | [dataTask resume]; 171 | } 172 | 173 | @end 174 | 175 | #pragma mark - 176 | 177 | static NSString * const kUrbanAirshipAPIBaseURLString = @"https://go.urbanairship.com/api/"; 178 | 179 | @implementation UrbanAirshipOrbiter 180 | 181 | + (instancetype)urbanAirshipManagerWithApplicationKey:(NSString *)key 182 | applicationSecret:(NSString *)secret 183 | { 184 | return [[UrbanAirshipOrbiter alloc] initWithBaseURL:[NSURL URLWithString:kUrbanAirshipAPIBaseURLString] credential:[NSURLCredential credentialWithUser:key password:secret persistence:NSURLCredentialPersistenceForSession]]; 185 | } 186 | 187 | #pragma mark - Orbiter 188 | 189 | - (id)initWithBaseURL:(NSURL *)baseURL 190 | credential:(NSURLCredential *)credential 191 | { 192 | self = [super initWithBaseURL:baseURL credential:credential]; 193 | if (!self) { 194 | return nil; 195 | } 196 | 197 | [self.SessionManager.requestSerializer setValue:@"*/*" forHTTPHeaderField:@"Accept"]; 198 | 199 | return self; 200 | } 201 | 202 | - (NSURLRequest *)requestForRegistrationOfDeviceToken:(id)deviceToken 203 | withPayload:(NSDictionary *)payload 204 | { 205 | NSString *path = [NSString stringWithFormat:@"device_tokens/%@", AFNormalizedDeviceTokenStringWithDeviceToken(deviceToken)]; 206 | NSString *urlString = [[self.SessionManager.baseURL URLByAppendingPathComponent:path] absoluteString]; 207 | return [self.SessionManager.requestSerializer requestWithMethod:@"PUT" URLString:urlString parameters:payload error:nil]; 208 | } 209 | 210 | - (NSURLRequest *)requestForUnregistrationOfDeviceToken:(id)deviceToken 211 | { 212 | NSString *path = [NSString stringWithFormat:@"device_tokens/%@", AFNormalizedDeviceTokenStringWithDeviceToken(deviceToken)]; 213 | NSString *urlString = [[self.SessionManager.baseURL URLByAppendingPathComponent:path] absoluteString]; 214 | return [self.SessionManager.requestSerializer requestWithMethod:@"DELETE" URLString:urlString parameters:nil error:nil]; 215 | } 216 | 217 | - (void)registerDeviceToken:(NSString *)deviceToken 218 | withAlias:(NSString *)alias 219 | success:(void (^)(id responseObject))success 220 | failure:(void (^)(NSError *error))failure 221 | { 222 | [self registerDeviceToken:deviceToken withAlias:alias badge:nil tags:nil timeZone:[NSTimeZone defaultTimeZone] quietTimeStart:nil quietTimeEnd:nil success:success failure:failure]; 223 | } 224 | 225 | - (void)registerDeviceToken:(NSString *)deviceToken 226 | withAlias:(NSString *)alias 227 | badge:(NSNumber *)badge 228 | tags:(NSSet *)tags 229 | timeZone:(NSTimeZone *)timeZone 230 | quietTimeStart:(NSDateComponents *)quietTimeStartComponents 231 | quietTimeEnd:(NSDateComponents *)quietTimeEndComponents 232 | success:(void (^)(id responseObject))success 233 | failure:(void (^)(NSError *error))failure 234 | { 235 | NSMutableDictionary *mutablePayload = [NSMutableDictionary dictionary]; 236 | if (alias) { 237 | [mutablePayload setValue:alias forKey:@"alias"]; 238 | } 239 | 240 | if (badge) { 241 | [mutablePayload setValue:[badge stringValue] forKey:@"badge"]; 242 | } 243 | 244 | if (tags && [tags count] > 0) { 245 | [mutablePayload setValue:[tags allObjects] forKey:@"tags"]; 246 | } 247 | 248 | if (quietTimeStartComponents && quietTimeEndComponents) { 249 | NSMutableDictionary *mutableQuietTimePayload = [NSMutableDictionary dictionary]; 250 | [mutableQuietTimePayload setValue:[NSString stringWithFormat:@"%02ld:%02ld", (long)[quietTimeStartComponents hour], (long)[quietTimeStartComponents minute]] forKey:@"start"]; 251 | [mutableQuietTimePayload setValue:[NSString stringWithFormat:@"%02ld:%02ld", (long)[quietTimeEndComponents hour], (long)[quietTimeEndComponents minute]] forKey:@"end"]; 252 | [mutablePayload setValue:mutableQuietTimePayload forKey:@"quiettime"]; 253 | } 254 | 255 | if (timeZone) { 256 | [mutablePayload setValue:[timeZone name] forKey:@"tz"]; 257 | } 258 | 259 | [self registerDeviceToken:deviceToken withPayload:mutablePayload success:success failure:failure]; 260 | } 261 | 262 | @end 263 | 264 | #pragma mark - 265 | 266 | static NSString * const kParseAPIBaseURLString = @"https://api.parse.com/1/"; 267 | 268 | @implementation ParseOrbiter 269 | 270 | + (instancetype)parseManagerWithApplicationID:(NSString *)applicationID 271 | RESTAPIKey:(NSString *)RESTAPIKey 272 | { 273 | ParseOrbiter *orbiter = [[ParseOrbiter alloc] initWithBaseURL:[NSURL URLWithString:kParseAPIBaseURLString] credential:nil]; 274 | [orbiter.SessionManager.requestSerializer setValue:applicationID forHTTPHeaderField:@"X-Parse-Application-Id"]; 275 | [orbiter.SessionManager.requestSerializer setValue:RESTAPIKey forHTTPHeaderField:@"X-Parse-REST-API-Key"]; 276 | 277 | return orbiter; 278 | } 279 | 280 | #pragma mark - Orbiter 281 | 282 | - (NSURLRequest *)requestForRegistrationOfDeviceToken:(__unused id)deviceToken 283 | withPayload:(NSDictionary *)payload 284 | { 285 | NSString *path = [[self.SessionManager.baseURL URLByAppendingPathComponent:@"installations"] absoluteString]; 286 | return [self.SessionManager.requestSerializer requestWithMethod:@"POST" URLString:path parameters:payload error:nil]; 287 | } 288 | 289 | - (NSURLRequest *)requestForUnregistrationOfDeviceToken:(__unused id)deviceToken { 290 | return nil; 291 | } 292 | 293 | 294 | - (void)registerDeviceToken:(id)deviceToken 295 | withAlias:(NSString *)alias 296 | success:(void (^)(id))success 297 | failure:(void (^)(NSError *))failure 298 | { 299 | [self registerDeviceToken:deviceToken withAlias:alias badge:nil channels:nil timeZone:[NSTimeZone defaultTimeZone] success:success failure:failure]; 300 | } 301 | 302 | - (void)registerDeviceToken:(id)deviceToken 303 | withAlias:(NSString *)alias 304 | badge:(NSNumber *)badge 305 | channels:(NSSet *)channels 306 | timeZone:(NSTimeZone *)timeZone 307 | success:(void (^)(id responseObject))success 308 | failure:(void (^)(NSError *error))failure 309 | { 310 | NSMutableDictionary *mutablePayload = [NSMutableDictionary dictionary]; 311 | [mutablePayload setValue:@"ios" forKey:@"deviceType"]; 312 | [mutablePayload setValue:AFNormalizedDeviceTokenStringWithDeviceToken(deviceToken) forKey:@"deviceToken"]; 313 | 314 | if (badge) { 315 | [mutablePayload setValue:[badge stringValue] forKey:@"badge"]; 316 | } 317 | 318 | if (channels && [channels count] > 0) { 319 | [mutablePayload setValue:[channels allObjects] forKey:@"channels"]; 320 | } 321 | 322 | if (timeZone) { 323 | [mutablePayload setValue:[timeZone name] forKey:@"timeZone"]; 324 | } 325 | 326 | [self registerDeviceToken:deviceToken withPayload:mutablePayload success:success failure:failure]; 327 | } 328 | 329 | - (void)unregisterDeviceToken:(__unused id)deviceToken 330 | success:(__unused void (^)())success 331 | failure:(__unused void (^)(NSError *))failure 332 | { 333 | [NSException raise:@"Unregistraion not supported by Parse API" format:nil]; 334 | } 335 | 336 | @end 337 | --------------------------------------------------------------------------------