@@ -156,6 +156,15 @@ import Foundation
156156 addSubscriptionChangeToTaskQueue ( interestName: interestName, change: . subscribe)
157157 }
158158
159+ /**
160+ Subscribe to interests with Pusher's Push Notification Service
161+
162+ - parameter interests: the name of the interests you want to subscribe to
163+ */
164+ open func setSubscriptions( interests: Array < String > ) {
165+ addSubscriptionChangeToTaskQueue ( interests: interests, change: . setSubscriptions)
166+ }
167+
159168 /**
160169 Unsubscribe from an interest with Pusher's Push Notification Service
161170
@@ -186,91 +195,140 @@ import Foundation
186195 requestQueue. run ( )
187196 }
188197
198+ private func addSubscriptionChangeToTaskQueue( interests: Array < String > , change: SubscriptionChange ) {
199+ requestQueue. tasks += { _, next in
200+ self . modifySubscription (
201+ interests: interests,
202+ change: change,
203+ successCallback: next
204+ )
205+ }
206+
207+ requestQueue. run ( )
208+ }
209+
189210 /**
190211 Makes either a POST or DELETE request for a given interest
191-
192- - parameter pusherAppKey: The app key for the Pusher app
193- - parameter clientId: The clientId returned by Pusher's server
194- - parameter interest: The name of the interest to be subscribed to /
195- unsunscribed from
212+ - parameter interest: The name of the interest to be subscribed to / unsunscribed from
196213 - parameter change: Whether to subscribe or unsubscribe
197214 - parameter callback: Callback to be called upon success
198215 */
199216 private func modifySubscription( interest: String , change: SubscriptionChange , successCallback: @escaping ( Any ? ) -> Void ) {
200- guard pusherAppKey != nil && clientId != nil else {
201- self . delegate? . debugLog ? ( message: " pusherAppKey \( String ( describing: pusherAppKey) ) or clientId \( String ( describing: clientId) ) not set - waiting for both to be set " )
217+ guard
218+ let clientId = clientId,
219+ let pusherAppKey = pusherAppKey
220+ else {
221+ self . delegate? . debugLog ? ( message: " pusherAppKey or clientId not set - waiting for both to be set " )
202222 self . requestQueue. pauseAndResetCurrentTask ( )
203223 return
204224 }
205225
206- self . delegate? . debugLog ? ( message: " Attempt number: \( self . failedRequestAttempts + 1 ) of \( maxFailedRequestAttempts) " )
226+ let url = " \( CLIENT_API_V1_ENDPOINT) /clients/ \( clientId) /interests/ \( interest) "
227+ let params : [ String : Any ] = [ " app_key " : pusherAppKey]
228+ let request = self . setRequest ( url: url, params: params, change: change)
229+ self . modifySubscription ( interests: [ interest] , request: request, change: change, successCallback: successCallback)
230+ }
207231
208- let url = " \( CLIENT_API_V1_ENDPOINT) /clients/ \( clientId!) /interests/ \( interest) "
209- var request = URLRequest ( url: URL ( string: url) !)
210- request. httpMethod = change. httpMethod ( )
232+ /**
233+ Makes a PUT request for given interests
234+ - parameter interests: The name of the interests to be subscribed to
235+ - parameter change: Whether to subscribe or unsubscribe
236+ - parameter callback: Callback to be called upon success
237+ */
238+ private func modifySubscription( interests: Array < String > , change: SubscriptionChange , successCallback: @escaping ( Any ? ) -> Void ) {
239+ guard
240+ let clientId = clientId,
241+ let pusherAppKey = pusherAppKey
242+ else {
243+ self . delegate? . debugLog ? ( message: " pusherAppKey or clientId not set - waiting for both to be set " )
244+ self . requestQueue. pauseAndResetCurrentTask ( )
245+ return
246+ }
211247
212- let params : [ String : Any ] = [ " app_key " : pusherAppKey!]
213- try ! request. httpBody = JSONSerialization . data ( withJSONObject: params, options: [ ] )
248+ let url = " \( CLIENT_API_V1_ENDPOINT) /clients/ \( clientId) /interests/ "
249+ let params : [ String : Any ] = [ " app_key " : pusherAppKey, " interests " : interests]
250+ let request = self . setRequest ( url: url, params: params, change: change)
251+ self . modifySubscription ( interests: interests, request: request, change: change, successCallback: successCallback)
252+ }
214253
215- request. addValue ( " application/json " , forHTTPHeaderField : " Content-Type " )
216- request . addValue ( LIBRARY_NAME_AND_VERSION , forHTTPHeaderField : " X-Pusher-Library " )
254+ private func modifySubscription ( interests : Array < String > , request: URLRequest , change : SubscriptionChange , successCallback : @escaping ( Any ? ) -> Void ) {
255+ self . delegate ? . debugLog ? ( message : " Attempt number: \( self . failedRequestAttempts + 1 ) of \( maxFailedRequestAttempts ) " )
217256
218257 let task = URLSession . dataTask (
219258 with: request,
220259 completionHandler: { data, response, error in
221260 guard let httpResponse = response as? HTTPURLResponse ,
222- ( 200 <= httpResponse. statusCode && httpResponse. statusCode < 300 ) &&
223- error == nil
224- else {
225- self . failedRequestAttempts += 1
226-
227- if error != nil {
228- self . delegate? . debugLog ? ( message: " Error when trying to modify subscription to interest: \( String ( describing: error? . localizedDescription) ) " )
229- } else if data != nil && response != nil {
230- let responseBody = String ( data: data!, encoding: . utf8)
231- self . delegate? . debugLog ? ( message: " Bad response from server: \( response!) with body: \( String ( describing: responseBody) ) " )
232- } else {
233- self . delegate? . debugLog ? ( message: " Bad response from server when trying to modify subscription to interest: \( interest ) " )
234- }
235-
236- if self . failedRequestAttempts >= self . maxFailedRequestAttempts {
237- self . delegate? . debugLog ? ( message: " Max number of failed native service requests reached " )
238-
239- self . requestQueue. paused = true
240- } else {
241- self . delegate? . debugLog ? ( message: " Retrying subscription modification request for interest: \( interest ) " )
242- self . requestQueue. retry ( Double ( self . failedRequestAttempts * self . failedRequestAttempts) )
243- }
244-
245- return
261+ ( 200 <= httpResponse. statusCode && httpResponse. statusCode < 300 ) &&
262+ error == nil
263+ else {
264+ self . failedRequestAttempts += 1
265+
266+ if error != nil {
267+ self . delegate? . debugLog ? ( message: " Error when trying to modify subscription to interest(s) : \( String ( describing: error? . localizedDescription) ) " )
268+ } else if data != nil && response != nil {
269+ let responseBody = String ( data: data!, encoding: . utf8)
270+ self . delegate? . debugLog ? ( message: " Bad response from server: \( response!) with body: \( String ( describing: responseBody) ) " )
271+ } else {
272+ self . delegate? . debugLog ? ( message: " Bad response from server when trying to modify subscription to interest(s) : \( interests ) " )
273+ }
274+
275+ if self . failedRequestAttempts >= self . maxFailedRequestAttempts {
276+ self . delegate? . debugLog ? ( message: " Max number of failed native service requests reached " )
277+
278+ self . requestQueue. paused = true
279+ } else {
280+ self . delegate? . debugLog ? ( message: " Retrying subscription modification request for interest(s) : \( interests ) " )
281+ self . requestQueue. retry ( Double ( self . failedRequestAttempts * self . failedRequestAttempts) )
282+ }
283+
284+ return
246285 }
247286
248287 switch change {
249288 case . subscribe:
289+ guard let interest = interests. first else { return }
250290 self . delegate? . subscribedToInterest ? ( name: interest)
291+ case . setSubscriptions:
292+ self . delegate? . subscribedToInterests ? ( interests: interests)
251293 case . unsubscribe:
294+ guard let interest = interests. first else { return }
252295 self . delegate? . unsubscribedFromInterest ? ( name: interest)
253296 }
254297
255- self . delegate? . debugLog ? ( message: " Success making \( change. stringValue) to \( interest ) " )
298+ self . delegate? . debugLog ? ( message: " Success making \( change. stringValue) to \( interests ) " )
256299
257300 self . failedRequestAttempts = 0
258301 successCallback ( nil )
259- }
302+ }
260303 )
261304
262305 task. resume ( )
263306 }
307+
308+ private func setRequest( url: String , params: [ String : Any ] , change: SubscriptionChange ) -> URLRequest {
309+ var request = URLRequest ( url: URL ( string: url) !)
310+ request. httpMethod = change. httpMethod ( )
311+
312+ try ! request. httpBody = JSONSerialization . data ( withJSONObject: params, options: [ ] )
313+
314+ request. addValue ( " application/json " , forHTTPHeaderField: " Content-Type " )
315+ request. addValue ( LIBRARY_NAME_AND_VERSION, forHTTPHeaderField: " X-Pusher-Library " )
316+
317+ return request
318+ }
264319}
265320
266321internal enum SubscriptionChange {
267322 case subscribe
323+ case setSubscriptions
268324 case unsubscribe
269325
270326 internal func stringValue( ) -> String {
271327 switch self {
272328 case . subscribe:
273329 return " subscribe "
330+ case . setSubscriptions:
331+ return " setSubscriptions "
274332 case . unsubscribe:
275333 return " unsubscribe "
276334 }
@@ -280,6 +338,8 @@ internal enum SubscriptionChange {
280338 switch self {
281339 case . subscribe:
282340 return " POST "
341+ case . setSubscriptions:
342+ return " PUT "
283343 case . unsubscribe:
284344 return " DELETE "
285345 }
0 commit comments