This repository was archived by the owner on Sep 15, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathSharingServiceRemote.swift
More file actions
606 lines (529 loc) · 27.9 KB
/
Copy pathSharingServiceRemote.swift
File metadata and controls
606 lines (529 loc) · 27.9 KB
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
import Foundation
@_implementationOnly import NSObject_SafeExpectations
/// SharingServiceRemote is responsible for wrangling the REST API calls related to
/// publiczice services, publicize connections, and keyring connections.
///
open class SharingServiceRemote: ServiceRemoteWordPressComREST {
// MARK: - Helper methods
/// Returns an error message to use is the API returns an unexpected result.
///
/// - Parameter operation: The NSHTTPURLResponse that returned the unexpected result.
///
/// - Returns: An `NSError` object.
///
@objc func errorForUnexpectedResponse(_ httpResponse: HTTPURLResponse?) -> NSError {
let failureReason = "The request returned an unexpected type."
let domain = "org.wordpress.sharing-management"
let code = 0
var urlString = "unknown"
if let unwrappedURL = httpResponse?.url?.absoluteString {
urlString = unwrappedURL
}
let userInfo = [
"requestURL": urlString,
NSLocalizedDescriptionKey: failureReason,
NSLocalizedFailureReasonErrorKey: failureReason
]
return NSError(domain: domain, code: code, userInfo: userInfo)
}
// MARK: - Publicize Related Methods
/// Fetches the list of Publicize services.
///
/// - Parameters:
/// - success: An optional success block accepting an array of `RemotePublicizeService` objects.
/// - failure: An optional failure block accepting an `NSError` argument.
///
@objc open func getPublicizeServices(_ success: (([RemotePublicizeService]) -> Void)?, failure: ((NSError?) -> Void)?) {
let endpoint = "meta/external-services"
let path = self.path(forEndpoint: endpoint, withVersion: ._1_1)
let params = ["type": "publicize"]
wordPressComRESTAPI.get(path, parameters: params as [String: AnyObject]?) { responseObject, httpResponse in
guard let responseDict = responseObject as? NSDictionary else {
failure?(self.errorForUnexpectedResponse(httpResponse))
return
}
success?(self.remotePublicizeServicesFromDictionary(responseDict))
} failure: { error, _ in
failure?(error as NSError)
}
}
/// Fetches the list of Publicize services for a specified siteID.
///
/// - Parameters:
/// - siteID: The WordPress.com ID of the site.
/// - success: An optional success block accepting an array of `RemotePublicizeService` objects.
/// - failure: An optional failure block accepting an `NSError` argument.
@objc open func getPublicizeServices(for siteID: NSNumber,
success: (([RemotePublicizeService]) -> Void)?,
failure: ((NSError?) -> Void)?) {
let path = path(forEndpoint: "sites/\(siteID)/external-services", withVersion: ._2_0)
let params = ["type": "publicize" as AnyObject]
wordPressComRESTAPI.get(
path,
parameters: params,
success: { response, httpResponse in
guard let responseDict = response as? NSDictionary else {
failure?(self.errorForUnexpectedResponse(httpResponse))
return
}
success?(self.remotePublicizeServicesFromDictionary(responseDict))
},
failure: { error, _ in
failure?(error as NSError)
}
)
}
/// Fetches the current user's list of keyring connections.
///
/// - Parameters:
/// - success: An optional success block accepting an array of `KeyringConnection` objects.
/// - failure: An optional failure block accepting an `NSError` argument.
///
@objc open func getKeyringConnections(_ success: (([KeyringConnection]) -> Void)?, failure: ((NSError?) -> Void)?) {
let endpoint = "me/keyring-connections"
let path = self.path(forEndpoint: endpoint, withVersion: ._1_1)
wordPressComRESTAPI.get(path,
parameters: nil,
success: { responseObject, httpResponse in
guard let onSuccess = success else {
return
}
guard let responseDict = responseObject as? NSDictionary else {
failure?(self.errorForUnexpectedResponse(httpResponse))
return
}
let connections = responseDict.array(forKey: ConnectionDictionaryKeys.connections) ?? []
let keyringConnections: [KeyringConnection] = connections.map { (dict) -> KeyringConnection in
let conn = KeyringConnection()
let dict = dict as AnyObject
let externalUsers = dict.array(forKey: ConnectionDictionaryKeys.additionalExternalUsers) ?? []
conn.additionalExternalUsers = self.externalUsersForKeyringConnection(externalUsers as NSArray)
conn.dateExpires = WPKitDateUtils.date(fromISOString: dict.string(forKey: ConnectionDictionaryKeys.expires))
conn.dateIssued = WPKitDateUtils.date(fromISOString: dict.string(forKey: ConnectionDictionaryKeys.issued))
conn.externalDisplay = dict.string(forKey: ConnectionDictionaryKeys.externalDisplay) ?? conn.externalDisplay
conn.externalID = dict.string(forKey: ConnectionDictionaryKeys.externalID) ?? conn.externalID
conn.externalName = dict.string(forKey: ConnectionDictionaryKeys.externalName) ?? conn.externalName
conn.externalProfilePicture = dict.string(forKey: ConnectionDictionaryKeys.externalProfilePicture) ?? conn.externalProfilePicture
conn.keyringID = dict.number(forKey: ConnectionDictionaryKeys.ID) ?? conn.keyringID
conn.label = dict.string(forKey: ConnectionDictionaryKeys.label) ?? conn.label
conn.refreshURL = dict.string(forKey: ConnectionDictionaryKeys.refreshURL) ?? conn.refreshURL
conn.status = dict.string(forKey: ConnectionDictionaryKeys.status) ?? conn.status
conn.service = dict.string(forKey: ConnectionDictionaryKeys.service) ?? conn.service
conn.type = dict.string(forKey: ConnectionDictionaryKeys.type) ?? conn.type
conn.userID = dict.number(forKey: ConnectionDictionaryKeys.userID) ?? conn.userID
return conn
}
onSuccess(keyringConnections)
},
failure: { error, _ in
failure?(error as NSError)
})
}
/// Creates KeyringConnectionExternalUser instances from the past array of
/// external user dictionaries.
///
/// - Parameters:
/// - externalUsers: An array of NSDictionaries where each NSDictionary represents a KeyringConnectionExternalUser
///
/// - Returns: An array of KeyringConnectionExternalUser instances.
///
private func externalUsersForKeyringConnection(_ externalUsers: NSArray) -> [KeyringConnectionExternalUser] {
let arr: [KeyringConnectionExternalUser] = externalUsers.map { (dict) -> KeyringConnectionExternalUser in
let externalUser = KeyringConnectionExternalUser()
externalUser.externalID = (dict as AnyObject).string(forKey: ConnectionDictionaryKeys.externalID) ?? externalUser.externalID
externalUser.externalName = (dict as AnyObject).string(forKey: ConnectionDictionaryKeys.externalName) ?? externalUser.externalName
externalUser.externalProfilePicture = (dict as AnyObject).string(forKey: ConnectionDictionaryKeys.externalProfilePicture) ?? externalUser.externalProfilePicture
externalUser.externalCategory = (dict as AnyObject).string(forKey: ConnectionDictionaryKeys.externalCategory) ?? externalUser.externalCategory
return externalUser
}
return arr
}
/// Fetches the current user's list of Publicize connections for the specified site's ID.
///
/// - Parameters:
/// - siteID: The WordPress.com ID of the site.
/// - success: An optional success block accepting an array of `RemotePublicizeConnection` objects.
/// - failure: An optional failure block accepting an `NSError` argument.
///
@objc open func getPublicizeConnections(_ siteID: NSNumber, success: (([RemotePublicizeConnection]) -> Void)?, failure: ((NSError?) -> Void)?) {
let endpoint = "sites/\(siteID)/publicize-connections"
let path = self.path(forEndpoint: endpoint, withVersion: ._1_1)
wordPressComRESTAPI.get(path,
parameters: nil,
success: { responseObject, httpResponse in
guard let onSuccess = success else {
return
}
guard let responseDict = responseObject as? NSDictionary else {
failure?(self.errorForUnexpectedResponse(httpResponse))
return
}
let connections = responseDict.array(forKey: ConnectionDictionaryKeys.connections) ?? []
let publicizeConnections: [RemotePublicizeConnection] = connections.compactMap { (dict) -> RemotePublicizeConnection? in
let conn = self.remotePublicizeConnectionFromDictionary(dict as! NSDictionary)
return conn
}
onSuccess(publicizeConnections)
},
failure: { error, _ in
failure?(error as NSError)
})
}
/// Create a new Publicize connection bweteen the specified blog and
/// the third-pary service represented by the keyring.
///
/// - Parameters:
/// - siteID: The WordPress.com ID of the site.
/// - keyringConnectionID: The ID of the third-party site's keyring connection.
/// - success: An optional success block accepting a `RemotePublicizeConnection` object.
/// - failure: An optional failure block accepting an `NSError` argument.
///
@objc open func createPublicizeConnection(_ siteID: NSNumber,
keyringConnectionID: NSNumber,
externalUserID: String?,
success: ((RemotePublicizeConnection) -> Void)?,
failure: ((NSError) -> Void)?) {
let endpoint = "sites/\(siteID)/publicize-connections/new"
let path = self.path(forEndpoint: endpoint, withVersion: ._1_1)
var parameters: [String: AnyObject] = [PublicizeConnectionParams.keyringConnectionID: keyringConnectionID]
if let userID = externalUserID {
parameters[PublicizeConnectionParams.externalUserID] = userID as AnyObject?
}
wordPressComRESTAPI.post(path,
parameters: parameters,
success: { responseObject, httpResponse in
guard let onSuccess = success else {
return
}
guard let responseDict = responseObject as? NSDictionary,
let conn = self.remotePublicizeConnectionFromDictionary(responseDict) else {
failure?(self.errorForUnexpectedResponse(httpResponse))
return
}
onSuccess(conn)
},
failure: { error, _ in
failure?(error as NSError)
})
}
/// Update the shared status of the specified publicize connection
///
/// - Parameters:
/// - connectionID: The ID of the publicize connection.
/// - externalID: The connection's externalID. Pass `nil` if the keyring
/// connection's default external ID should be used. Otherwise pass the external
/// ID of one if the keyring connection's `additionalExternalUsers`.
/// - siteID: The WordPress.com ID of the site.
/// - success: An optional success block accepting no arguments.
/// - failure: An optional failure block accepting an `NSError` argument.
///
@objc open func updatePublicizeConnectionWithID(_ connectionID: NSNumber,
externalID: String?,
forSite siteID: NSNumber,
success: ((RemotePublicizeConnection) -> Void)?,
failure: ((NSError?) -> Void)?) {
let endpoint = "sites/\(siteID)/publicize-connections/\(connectionID)"
let path = self.path(forEndpoint: endpoint, withVersion: ._1_1)
let externalUserID = (externalID == nil) ? "false" : externalID!
let parameters = [
PublicizeConnectionParams.externalUserID: externalUserID
]
wordPressComRESTAPI.post(path,
parameters: parameters as [String: AnyObject]?,
success: { responseObject, httpResponse in
guard let onSuccess = success else {
return
}
guard let responseDict = responseObject as? NSDictionary,
let conn = self.remotePublicizeConnectionFromDictionary(responseDict) else {
failure?(self.errorForUnexpectedResponse(httpResponse))
return
}
onSuccess(conn)
},
failure: { error, _ in
failure?(error as NSError)
})
}
/// Update the shared status of the specified publicize connection
///
/// - Parameters:
/// - connectionID: The ID of the publicize connection.
/// - shared: True if the connection is shared with all users of the blog. False otherwise.
/// - siteID: The WordPress.com ID of the site.
/// - success: An optional success block accepting no arguments.
/// - failure: An optional failure block accepting an `NSError` argument.
///
@objc open func updatePublicizeConnectionWithID(_ connectionID: NSNumber,
shared: Bool,
forSite siteID: NSNumber,
success: ((RemotePublicizeConnection) -> Void)?,
failure: ((NSError?) -> Void)?) {
let endpoint = "sites/\(siteID)/publicize-connections/\(connectionID)"
let path = self.path(forEndpoint: endpoint, withVersion: ._1_1)
let parameters = [
PublicizeConnectionParams.shared: shared
]
wordPressComRESTAPI.post(path,
parameters: parameters as [String: AnyObject]?,
success: { responseObject, httpResponse in
guard let onSuccess = success else {
return
}
guard let responseDict = responseObject as? NSDictionary,
let conn = self.remotePublicizeConnectionFromDictionary(responseDict) else {
failure?(self.errorForUnexpectedResponse(httpResponse))
return
}
onSuccess(conn)
},
failure: { error, _ in
failure?(error as NSError)
})
}
/// Disconnects (deletes) the specified publicize connection
///
/// - Parameters:
/// - siteID: The WordPress.com ID of the site.
/// - connectionID: The ID of the publicize connection.
/// - success: An optional success block accepting no arguments.
/// - failure: An optional failure block accepting an `NSError` argument.
///
@objc open func deletePublicizeConnection(_ siteID: NSNumber, connectionID: NSNumber, success: (() -> Void)?, failure: ((NSError?) -> Void)?) {
let endpoint = "sites/\(siteID)/publicize-connections/\(connectionID)/delete"
let path = self.path(forEndpoint: endpoint, withVersion: ._1_1)
wordPressComRESTAPI.post(path,
parameters: nil,
success: { _, _ in
success?()
},
failure: { error, _ in
failure?(error as NSError)
})
}
/// Composees a `RemotePublicizeConnection` populated with values from the passed `NSDictionary`
///
/// - Parameter dict: An `NSDictionary` representing a `RemotePublicizeConnection`.
///
/// - Returns: A `RemotePublicizeConnection` object.
///
private func remotePublicizeConnectionFromDictionary(_ dict: NSDictionary) -> RemotePublicizeConnection? {
guard let connectionID = dict.number(forKey: ConnectionDictionaryKeys.ID) else {
return nil
}
let conn = RemotePublicizeConnection()
conn.connectionID = connectionID
conn.externalDisplay = dict.string(forKey: ConnectionDictionaryKeys.externalDisplay) ?? conn.externalDisplay
conn.externalID = dict.string(forKey: ConnectionDictionaryKeys.externalID) ?? conn.externalID
conn.externalName = dict.string(forKey: ConnectionDictionaryKeys.externalName) ?? conn.externalName
conn.externalProfilePicture = dict.string(forKey: ConnectionDictionaryKeys.externalProfilePicture) ?? conn.externalProfilePicture
conn.externalProfileURL = dict.string(forKey: ConnectionDictionaryKeys.externalProfileURL) ?? conn.externalProfileURL
conn.keyringConnectionID = dict.number(forKey: ConnectionDictionaryKeys.keyringConnectionID) ?? conn.keyringConnectionID
conn.keyringConnectionUserID = dict.number(forKey: ConnectionDictionaryKeys.keyringConnectionUserID) ?? conn.keyringConnectionUserID
conn.label = dict.string(forKey: ConnectionDictionaryKeys.label) ?? conn.label
conn.refreshURL = dict.string(forKey: ConnectionDictionaryKeys.refreshURL) ?? conn.refreshURL
conn.status = dict.string(forKey: ConnectionDictionaryKeys.status) ?? conn.status
conn.service = dict.string(forKey: ConnectionDictionaryKeys.service) ?? conn.service
if let expirationDateAsString = dict.string(forKey: ConnectionDictionaryKeys.expires) {
conn.dateExpires = WPKitDateUtils.date(fromISOString: expirationDateAsString)
}
if let issueDateAsString = dict.string(forKey: ConnectionDictionaryKeys.issued) {
conn.dateIssued = WPKitDateUtils.date(fromISOString: issueDateAsString)
}
if let sharedDictNumber = dict.number(forKey: ConnectionDictionaryKeys.shared) {
conn.shared = sharedDictNumber.boolValue
}
if let siteIDDictNumber = dict.number(forKey: ConnectionDictionaryKeys.siteID) {
conn.siteID = siteIDDictNumber
}
if let userIDDictNumber = dict.number(forKey: ConnectionDictionaryKeys.userID) {
conn.userID = userIDDictNumber
}
return conn
}
// MARK: - Sharing Button Related Methods
/// Fetches the list of sharing buttons for a blog.
///
/// - Parameters:
/// - siteID: The WordPress.com ID of the site.
/// - success: An optional success block accepting an array of `RemoteSharingButton` objects.
/// - failure: An optional failure block accepting an `NSError` argument.
///
@objc open func getSharingButtonsForSite(_ siteID: NSNumber, success: (([RemoteSharingButton]) -> Void)?, failure: ((NSError?) -> Void)?) {
let endpoint = "sites/\(siteID)/sharing-buttons"
let path = self.path(forEndpoint: endpoint, withVersion: ._1_1)
wordPressComRESTAPI.get(path,
parameters: nil,
success: { responseObject, httpResponse in
guard let onSuccess = success else {
return
}
guard let responseDict = responseObject as? NSDictionary else {
failure?(self.errorForUnexpectedResponse(httpResponse))
return
}
let buttons = responseDict.array(forKey: SharingButtonsKeys.sharingButtons) as? NSArray ?? NSArray()
let sharingButtons = self.remoteSharingButtonsFromDictionary(buttons)
onSuccess(sharingButtons)
},
failure: { error, _ in
failure?(error as NSError)
})
}
/// Updates the list of sharing buttons for a blog.
///
/// - Parameters:
/// - siteID: The WordPress.com ID of the site.
/// - sharingButtons: The list of sharing buttons to update. Should be the full list and in the desired order.
/// - success: An optional success block accepting an array of `RemoteSharingButton` objects.
/// - failure: An optional failure block accepting an `NSError` argument.
///
@objc open func updateSharingButtonsForSite(_ siteID: NSNumber, sharingButtons: [RemoteSharingButton], success: (([RemoteSharingButton]) -> Void)?, failure: ((NSError?) -> Void)?) {
let endpoint = "sites/\(siteID)/sharing-buttons"
let path = self.path(forEndpoint: endpoint, withVersion: ._1_1)
let buttons = dictionariesFromRemoteSharingButtons(sharingButtons)
let parameters = [SharingButtonsKeys.sharingButtons: buttons]
wordPressComRESTAPI.post(path,
parameters: parameters as [String: AnyObject]?,
success: { responseObject, httpResponse in
guard let onSuccess = success else {
return
}
guard let responseDict = responseObject as? NSDictionary else {
failure?(self.errorForUnexpectedResponse(httpResponse))
return
}
let buttons = responseDict.array(forKey: SharingButtonsKeys.updated) as? NSArray ?? NSArray()
let sharingButtons = self.remoteSharingButtonsFromDictionary(buttons)
onSuccess(sharingButtons)
},
failure: { error, _ in
failure?(error as NSError)
})
}
/// Composees a `RemotePublicizeConnection` populated with values from the passed `NSDictionary`
///
/// - Parameter buttons: An `NSArray` of `NSDictionary`s representing `RemoteSharingButton` objects.
///
/// - Returns: An array of `RemoteSharingButton` objects.
///
private func remoteSharingButtonsFromDictionary(_ buttons: NSArray) -> [RemoteSharingButton] {
var order = 0
let sharingButtons: [RemoteSharingButton] = buttons.map { (dict) -> RemoteSharingButton in
let btn = RemoteSharingButton()
btn.buttonID = (dict as AnyObject).string(forKey: SharingButtonsKeys.buttonID) ?? btn.buttonID
btn.name = (dict as AnyObject).string(forKey: SharingButtonsKeys.name) ?? btn.name
btn.shortname = (dict as AnyObject).string(forKey: SharingButtonsKeys.shortname) ?? btn.shortname
if let customDictNumber = (dict as AnyObject).number(forKey: SharingButtonsKeys.custom) {
btn.custom = customDictNumber.boolValue
}
if let enabledDictNumber = (dict as AnyObject).number(forKey: SharingButtonsKeys.enabled) {
btn.enabled = enabledDictNumber.boolValue
}
btn.visibility = (dict as AnyObject).string(forKey: SharingButtonsKeys.visibility) ?? btn.visibility
btn.order = NSNumber(value: order)
order += 1
return btn
}
return sharingButtons
}
private func dictionariesFromRemoteSharingButtons(_ buttons: [RemoteSharingButton]) -> [NSDictionary] {
return buttons.map({ (btn) -> NSDictionary in
let dict = NSMutableDictionary()
dict[SharingButtonsKeys.buttonID] = btn.buttonID
dict[SharingButtonsKeys.name] = btn.name
dict[SharingButtonsKeys.shortname] = btn.shortname
dict[SharingButtonsKeys.custom] = btn.custom
dict[SharingButtonsKeys.enabled] = btn.enabled
if let visibility = btn.visibility {
dict[SharingButtonsKeys.visibility] = visibility
}
return dict
})
}
private func remotePublicizeServicesFromDictionary(_ dictionary: NSDictionary) -> [RemotePublicizeService] {
let responseString = dictionary.description as NSString
let services: NSDictionary = (dictionary.forKey(ServiceDictionaryKeys.services) as? NSDictionary) ?? NSDictionary()
return services.allKeys.map { key in
let dict = (services.forKey(key) as? NSDictionary) ?? NSDictionary()
let pub = RemotePublicizeService()
pub.connectURL = dict.string(forKey: ServiceDictionaryKeys.connectURL) ?? ""
pub.detail = dict.string(forKey: ServiceDictionaryKeys.description) ?? ""
pub.externalUsersOnly = dict.number(forKey: ServiceDictionaryKeys.externalUsersOnly)?.boolValue ?? false
pub.icon = dict.string(forKey: ServiceDictionaryKeys.icon) ?? ""
pub.serviceID = dict.string(forKey: ServiceDictionaryKeys.ID) ?? ""
pub.jetpackModuleRequired = dict.string(forKey: ServiceDictionaryKeys.jetpackModuleRequired) ?? ""
pub.jetpackSupport = dict.number(forKey: ServiceDictionaryKeys.jetpackSupport)?.boolValue ?? false
pub.label = dict.string(forKey: ServiceDictionaryKeys.label) ?? ""
pub.multipleExternalUserIDSupport = dict.number(forKey: ServiceDictionaryKeys.multipleExternalUserIDSupport)?.boolValue ?? false
pub.type = dict.string(forKey: ServiceDictionaryKeys.type) ?? ""
pub.status = dict.string(forKey: ServiceDictionaryKeys.status) ?? ""
// We're not guarenteed to get the right order by inspecting the
// response dictionary's keys. Instead, we can check the index
// of each service in the response string.
pub.order = NSNumber(value: responseString.range(of: pub.serviceID).location)
return pub
}
}
}
// Keys for PublicizeService dictionaries
private struct ServiceDictionaryKeys {
static let connectURL = "connect_URL"
static let description = "description"
static let externalUsersOnly = "external_users_only"
static let ID = "ID"
static let icon = "icon"
static let jetpackModuleRequired = "jetpack_module_required"
static let jetpackSupport = "jetpack_support"
static let label = "label"
static let multipleExternalUserIDSupport = "multiple_external_user_ID_support"
static let services = "services"
static let type = "type"
static let status = "status"
}
// Keys for both KeyringConnection and PublicizeConnection dictionaries
private struct ConnectionDictionaryKeys {
// shared keys
static let connections = "connections"
static let expires = "expires"
static let externalID = "external_ID"
static let externalName = "external_name"
static let externalDisplay = "external_display"
static let externalProfilePicture = "external_profile_picture"
static let issued = "issued"
static let ID = "ID"
static let label = "label"
static let refreshURL = "refresh_URL"
static let service = "service"
static let sites = "sites"
static let status = "status"
static let userID = "user_ID"
// only KeyringConnections
static let additionalExternalUsers = "additional_external_users"
static let type = "type"
static let externalCategory = "external_category"
// only PublicizeConnections
static let externalFollowerCount = "external_follower_count"
static let externalProfileURL = "external_profile_URL"
static let keyringConnectionID = "keyring_connection_ID"
static let keyringConnectionUserID = "keyring_connection_user_ID"
static let shared = "shared"
static let siteID = "site_ID"
}
// Names of parameters passed when creating or updating a publicize connection
private struct PublicizeConnectionParams {
static let keyringConnectionID = "keyring_connection_ID"
static let externalUserID = "external_user_ID"
static let shared = "shared"
}
// Names of parameters used in SharingButton requests
private struct SharingButtonsKeys {
static let sharingButtons = "sharing_buttons"
static let buttonID = "ID"
static let name = "name"
static let shortname = "shortname"
static let custom = "custom"
static let enabled = "enabled"
static let visibility = "visibility"
static let updated = "updated"
}