-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace context object with CoreDataStack
in NotificationSettingsService
#19422
Changes from all commits
cdb9750
6f106f6
bd2f325
f095331
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ import WordPressKit | |
|
||
/// This service encapsulates the Restful API related to WordPress Notifications. | ||
/// | ||
open class NotificationSettingsService: LocalCoreDataService { | ||
class NotificationSettingsService { | ||
// MARK: - Aliases | ||
public typealias Channel = NotificationSettings.Channel | ||
public typealias Stream = NotificationSettings.Stream | ||
|
@@ -14,14 +14,17 @@ open class NotificationSettingsService: LocalCoreDataService { | |
/// | ||
/// - Parameter managedObjectContext: A Reference to the MOC that should be used to interact with the Core Data Stack. | ||
/// | ||
public override init(managedObjectContext context: NSManagedObjectContext) { | ||
super.init(managedObjectContext: context) | ||
public convenience init(coreDataStack: CoreDataStack) { | ||
var remoteApi: WordPressComRestApi? = nil | ||
|
||
if let defaultAccount = try? WPAccount.lookupDefaultWordPressComAccount(in: context), | ||
if let defaultAccount = try? WPAccount.lookupDefaultWordPressComAccount(in: coreDataStack.mainContext), | ||
defaultAccount.authToken != nil, | ||
let restApi = defaultAccount.wordPressComRestApi { | ||
remoteApi = restApi.hasCredentials() ? restApi : nil | ||
let restApi = defaultAccount.wordPressComRestApi, | ||
restApi.hasCredentials() { | ||
remoteApi = restApi | ||
} | ||
|
||
self.init(coreDataStack: coreDataStack, wordPressComRestApi: remoteApi) | ||
} | ||
|
||
/// Convenience Initializer. Useful for Unit Testing | ||
|
@@ -30,8 +33,8 @@ open class NotificationSettingsService: LocalCoreDataService { | |
/// - managedObjectContext: A Reference to the MOC that should be used to interact with the Core Data Stack. | ||
/// - wordPressComRestApi: The WordPressComRestApi that should be used. | ||
/// | ||
@objc public convenience init(managedObjectContext context: NSManagedObjectContext, wordPressComRestApi: WordPressComRestApi) { | ||
self.init(managedObjectContext: context) | ||
public init(coreDataStack: CoreDataStack, wordPressComRestApi: WordPressComRestApi?) { | ||
self.coreDataStack = coreDataStack | ||
self.remoteApi = wordPressComRestApi | ||
} | ||
|
||
|
@@ -177,7 +180,7 @@ open class NotificationSettingsService: LocalCoreDataService { | |
/// | ||
fileprivate func settingsFromRemote(_ remoteSettings: [RemoteNotificationSettings]) -> [NotificationSettings] { | ||
var parsed = [NotificationSettings]() | ||
let blogs = ((try? BlogQuery().blogs(in: managedObjectContext)) ?? []).filter { $0.dotComID != nil } | ||
let blogs = ((try? BlogQuery().blogs(in: coreDataStack.mainContext)) ?? []).filter { $0.dotComID != nil } | ||
let blogMap = Dictionary(blogs.map { ($0.dotComID!.intValue, $0) }, uniquingKeysWith: { _, new in new }) | ||
|
||
for remoteSetting in remoteSettings { | ||
|
@@ -305,7 +308,7 @@ open class NotificationSettingsService: LocalCoreDataService { | |
|
||
// MARK: - Private Properties | ||
fileprivate var remoteApi: WordPressComRestApi? | ||
|
||
private let coreDataStack: CoreDataStack | ||
|
||
// MARK: - Private Computed Properties | ||
fileprivate var notificationsServiceRemote: NotificationSettingsServiceRemote? { | ||
|
@@ -316,10 +319,6 @@ open class NotificationSettingsService: LocalCoreDataService { | |
return NotificationSettingsServiceRemote(wordPressComRestApi: remoteApi) | ||
} | ||
|
||
fileprivate var blogService: BlogService { | ||
return BlogService(managedObjectContext: managedObjectContext) | ||
} | ||
|
||
Comment on lines
-319
to
-322
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well done finding this unused |
||
fileprivate var deviceId: String { | ||
return PushNotificationsManager.shared.deviceId ?? String() | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ import CoreData | |
|
||
/// The main data provider for Weekly Roundup information. | ||
/// | ||
class WeeklyRoundupDataProvider { | ||
private class WeeklyRoundupDataProvider { | ||
|
||
// MARK: - Definitions | ||
|
||
|
@@ -19,7 +19,7 @@ class WeeklyRoundupDataProvider { | |
|
||
// MARK: - Misc Properties | ||
|
||
private let context: NSManagedObjectContext | ||
private let coreDataStack: CoreDataStack | ||
|
||
/// Method to report errors that won't interrupt the execution. | ||
/// | ||
|
@@ -29,8 +29,8 @@ class WeeklyRoundupDataProvider { | |
/// | ||
private let debugSettings = WeeklyRoundupDebugScreen.Settings() | ||
|
||
init(context: NSManagedObjectContext, onError: @escaping (Error) -> Void) { | ||
self.context = context | ||
init(coreDataStack: CoreDataStack, onError: @escaping (Error) -> Void) { | ||
self.coreDataStack = coreDataStack | ||
self.onError = onError | ||
} | ||
|
||
|
@@ -55,7 +55,7 @@ class WeeklyRoundupDataProvider { | |
} | ||
} | ||
|
||
func getTopSiteStats(from sites: [Blog], completion: @escaping (Result<SiteStats?, Error>) -> Void) { | ||
private func getTopSiteStats(from sites: [Blog], completion: @escaping (Result<SiteStats?, Error>) -> Void) { | ||
var endDateComponents = DateComponents() | ||
endDateComponents.weekday = 1 | ||
|
||
|
@@ -164,7 +164,7 @@ class WeeklyRoundupDataProvider { | |
/// Filters the sites that have the Weekly Roundup notification setting enabled. | ||
/// | ||
private func filterWeeklyRoundupEnabledSites(_ sites: [Blog], result: @escaping (Result<[Blog], Error>) -> Void) { | ||
let noteService = NotificationSettingsService(managedObjectContext: context) | ||
let noteService = NotificationSettingsService(coreDataStack: coreDataStack) | ||
|
||
noteService.getAllSettings { settings in | ||
let weeklyRoundupEnabledSites = sites.filter { site in | ||
|
@@ -193,7 +193,7 @@ class WeeklyRoundupDataProvider { | |
] | ||
|
||
do { | ||
let result = try context.fetch(request) | ||
let result = try coreDataStack.mainContext.fetch(request) | ||
return .success(result) | ||
} catch { | ||
return .failure(DataRequestError.siteFetchingError(error)) | ||
|
@@ -382,8 +382,7 @@ class WeeklyRoundupBackgroundTask: BackgroundTask { | |
} | ||
} | ||
|
||
let context = ContextManager.shared.newDerivedContext() | ||
let dataProvider = WeeklyRoundupDataProvider(context: context, onError: onError) | ||
let dataProvider = WeeklyRoundupDataProvider(coreDataStack: ContextManager.shared, onError: onError) | ||
var siteStats: [Blog: StatsSummaryData]? = nil | ||
|
||
let requestData = BlockOperation { | ||
|
@@ -428,8 +427,8 @@ class WeeklyRoundupBackgroundTask: BackgroundTask { | |
views: stats.viewsCount, | ||
comments: stats.commentsCount, | ||
likes: stats.likesCount, | ||
periodEndDate: self.currentRunPeriodEndDate(), | ||
context: context) { result in | ||
periodEndDate: self.currentRunPeriodEndDate() | ||
) { result in | ||
|
||
switch result { | ||
case .success: | ||
|
@@ -538,21 +537,19 @@ class WeeklyRoundupNotificationScheduler { | |
comments: Int, | ||
likes: Int, | ||
periodEndDate: Date, | ||
context: NSManagedObjectContext, | ||
completion: @escaping (Result<Void, Error>) -> Void) { | ||
|
||
var siteTitle: String? | ||
var dotComID: Int? | ||
|
||
context.performAndWait { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm pretty sure it's safest to ensure that these operations accessing the object happen on the same queue as its context. This change was added because originally we were setting crashes here when accessing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 I was thinking the same thing, probably safer to use site.context than the one in arguments. I'll make the change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in bd2f325 |
||
dotComID = site.dotComID?.intValue | ||
siteTitle = site.title | ||
} | ||
completion: @escaping (Result<Void, Error>) -> Void | ||
) { | ||
var siteTitle: String? | ||
var dotComID: Int? | ||
|
||
site.managedObjectContext?.performAndWait { | ||
siteTitle = site.title | ||
dotComID = site.dotComID?.intValue | ||
} | ||
|
||
guard let dotComID = dotComID else { | ||
// Error | ||
return | ||
} | ||
guard let dotComID = dotComID else { | ||
fatalError("The argument site is not a WordPress.com site. Site: \(site)") | ||
} | ||
|
||
let title = notificationTitle(siteTitle) | ||
let body = notificationBodyWith(views: views, comments: likes, likes: comments) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,7 +101,7 @@ final public class PushNotificationsManager: NSObject { | |
deviceToken = newToken | ||
|
||
// Register against WordPress.com | ||
let noteService = NotificationSettingsService(managedObjectContext: ContextManager.sharedInstance().mainContext) | ||
let noteService = NotificationSettingsService(coreDataStack: ContextManager.sharedInstance()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you consider adding an instance property to store I don't think it would make much difference at runtime, given it would still access the shared instance. It might be useful in the future when/if we'll remove all the shared instances accesses in favor of Dependency Injection. 🤷♂️ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't want to think too far ahead, even though we know DI is going to happen at some point, but we don't know how it's going to look like, which can affect how the code should be written. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough. 👌 |
||
|
||
noteService.registerDeviceForPushNotifications(newToken, success: { deviceId in | ||
DDLogVerbose("Successfully registered Device ID \(deviceId) for Push Notifications") | ||
|
@@ -138,7 +138,7 @@ final public class PushNotificationsManager: NSObject { | |
|
||
ZendeskUtils.unregisterDevice() | ||
|
||
let noteService = NotificationSettingsService(managedObjectContext: ContextManager.sharedInstance().mainContext) | ||
let noteService = NotificationSettingsService(coreDataStack: ContextManager.sharedInstance()) | ||
|
||
noteService.unregisterDeviceForPushNotifications(knownDeviceId, success: { | ||
DDLogInfo("Successfully unregistered Device ID \(knownDeviceId) for Push Notifications!") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍