-
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
Refactor AccountService
to use CoreDataStack
#19893
Conversation
Generated by 🚫 dangerJS |
You can test the changes in Jetpack from this Pull Request by:
|
You can test the changes in WordPress from this Pull Request by:
|
The UI test is quite simple, log in using a WP.com account and then log out, the test expects the app to end up at login prologue screen (the one with "Log in or sign up with WP.com" button). But the actual behavior is, after the "Log out" alert button is tapped, the app presents the "Log in" modal. See the recording below: Simulator.Screen.Recording.-.iPhone.14.Pro.-.2023-01-12.at.14.50.02.mp4Here are some key events that happened in the UI test to cause the failure:
|
Bumped the milestone from 21.7 to 21.8 because I'm about to start the 21.7 code freeze and this has merge conflicts. Happy to help with cherry-picking into 21.7 if necessary later on. |
There were a few compiling issues and no longer needed `XCTExpectation`s
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.
The feedback I left has been well-addressed and I couldn't find anything else to suggest!
if managedObjectContext.hasChanges { | ||
ContextManager.sharedInstance().save(managedObjectContext) | ||
coreDataStack.performAndSave { context in | ||
guard let count = try? WPAccount.lookupNumberOfAccounts(in: context), count > 1 else { |
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.
I guess some day we'll probably want a throws
-ing variant of performAndSave
😅
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.
A while ago, I tried to get the current one to rethrow
, but I don't think Swift compiler can handle an "escaped" rethrow block. We probably will have to have a performAndSaveThrowing
variant, instead of sharing the reusing the same function "performAndSave" name.
Update release notes with changes in #19893
Issue
Currently we have a lot of service types that inherit from
LocalCoreDataService
, which uses aNSManagedObjectContext
. The idea is the service class uses the provided context object to perform all the Core Data operations, including read and write. This approach introduces two potential issues:mainContext
—which should be used for reading only—may be used to write changes to database, since the service class simply uses the provided context object without checking.createOrUpdateAccount
function), there is no guarantee the context object is used in the correct thread—the caller needs to make sure of it which isn't ideal.Proposal
To resolve these potential issues, this PR refactor the service types in two ways, which will be applied across all other service types in future PRs.
LocalCoreDataService
withCoreDataService
, which takes aCoreDataStack
instance.coreDataStack.performAndSave
and read usingcoreDataStack.mainContext.performBlock
. By doing this, the service type should be thread-safe and can be called from any thread—one less thing for the callers to worry about.There is also an "implicit pattern", which is hard to enforce syntactically.
For functions in a service type that take a
NSManagedObject
argument, they should not assume what context the object belongs to (re-querying it usingcontext.existingObject(with:)
if needed, typically when updating them). Hence, it's preferred to takeNSManagedObjectID
as arugments, instead ofNSManagedObject
.In a similar way, functions in a service type should not return
NSManagedObject
instances (unless the function is absolutely sure it's called from a main thread and returns objects of themainContext
), they should returnNSManagedObjectID
instead.Test instructions
The changed files should indicate the affected areas, it's worth doing a bit regression testing on these areas. But I think a quick smoke testing on the app would be good too.
Regression Notes
Potential unintended areas of impact
None.
What I did to test those areas of impact (or what existing automated tests I relied on)
None.
What automated tests I added (or what prevented me from doing so)
None.
PR submission checklist:
RELEASE-NOTES.txt
if necessary.