@@ -11,97 +11,122 @@ import Foundation
11
11
*/
12
12
public class NativePusher {
13
13
static let sharedInstance = NativePusher ( )
14
-
14
+
15
15
private static let PLATFORM_TYPE = " apns "
16
16
private let CLIENT_API_V1_ENDPOINT = " https://nativepushclient-cluster1.pusher.com/client_api/v1 "
17
-
17
+
18
18
private let URLSession = NSURLSession . sharedSession ( )
19
-
20
- // Identifies a Pusher app.
21
- // This app should have push notifications enabled.
19
+
20
+ /**
21
+ Identifies a Pusher app.
22
+ This app should have push notifications enabled.
23
+ */
22
24
private var pusherAppKey : String ? = nil
23
-
25
+
26
+
24
27
public func setPusherAppKey( pusherAppKey: String ) {
25
28
self . pusherAppKey = pusherAppKey
26
29
tryFlushOutbox ( )
27
30
}
28
-
29
- // The id issued to this app instance by Pusher.
30
- // We get it upon registration.
31
- // We use it to identify ourselves when subscribing/unsubscribing.
31
+
32
+ /**
33
+ The id issued to this app instance by Pusher.
34
+ We get it upon registration.
35
+ We use it to identify ourselves when subscribing/unsubscribing.
36
+ */
32
37
private var clientId : String ? = nil
33
-
34
- // Queued actions to perform when the client is registered.
35
- private var outbox : Array < ( String , SubscriptionChange ) > = [ ]
36
-
37
- // Normal clients should access the shared instance via Pusher.nativePusher().
38
- private init ( ) {
38
+
39
+ /**
40
+ Queued actions to perform when the client is registered.
41
+ */
42
+ private var outbox : [ ( String , SubscriptionChange ) ] = [ ]
43
+
44
+ /**
45
+ Normal clients should access the shared instance via Pusher.nativePusher().
46
+ */
47
+ private init ( ) { }
48
+
49
+ /**
50
+ Makes device token presentable to server
51
+
52
+ - parameter deviceToken: the deviceToken received when registering
53
+ to receive push notifications, as NSData
54
+
55
+ - returns: the deviceToken formatted as a String
56
+ */
57
+ private func deviceTokenToString( deviceToken: NSData ) -> String {
58
+ let characterSet : NSCharacterSet = NSCharacterSet ( charactersInString: " <> " )
59
+
60
+ let deviceTokenString : String = ( deviceToken. description as NSString )
61
+ . stringByTrimmingCharactersInSet ( characterSet )
62
+ . stringByReplacingOccurrencesOfString ( " " , withString: " " ) as String
63
+ return deviceTokenString
39
64
}
40
-
65
+
41
66
/**
42
67
Registers this app instance with Pusher for push notifications.
43
68
This must be done before we can subscribe to interests.
44
69
Registration happens asynchronously; any errors are reported by print statements.
70
+
71
+ - parameter deviceToken: the deviceToken received when registering
72
+ to receive push notifications, as NSData
45
73
*/
46
- public func register( deviceToken : NSData ) {
74
+ public func register( deviceToken: NSData ) {
47
75
let request = NSMutableURLRequest ( URL: NSURL ( string: CLIENT_API_V1_ENDPOINT + " /clients " ) !)
48
76
request. HTTPMethod = " POST "
49
77
let deviceTokenString = deviceTokenToString ( deviceToken)
50
-
51
- let params : [ String : AnyObject ] = [
78
+
79
+ let params : [ String : AnyObject ] = [
52
80
" platform_type " : NativePusher . PLATFORM_TYPE,
53
81
" token " : deviceTokenString
54
82
]
55
-
83
+
56
84
try ! request. HTTPBody = NSJSONSerialization . dataWithJSONObject ( params, options: [ ] )
57
85
request. addValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
58
-
86
+
59
87
let task = URLSession . dataTaskWithRequest ( request, completionHandler: { data, response, error in
60
- if let httpResponse =
61
- response as? NSHTTPURLResponse
62
- where (
63
- httpResponse. statusCode >= 200 &&
64
- httpResponse. statusCode < 300 )
65
- {
66
- // We expect to get a JSON response in the form:
67
- //
68
- // {
69
- // "id": string,
70
- // "pusher_app_key": string,
71
- // "platform_type": either "apns" or "gcm",
72
- // "token": string
73
- // }
74
- //
75
- // Currently, we only care about the "id" value, which is our new client id.
76
- // We store our id so that we can use it to subscribe/unsubscribe.
77
- if let json = try ! NSJSONSerialization . JSONObjectWithData ( data!, options: [ ] )
78
- as? Dictionary < String , AnyObject >
79
- {
80
- if let clientIdJson = json [ " id " ] {
81
- // There is a value at key "id".
82
- if let clientId = clientIdJson as? String {
83
- // Success. We got a string id. Squirrel it away.
84
- self . clientId = clientId
85
- self . tryFlushOutbox ( )
88
+ if let httpResponse = response as? NSHTTPURLResponse
89
+ where ( httpResponse. statusCode >= 200 && httpResponse. statusCode < 300 ) {
90
+ /**
91
+ We expect to get a JSON response in the form:
92
+
93
+ {
94
+ "id": string,
95
+ "pusher_app_key": string,
96
+ "platform_type": either "apns" or "gcm",
97
+ "token": string
98
+ }
99
+
100
+ Currently, we only care about the "id" value, which is our new client id.
101
+ We store our id so that we can use it to subscribe/unsubscribe.
102
+ */
103
+ if let json = try ! NSJSONSerialization . JSONObjectWithData ( data!, options: [ ] )
104
+ as? [ String : AnyObject ] {
105
+ if let clientIdJson = json [ " id " ] {
106
+ if let clientId = clientIdJson as? String {
107
+ self . clientId = clientId
108
+ self . tryFlushOutbox ( )
109
+ } else {
110
+ print ( " Value at \" id \" key in JSON response was not a string: " + String( json) )
111
+ }
112
+ } else {
113
+ print ( " No \" id \" key in JSON response: " + String( json) )
114
+ }
86
115
} else {
87
- print ( " Value at \" id \" key in JSON response was not a string: " + String( json ) )
116
+ print ( " Could not parse body as JSON object: " + String( data ) )
88
117
}
89
- } else {
90
- print ( " No \" id \" key in JSON response: " + String( json) )
91
- }
92
- } else {
93
- print ( " Could not parse body as JSON object: " + String( data) )
94
- }
95
118
} else {
96
119
print ( " Bad HTTP response: " + String( response) )
97
120
}
98
121
} )
99
-
122
+
100
123
task. resume ( )
101
124
}
102
-
125
+
103
126
/**
104
127
Subscribe to an interest with Pusher's Push Notification Service
128
+
129
+ - parameter interestName: the name of the interest you want to subscribe to
105
130
*/
106
131
public func subscribe( interestName: String ) {
107
132
outbox. append ( interestName, SubscriptionChange . Subscribe)
@@ -110,26 +135,43 @@ public class NativePusher {
110
135
111
136
/**
112
137
Unsubscribe from an interest with Pusher's Push Notification Service
138
+
139
+ - parameter interestName: the name of the interest you want to unsubscribe
140
+ from
113
141
*/
114
142
public func unsubscribe( interestName: String ) {
115
143
outbox. append ( interestName, SubscriptionChange . Unsubscribe)
116
144
tryFlushOutbox ( )
117
145
}
118
-
146
+
147
+ /**
148
+ Attempts to flush the outbox by making the appropriate requests to either
149
+ subscribe to or unsubscribe from an interest
150
+ */
119
151
private func tryFlushOutbox( ) {
120
152
switch ( self . pusherAppKey, self . clientId) {
121
153
case ( . Some( let pusherAppKey) , . Some( let clientId) ) :
122
154
if ( 0 < outbox. count) {
123
- let ( interest, change) = outbox. removeAtIndex ( 0 )
155
+ let ( interest, change) = outbox. removeAtIndex ( 0 )
124
156
modifySubscription ( pusherAppKey, clientId: clientId, interest: interest, change: change) {
125
157
self . tryFlushOutbox ( )
126
158
}
127
159
}
128
160
case _: break
129
161
}
130
162
}
131
-
132
- private func modifySubscription( pusherAppKey: String , clientId: String , interest: String , change: SubscriptionChange , callback: ( Void ) -> ( Void ) ) {
163
+
164
+ /**
165
+ Makes either a POST or DELETE request for a given interest
166
+
167
+ - parameter pusherAppKey: The app key for the Pusher app
168
+ - parameter clientId: The clientId returned by Pusher's server
169
+ - parameter interest: The name of the interest to be subscribed to /
170
+ unsunscribed from
171
+ - parameter change: Whether to subscribe or unsubscribe
172
+ - parameter callback: Callback to be called upon success
173
+ */
174
+ private func modifySubscription( pusherAppKey: String , clientId: String , interest: String , change: SubscriptionChange , callback: ( Void ) -> ( Void ) ) {
133
175
let url = " \( CLIENT_API_V1_ENDPOINT) /clients/ \( clientId) /interests/ \( interest) "
134
176
let request = NSMutableURLRequest ( URL: NSURL ( string: url) !)
135
177
switch ( change) {
@@ -138,14 +180,12 @@ public class NativePusher {
138
180
case . Unsubscribe:
139
181
request. HTTPMethod = " DELETE "
140
182
}
141
-
142
- let params : [ String : AnyObject ] = [
143
- " app_key " : pusherAppKey,
144
- ]
145
-
183
+
184
+ let params : [ String : AnyObject ] = [ " app_key " : pusherAppKey]
185
+
146
186
try ! request. HTTPBody = NSJSONSerialization . dataWithJSONObject ( params, options: [ ] )
147
187
request. addValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
148
-
188
+
149
189
let task = URLSession . dataTaskWithRequest (
150
190
request,
151
191
completionHandler: { data, response, error in
@@ -158,7 +198,7 @@ public class NativePusher {
158
198
callback ( )
159
199
}
160
200
)
161
-
201
+
162
202
task. resume ( )
163
203
}
164
204
}
0 commit comments