Skip to content

Commit a9c6be6

Browse files
committed
Migrate publicize operations to JetpackPublicizeService
Move all publicize connection operations (create, update, delete, fetch keyrings) from SharingService/SharingServiceRemote to JetpackPublicizeService. Remove the legacy v1.1 API methods and update all Obj-C callers.
1 parent e9a0480 commit a9c6be6

6 files changed

Lines changed: 38 additions & 836 deletions

File tree

Modules/Sources/WordPressKit/SharingServiceRemote.swift

Lines changed: 0 additions & 444 deletions
Large diffs are not rendered by default.

WordPress/Classes/Services/BlogService.m

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,20 +152,17 @@ - (void)syncBlogAndAllMetadata:(Blog *)blog completionHandler:(void (^)(void))co
152152
dispatch_group_leave(syncGroup);
153153
}];
154154

155-
SharingSyncService *sharingService = [[SharingSyncService alloc] initWithCoreDataStack:self.coreDataStack];
155+
JetpackPublicizeService *publicizeService = [[JetpackPublicizeService alloc] initWithCoreDataStack:[ContextManager sharedInstance]];
156156
dispatch_group_enter(syncGroup);
157-
[sharingService syncPublicizeConnectionsForBlog:blog
158-
success:^{
159-
dispatch_group_leave(syncGroup);
160-
}
161-
failure:^(NSError *error) {
162-
DDLogError(@"Failed syncing publicize connections for blog %@: %@", blog.url, error);
163-
dispatch_group_leave(syncGroup);
164-
}];
165-
166-
SharingService *publicizeService = [[SharingService alloc] initWithContextManager:[ContextManager sharedInstance]];
157+
[publicizeService syncConnectionsFor:blog success:^{
158+
dispatch_group_leave(syncGroup);
159+
} failure:^(NSError *error) {
160+
DDLogError(@"Failed syncing publicize connections for blog %@: %@", blog.url, error);
161+
dispatch_group_leave(syncGroup);
162+
}];
163+
167164
dispatch_group_enter(syncGroup);
168-
[publicizeService syncPublicizeServicesForBlog:blog success:^{
165+
[publicizeService syncServicesFor:blog success:^{
169166
dispatch_group_leave(syncGroup);
170167
} failure:^(NSError * _Nullable error) {
171168
DDLogError(@"Failed syncing publicize services for blog %@: %@", blog.url, error);

WordPress/Classes/Services/SharingService.swift

Lines changed: 0 additions & 344 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import WordPressKit
77
/// connections, and keyring connections.
88
///
99
@objc public class SharingService: NSObject {
10-
let SharingAPIErrorNotFound = "not_found"
11-
1210
private let coreDataStack: CoreDataStackSwift
1311

1412
/// The initialiser for Objective-C code.
@@ -23,348 +21,6 @@ import WordPressKit
2321
self.coreDataStack = coreDataStack
2422
}
2523

26-
// MARK: - Publicize Related Methods
27-
28-
/// Syncs the list of Publicize services. The list is expected to very rarely change.
29-
///
30-
/// - Parameters:
31-
/// - blog: The `Blog` for which to sync publicize services
32-
/// - success: An optional success block accepting no parameters
33-
/// - failure: An optional failure block accepting an `NSError` parameter
34-
///
35-
@objc public func syncPublicizeServicesForBlog(_ blog: Blog, success: (() -> Void)?, failure: ((NSError?) -> Void)?) {
36-
guard let remote = remoteForBlog(blog),
37-
let blogID = blog.dotComID else {
38-
failure?(nil)
39-
return
40-
}
41-
42-
remote.getPublicizeServices(for: blogID, success: { remoteServices in
43-
// Process the results
44-
self.mergePublicizeServices(remoteServices, success: success)
45-
}, failure: failure)
46-
}
47-
48-
/// Fetches the current user's list of keyring connections. Nothing is saved to core data.
49-
/// The success block should accept an array of `KeyringConnection` objects.
50-
///
51-
/// - Parameters:
52-
/// - blog: The `Blog` for which to sync keyring connections
53-
/// - success: An optional success block accepting an array of `KeyringConnection` objects
54-
/// - failure: An optional failure block accepting an `NSError` parameter
55-
///
56-
@objc public func fetchKeyringConnectionsForBlog(_ blog: Blog, success: (([KeyringConnection]) -> Void)?, failure: ((NSError?) -> Void)?) {
57-
guard let remote = remoteForBlog(blog) else {
58-
return
59-
}
60-
remote.getKeyringConnections({ keyringConnections in
61-
// Just return the result
62-
success?(keyringConnections)
63-
},
64-
failure: failure)
65-
}
66-
67-
/// Creates a new publicize connection for the specified `Blog`, using the specified
68-
/// keyring. Optionally the connection can target a particular external user account.
69-
///
70-
/// - Parameters
71-
/// - blog: The `Blog` for which to sync publicize connections
72-
/// - keyring: The `KeyringConnection` to use
73-
/// - externalUserID: An optional string representing a user ID on the external service.
74-
/// - success: An optional success block accepting a `PublicizeConnection` parameter.
75-
/// - failure: An optional failure block accepting an NSError parameter.
76-
///
77-
@objc public func createPublicizeConnectionForBlog(_ blog: Blog,
78-
keyring: KeyringConnection,
79-
externalUserID: String?,
80-
success: ((PublicizeConnection) -> Void)?,
81-
failure: ((NSError?) -> Void)?) {
82-
let blogObjectID = blog.objectID
83-
guard let remote = remoteForBlog(blog) else {
84-
return
85-
}
86-
let dotComID = blog.dotComID!
87-
remote.createPublicizeConnection(
88-
dotComID,
89-
keyringConnectionID: keyring.keyringID,
90-
externalUserID: externalUserID,
91-
success: { remoteConnection in
92-
let properties = [
93-
"service": keyring.service
94-
]
95-
WPAppAnalytics.track(.sharingPublicizeConnected, properties: properties, blogID: dotComID)
96-
97-
self.coreDataStack.performAndSave({ context -> NSManagedObjectID in
98-
try self.createOrReplacePublicizeConnectionForBlogWithObjectID(blogObjectID, remoteConnection: remoteConnection, in: context)
99-
}, completion: { result in
100-
let transformed = result.flatMap { objectID in
101-
Result {
102-
let object = try self.coreDataStack.mainContext.existingObject(with: objectID)
103-
return object as! PublicizeConnection
104-
}
105-
}
106-
switch transformed {
107-
case let .success(object):
108-
success?(object)
109-
case let .failure(error):
110-
DDLogError("Error creating publicize connection from remote: \(error)")
111-
failure?(error as NSError)
112-
}
113-
}, on: .main)
114-
},
115-
failure: { (error: NSError?) in
116-
failure?(error)
117-
})
118-
}
119-
120-
/// Update the specified `PublicizeConnection`. The update to core data is performed
121-
/// optimistically. In case of failure the original value will be restored.
122-
///
123-
/// - Parameters:
124-
/// - shared: True if the connection should be shared with all users of the blog.
125-
/// - pubConn: The `PublicizeConnection` to update
126-
/// - success: An optional success block accepting no parameters.
127-
/// - failure: An optional failure block accepting an NSError parameter.
128-
///
129-
@objc public func updateSharedForBlog(
130-
_ blog: Blog,
131-
shared: Bool,
132-
forPublicizeConnection pubConn: PublicizeConnection,
133-
success: (() -> Void)?,
134-
failure: ((NSError?) -> Void)?
135-
) {
136-
typealias PubConnUpdateResult = (oldValue: Bool, siteID: NSNumber, connectionID: NSNumber, service: String, remote: SharingServiceRemote?)
137-
138-
let blogObjectID = blog.objectID
139-
coreDataStack.performAndSave({ context -> PubConnUpdateResult in
140-
let blogInContext = try context.existingObject(with: blogObjectID) as! Blog
141-
let pubConnInContext = try context.existingObject(with: pubConn.objectID) as! PublicizeConnection
142-
let oldValue = pubConnInContext.shared
143-
pubConnInContext.shared = shared
144-
return (
145-
oldValue: oldValue,
146-
siteID: pubConnInContext.siteID,
147-
connectionID: pubConnInContext.connectionID,
148-
service: pubConnInContext.service,
149-
remote: self.remoteForBlog(blogInContext)
150-
)
151-
}, completion: { result in
152-
switch result {
153-
case let .success(value):
154-
if value.oldValue == shared {
155-
success?()
156-
return
157-
}
158-
159-
value.remote?.updatePublicizeConnectionWithID(
160-
value.connectionID,
161-
shared: shared,
162-
forSite: value.siteID,
163-
success: { remoteConnection in
164-
let properties = [
165-
"service": value.service,
166-
"is_site_wide": NSNumber(value: shared).stringValue
167-
]
168-
WPAppAnalytics.track(.sharingPublicizeConnectionAvailableToAllChanged, properties: properties, blogID: value.siteID)
169-
170-
self.coreDataStack.performAndSave({ context in
171-
try self.createOrReplacePublicizeConnectionForBlogWithObjectID(blogObjectID, remoteConnection: remoteConnection, in: context)
172-
}, completion: { result in
173-
switch result {
174-
case .success:
175-
success?()
176-
case let .failure(error):
177-
DDLogError("Error creating publicize connection from remote: \(error)")
178-
failure?(error as NSError)
179-
}
180-
}, on: .main)
181-
},
182-
failure: { (error: NSError?) in
183-
self.coreDataStack.performAndSave({ context in
184-
let pubConnInContext = try context.existingObject(with: pubConn.objectID) as! PublicizeConnection
185-
pubConnInContext.shared = value.oldValue
186-
}, completion: { _ in
187-
failure?(error)
188-
}, on: .main)
189-
}
190-
)
191-
case let .failure(error):
192-
failure?(error as NSError)
193-
}
194-
}, on: .main)
195-
}
196-
197-
/// Update the specified `PublicizeConnection`. The update to core data is performed
198-
/// optimistically. In case of failure the original value will be restored.
199-
///
200-
/// - Parameters:
201-
/// - externalID: True if the connection should be shared with all users of the blog.
202-
/// - pubConn: The `PublicizeConnection` to update
203-
/// - success: An optional success block accepting no parameters.
204-
/// - failure: An optional failure block accepting an NSError parameter.
205-
///
206-
@objc public func updateExternalID(_ externalID: String,
207-
forBlog blog: Blog,
208-
forPublicizeConnection pubConn: PublicizeConnection,
209-
success: (() -> Void)?,
210-
failure: ((NSError?) -> Void)?) {
211-
if pubConn.externalID == externalID {
212-
success?()
213-
return
214-
}
215-
216-
let blogObjectID = blog.objectID
217-
let siteID = pubConn.siteID
218-
guard let remote = remoteForBlog(blog) else {
219-
return
220-
}
221-
remote.updatePublicizeConnectionWithID(pubConn.connectionID,
222-
externalID: externalID,
223-
forSite: siteID,
224-
success: { remoteConnection in
225-
self.coreDataStack.performAndSave({ context in
226-
try self.createOrReplacePublicizeConnectionForBlogWithObjectID(blogObjectID, remoteConnection: remoteConnection, in: context)
227-
}, completion: { result in
228-
switch result {
229-
case .success:
230-
success?()
231-
case let .failure(error):
232-
DDLogError("Error creating publicize connection from remote: \(error)")
233-
failure?(error as NSError)
234-
}
235-
}, on: .main)
236-
},
237-
failure: failure)
238-
}
239-
240-
/// Deletes the specified `PublicizeConnection`. The delete from core data is performed
241-
/// optimistically. The caller's `failure` block should be responsible for resyncing
242-
/// the deleted connection.
243-
///
244-
/// - Parameters:
245-
/// - pubConn: The `PublicizeConnection` to delete
246-
/// - success: An optional success block accepting no parameters.
247-
/// - failure: An optional failure block accepting an NSError parameter.
248-
///
249-
@objc public func deletePublicizeConnectionForBlog(_ blog: Blog, pubConn: PublicizeConnection, success: (() -> Void)?, failure: ((NSError?) -> Void)?) {
250-
// optimistically delete the connection locally.
251-
coreDataStack.performAndSave({ context in
252-
let blogInContext = try context.existingObject(with: blog.objectID) as! Blog
253-
let pubConnInContext = try context.existingObject(with: pubConn.objectID) as! PublicizeConnection
254-
255-
let siteID = pubConnInContext.siteID
256-
context.delete(pubConnInContext)
257-
return (siteID, pubConnInContext.connectionID, pubConnInContext.service, self.remoteForBlog(blogInContext))
258-
}, completion: { result in
259-
switch result {
260-
case let .success((siteID, connectionID, service, remote)):
261-
remote?.deletePublicizeConnection(
262-
siteID,
263-
connectionID: connectionID,
264-
success: {
265-
let properties = [
266-
"service": service
267-
]
268-
WPAppAnalytics.track(.sharingPublicizeDisconnected, properties: properties, blogID: siteID)
269-
success?()
270-
},
271-
failure: { (error: NSError?) in
272-
if let errorCode = error?.userInfo[WordPressComRestApi.ErrorKeyErrorCode] as? String {
273-
if errorCode == self.SharingAPIErrorNotFound {
274-
// This is a special situation. If the call to disconnect the service returns not_found then the service
275-
// has probably already been disconnected and the call was made with stale data.
276-
// Assume this is the case and treat this error as a successful disconnect.
277-
success?()
278-
return
279-
}
280-
}
281-
failure?(error)
282-
}
283-
)
284-
case let .failure(error):
285-
failure?(error as NSError)
286-
}
287-
}, on: .main)
288-
}
289-
290-
// MARK: - Private PublicizeService Methods
291-
292-
/// Called when syncing Publicize services. Merges synced and cached data, removing
293-
/// anything that does not exist on the server. Saves the context.
294-
///
295-
/// - Parameters
296-
/// - remoteServices: An array of `RemotePublicizeService` objects to merge.
297-
/// - success: An optional callback block to be performed when core data has saved the changes.
298-
///
299-
private func mergePublicizeServices(_ remoteServices: [RemotePublicizeService], success: (() -> Void)? ) {
300-
coreDataStack.performAndSave({ context in
301-
let currentPublicizeServices = (try? PublicizeService.allPublicizeServices(in: context)) ?? []
302-
303-
// Create or update based on the contents synced.
304-
let servicesToKeep = remoteServices.map { (remoteService) -> PublicizeService in
305-
self.createOrReplaceFromRemotePublicizeService(remoteService, in: context)
306-
}
307-
308-
// Delete any cached PublicizeServices that were not synced.
309-
for pubService in currentPublicizeServices {
310-
if !servicesToKeep.contains(pubService) {
311-
context.delete(pubService)
312-
}
313-
}
314-
}, completion: success, on: .main)
315-
}
316-
317-
/// Composes a new `PublicizeService`, or updates an existing one, with data represented by the passed `RemotePublicizeService`.
318-
///
319-
/// - Parameter remoteService: The remote publicize service representing a `PublicizeService`
320-
///
321-
/// - Returns: A `PublicizeService`.
322-
///
323-
private func createOrReplaceFromRemotePublicizeService(_ remoteService: RemotePublicizeService, in context: NSManagedObjectContext) -> PublicizeService {
324-
var pubService = try? PublicizeService.lookupPublicizeServiceNamed(remoteService.serviceID, in: context)
325-
if pubService == nil {
326-
pubService = NSEntityDescription.insertNewObject(forEntityName: PublicizeService.entityName(),
327-
into: context) as? PublicizeService
328-
}
329-
pubService?.connectURL = remoteService.connectURL
330-
pubService?.detail = remoteService.detail
331-
pubService?.externalUsersOnly = remoteService.externalUsersOnly
332-
pubService?.icon = remoteService.icon
333-
pubService?.jetpackModuleRequired = remoteService.jetpackModuleRequired
334-
pubService?.jetpackSupport = remoteService.jetpackSupport
335-
pubService?.label = remoteService.label
336-
pubService?.multipleExternalUserIDSupport = remoteService.multipleExternalUserIDSupport
337-
pubService?.order = remoteService.order
338-
pubService?.serviceID = remoteService.serviceID
339-
pubService?.type = remoteService.type
340-
pubService?.status = (remoteService.status.isEmpty ? PublicizeService.defaultStatus : remoteService.status)
341-
342-
return pubService!
343-
}
344-
345-
// MARK: - Private PublicizeConnection Methods
346-
347-
/// Composes a new `PublicizeConnection`, with data represented by the passed `RemotePublicizeConnection`.
348-
/// Throws an error if unable to find a `Blog` for the `blogObjectID`
349-
///
350-
/// - Parameter blogObjectID: And `NSManagedObjectID` for for a `Blog` entity.
351-
///
352-
/// - Returns: A `PublicizeConnection`.
353-
///
354-
private func createOrReplacePublicizeConnectionForBlogWithObjectID(
355-
_ blogObjectID: NSManagedObjectID,
356-
remoteConnection: RemotePublicizeConnection,
357-
in context: NSManagedObjectContext
358-
) throws -> NSManagedObjectID {
359-
let blog = try context.existingObject(with: blogObjectID) as! Blog
360-
let pubConn = PublicizeConnection.createOrReplace(from: remoteConnection, in: context)
361-
pubConn.blog = blog
362-
363-
try context.obtainPermanentIDs(for: [pubConn])
364-
365-
return pubConn.objectID
366-
}
367-
36824
// MARK: Sharing Button Related Methods
36925

37026
/// Syncs `SharingButton`s for the specified wpcom blog.

0 commit comments

Comments
 (0)