forked from noodlewerk/NWPusher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNWPushFeedback.m
148 lines (127 loc) · 5.07 KB
/
NWPushFeedback.m
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
//
// NWPushFeedback.m
// Pusher
//
// Copyright (c) 2012 noodlewerk. All rights reserved.
//
#import "NWPushFeedback.h"
#import "NWSSLConnection.h"
#import "NWSecTools.h"
#import "NWNotification.h"
static NSString * const NWSandboxPushHost = @"feedback.sandbox.push.apple.com";
static NSString * const NWPushHost = @"feedback.push.apple.com";
static NSUInteger const NWPushPort = 2196;
static NSUInteger const NWTokenMaxSize = 32;
@implementation NWPushFeedback
#pragma mark - Connecting
- (BOOL)connectWithIdentity:(NWIdentityRef)identity environment:(NWEnvironment)environment error:(NSError *__autoreleasing *)error
{
if (_connection) [_connection disconnect]; _connection = nil;
if (environment == NWEnvironmentAuto) environment = [NWSecTools environmentForIdentity:identity];
NSString *host = (environment == NWEnvironmentSandbox) ? NWSandboxPushHost : NWPushHost;
NWSSLConnection *connection = [[NWSSLConnection alloc] initWithHost:host port:NWPushPort identity:identity];
BOOL connected = [connection connectWithError:error];
if (!connected) {
return connected;
}
_connection = connection;
return YES;
}
- (BOOL)connectWithPKCS12Data:(NSData *)data password:(NSString *)password environment:(NWEnvironment)environment error:(NSError *__autoreleasing *)error
{
NWIdentityRef identity = [NWSecTools identityWithPKCS12Data:data password:password error:error];
if (!identity) {
return NO;
}
return [self connectWithIdentity:identity environment:environment error:error];
}
- (void)disconnect
{
[_connection disconnect]; _connection = nil;
}
+ (instancetype)connectWithIdentity:(NWIdentityRef)identity environment:(NWEnvironment)environment error:(NSError *__autoreleasing *)error
{
NWPushFeedback *feedback = [[NWPushFeedback alloc] init];
return identity && [feedback connectWithIdentity:identity environment:environment error:error] ? feedback : nil;
}
+ (instancetype)connectWithPKCS12Data:(NSData *)data password:(NSString *)password environment:(NWEnvironment)environment error:(NSError *__autoreleasing *)error
{
NWPushFeedback *feedback = [[NWPushFeedback alloc] init];
return data && [feedback connectWithPKCS12Data:data password:password environment:environment error:error] ? feedback : nil;
}
#pragma mark - Reading feedback
- (BOOL)readTokenData:(NSData **)token date:(NSDate **)date error:(NSError *__autoreleasing *)error
{
*token = nil;
*date = nil;
NSMutableData *data = [NSMutableData dataWithLength:sizeof(uint32_t) + sizeof(uint16_t) + NWTokenMaxSize];
NSUInteger length = 0;
BOOL read = [_connection read:data length:&length error:error];
if (!read || length == 0) {
return read;
}
if (length != data.length) {
return [NWErrorUtil noWithErrorCode:kNWErrorFeedbackLength reason:length error:error];
}
uint32_t time = 0;
[data getBytes:&time range:NSMakeRange(0, 4)];
*date = [NSDate dateWithTimeIntervalSince1970:htonl(time)];
uint16_t l = 0;
[data getBytes:&l range:NSMakeRange(4, 2)];
NSUInteger tokenLength = htons(l);
if (tokenLength != NWTokenMaxSize) {
return [NWErrorUtil noWithErrorCode:kNWErrorFeedbackTokenLength reason:tokenLength error:error];
}
*token = [data subdataWithRange:NSMakeRange(6, length - 6)];
return YES;
}
- (BOOL)readToken:(NSString **)token date:(NSDate **)date error:(NSError *__autoreleasing *)error
{
*token = nil;
NSData *data = nil;
BOOL read = [self readTokenData:&data date:date error:error];
if (!read) {
return read;
}
if (data) *token = [NWNotification hexFromData:data];
return YES;
}
- (NSArray *)readTokenDatePairsWithMax:(NSUInteger)max error:(NSError *__autoreleasing *)error
{
NSMutableArray *pairs = @[].mutableCopy;
for (NSUInteger i = 0; i < max; i++) {
NSString *token = nil;
NSDate *date = nil;
NSError *e = nil;
BOOL read = [self readToken:&token date:&date error:&e];
if (!read && e.code == kNWErrorReadClosedGraceful) {
break;
}
if (!read) {
if (error) *error = e;
return nil;
}
if (token && date) {
[pairs addObject:@[token, date]];
}
}
return pairs;
}
#pragma mark - Deprecated
- (BOOL)connectWithIdentity:(NWIdentityRef)identity error:(NSError *__autoreleasing *)error
{
return [self connectWithIdentity:identity environment:NWEnvironmentAuto error:error];
}
- (BOOL)connectWithPKCS12Data:(NSData *)data password:(NSString *)password error:(NSError *__autoreleasing *)error
{
return [self connectWithPKCS12Data:data password:password environment:NWEnvironmentAuto error:error];
}
+ (instancetype)connectWithIdentity:(NWIdentityRef)identity error:(NSError *__autoreleasing *)error
{
return [self connectWithIdentity:identity environment:NWEnvironmentAuto error:error];
}
+ (instancetype)connectWithPKCS12Data:(NSData *)data password:(NSString *)password error:(NSError *__autoreleasing *)error
{
return [self connectWithPKCS12Data:data password:password environment:NWEnvironmentAuto error:error];
}
@end