Skip to content
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

Fix Core Data concurrency issues in AccountService #20394

Merged
merged 3 commits into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
22.1
-----
* [**] [internal] Refactor updating account related Core Data operations, which ususally happens during log in and out of the app. [#20394]
* [***] [internal] Refactor uploading photos (from the device photo, the Free Photo library, and other sources) to the WordPress Media Library. Affected areas are where you can choose a photo and upload, including the "Media" screen, adding images to a post, updating site icon, etc. [#20322]


22.0
-----
* [*] Remove large title in Reader and Notifications tabs. [#20271]
Expand Down
2 changes: 1 addition & 1 deletion WordPress/Classes/Services/AccountService.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ extern NSNotificationName const WPAccountEmailAndDefaultBlogUpdatedNotification;
Updates the default blog for the specified account. The default blog will be the one whose siteID matches
the accounts primaryBlogID.
*/
- (void)updateDefaultBlogIfNeeded:(WPAccount *)account;
- (void)updateDefaultBlogIfNeeded:(WPAccount *)account inContext:(NSManagedObjectContext *)context;

/**
Syncs the details for the account associated with the provided auth token, then
Expand Down
27 changes: 20 additions & 7 deletions WordPress/Classes/Services/AccountService.m
Original file line number Diff line number Diff line change
Expand Up @@ -351,12 +351,14 @@ - (void)updateAccountWithID:(NSManagedObjectID *)objectID withUserDetails:(Remot
// Make sure the account is saved before updating its default blog.
[self.coreDataStack performAndSaveUsingBlock:^(NSManagedObjectContext *context) {
WPAccount *account = [context existingObjectWithID:objectID error:nil];
[self updateDefaultBlogIfNeeded:account];
[self updateDefaultBlogIfNeeded:account inContext:context];
}];
}

- (void)updateDefaultBlogIfNeeded:(WPAccount *)account
- (void)updateDefaultBlogIfNeeded:(WPAccount *)account inContext:(NSManagedObjectContext *)context
{
NSParameterAssert(account.managedObjectContext == context);

if (!account.primaryBlogID || [account.primaryBlogID intValue] == 0) {
return;
}
Expand All @@ -375,17 +377,27 @@ - (void)updateDefaultBlogIfNeeded:(WPAccount *)account

// Update app extensions if needed.
if ([account isDefaultWordPressComAccount]) {
[self setupAppExtensionsWithDefaultAccount];
[self setupAppExtensionsWithDefaultAccount:account inContext:context];
}
}

- (void)setupAppExtensionsWithDefaultAccount
{
WPAccount * __block defaultAccount = nil;
[self.coreDataStack.mainContext performBlockAndWait:^{
defaultAccount = [WPAccount lookupDefaultWordPressComAccountInContext:self.coreDataStack.mainContext];
NSManagedObjectContext *context = self.coreDataStack.mainContext;
[context performBlockAndWait:^{
WPAccount *account = [WPAccount lookupDefaultWordPressComAccountInContext:context];
if (account == nil) {
return;
}
[self setupAppExtensionsWithDefaultAccount:account inContext:context];
}];
}

- (void)setupAppExtensionsWithDefaultAccount:(WPAccount *)defaultAccount inContext:(NSManagedObjectContext *)context
{
NSParameterAssert(defaultAccount.managedObjectContext == context);

NSManagedObjectID *defaultAccountObjectID = defaultAccount.objectID;
Blog *defaultBlog = [defaultAccount defaultBlog];
NSNumber *siteId = defaultBlog.dotComID;
NSString *blogName = defaultBlog.settings.name;
Expand All @@ -412,7 +424,7 @@ - (void)setupAppExtensionsWithDefaultAccount
NSString *todayExtensionBlogName = [sharedDefaults objectForKey:AppConfigurationWidgetStatsToday.userDefaultsSiteNameKey];
NSString *todayExtensionBlogUrl = [sharedDefaults objectForKey:AppConfigurationWidgetStatsToday.userDefaultsSiteUrlKey];

Blog *todayExtensionBlog = [Blog lookupWithID:todayExtensionSiteID in:self.coreDataStack.mainContext];
Blog *todayExtensionBlog = [Blog lookupWithID:todayExtensionSiteID in:context];
NSTimeZone *timeZone = [todayExtensionBlog timeZone];

if (todayExtensionSiteID == NULL || todayExtensionBlog == nil) {
Expand All @@ -423,6 +435,7 @@ - (void)setupAppExtensionsWithDefaultAccount
}

dispatch_async(dispatch_get_main_queue(), ^{
WPAccount *defaultAccount = [self.coreDataStack.mainContext existingObjectWithID:defaultAccountObjectID error:nil];

TodayExtensionService *service = [TodayExtensionService new];
[service configureTodayWidgetWithSiteID:todayExtensionSiteID
Expand Down
2 changes: 1 addition & 1 deletion WordPress/Classes/Services/BlogService.m
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ - (void)mergeBlogs:(NSArray<RemoteBlog *> *)blogs withAccountID:(NSManagedObject

// Ensure that the account has a default blog defined (if there is one).
AccountService *service = [[AccountService alloc] initWithCoreDataStack:self.coreDataStack];
[service updateDefaultBlogIfNeeded:account];
[service updateDefaultBlogIfNeeded:account inContext:context];
}

- (void)updateBlogWithRemoteBlog:(RemoteBlog *)remoteBlog account:(WPAccount *)account inContext:(NSManagedObjectContext *)context
Expand Down