Skip to content
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
75 changes: 75 additions & 0 deletions WordPress/Classes/Services/AccountService+Swift.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,83 @@
import Foundation
import WordPressShared
import ShareExtensionCore
import WebKit

extension AccountService {
// MARK: - Current Account

@objc public static let defaultDotcomAccountUUIDDefaultsKey = "AccountDefaultDotcomUUID"

@objc public func setDefaultWordPressComAccount(_ account: WPAccount) {
wpAssert(account.authToken?.isEmpty == false, "Account should have an authToken for WP.com")

guard !account.isDefaultWordPressComAccount else {
return
}

UserPersistentStoreFactory.instance().set(account.uuid, forKey: AccountService.defaultDotcomAccountUUIDDefaultsKey)

let objectID = TaggedManagedObjectID(account)
let notifyAccountChange = {
let context = self.coreDataStack.mainContext
let account = try? context.existingObject(with: objectID)
NotificationCenter.default.post(name: .WPAccountDefaultWordPressComAccountChanged, object: account)

PushNotificationsManager.shared.setupRemoteNotifications()
}

if Thread.isMainThread {
// This is meant to help with testing account observers.
// Short version: dispatch_async and XCTest asynchronous helpers don't play nice with each other
// Long version: see the comment in https://github.com/wordpress-mobile/WordPress-iOS/blob/2f9a2100ca69d8f455acec47a1bbd6cbc5084546/WordPress/WordPressTest/AccountServiceRxTests.swift#L7
notifyAccountChange()
} else {
DispatchQueue.main.async(execute: notifyAccountChange)
}
}

func removeDefaultWordPressComAccount() {
wpAssert(Thread.isMainThread, "Must be called from main thread")

PushNotificationsManager.shared.unregisterDeviceToken()

guard let account = try? WPAccount.lookupDefaultWordPressComAccount(in: coreDataStack.mainContext) else {
return
}

let objectID = TaggedManagedObjectID(account)
coreDataStack.performAndSave { context in
do {
let account = try context.existingObject(with: objectID)
context.delete(account)
} catch {
wpAssertionFailure("account missing")
}
}

// Clear WordPress.com cookies
let cookieJars: [CookieJar] = [
HTTPCookieStorage.shared,
WKWebsiteDataStore.default().httpCookieStore
]

for cookieJar in cookieJars {
cookieJar.removeWordPressComCookies(completion: {})
}

URLCache.shared.removeAllCachedResponses()

// Remove defaults
UserPersistentStoreFactory.instance().removeObject(forKey: AccountService.defaultDotcomAccountUUIDDefaultsKey)

WPAnalytics.refreshMetadata()
NotificationCenter.default.post(name: .WPAccountDefaultWordPressComAccountChanged, object: nil)

StatsCache.clearCaches()
}

// MARK: - App Extensions

func setupAppExtensions() {
let context = coreDataStack.mainContext
context.performAndWait {
Expand Down
28 changes: 0 additions & 28 deletions WordPress/Classes/Services/AccountService.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,6 @@ extern NSNotificationName const WPAccountEmailAndDefaultBlogUpdatedNotification;
/// @name Default WordPress.com account
///------------------------------------

/**
Sets the default WordPress.com account

@param account the account to set as default for WordPress.com
@see defaultWordPressComAccount
@see removeDefaultWordPressComAccount
*/
- (void)setDefaultWordPressComAccount:(WPAccount *)account;

/**
Removes the default WordPress.com account. Should only be called from the Main Thread

@see defaultWordPressComAccount
@see setDefaultWordPressComAccount:
*/
- (void)removeDefaultWordPressComAccount;

/**
Query to check if an email address is paired to a wpcom account. Used in the
magic links signup flow.
Expand All @@ -49,17 +32,6 @@ extern NSNotificationName const WPAccountEmailAndDefaultBlogUpdatedNotification;
*/
- (void)isEmailAvailable:(NSString *)email success:(void (^)(BOOL available))success failure:(void (^)(NSError *error))failure;

/**
Query to check if a username is available. Used in the signup flow.

@param email
@param success
@param failure
*/
- (void)isUsernameAvailable:(NSString *)username
success:(void (^)(BOOL available))success
failure:(void (^)(NSError *error))failure;

/**
Requests a verification email to be sent to the email address associated with the current account.

Expand Down
105 changes: 1 addition & 104 deletions WordPress/Classes/Services/AccountService.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@
#import "WordPress-Swift.h"
#endif

static NSString * const DefaultDotcomAccountUUIDDefaultsKey = @"AccountDefaultDotcomUUID";
static NSString * const DefaultDotcomAccountPasswordRemovedKey = @"DefaultDotcomAccountPasswordRemovedKey";

static NSString * const WordPressDotcomXMLRPCKey = @"https://wordpress.com/xmlrpc.php";
NSNotificationName const WPAccountDefaultWordPressComAccountChangedNotification = @"WPAccountDefaultWordPressComAccountChangedNotification";
NSString * const WPAccountEmailAndDefaultBlogUpdatedNotification = @"WPAccountEmailAndDefaultBlogUpdatedNotification";

Expand All @@ -31,89 +27,6 @@ - (instancetype)initWithCoreDataStack:(id<CoreDataStack>)coreDataStack
return self;
}

///------------------------------------
/// @name Default WordPress.com account
///------------------------------------

/**
Sets the default WordPress.com account

@param account the account to set as default for WordPress.com
@see defaultWordPressComAccount
@see removeDefaultWordPressComAccount
*/
- (void)setDefaultWordPressComAccount:(WPAccount *)account
{
NSParameterAssert(account != nil);
NSAssert(account.authToken.length > 0, @"Account should have an authToken for WP.com");

if ([account isDefaultWordPressComAccount]) {
return;
}

[[UserPersistentStoreFactory userDefaultsInstance] setObject:account.uuid forKey:DefaultDotcomAccountUUIDDefaultsKey];

NSManagedObjectID *accountID = account.objectID;
void (^notifyAccountChange)(void) = ^{
NSManagedObjectContext *mainContext = self.coreDataStack.mainContext;
NSManagedObject *accountInContext = [mainContext existingObjectWithID:accountID error:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:WPAccountDefaultWordPressComAccountChangedNotification object:accountInContext];

[[PushNotificationsManager shared] setupRemoteNotifications];
};
if ([NSThread isMainThread]) {
// This is meant to help with testing account observers.
// Short version: dispatch_async and XCTest asynchronous helpers don't play nice with each other
// Long version: see the comment in https://github.com/wordpress-mobile/WordPress-iOS/blob/2f9a2100ca69d8f455acec47a1bbd6cbc5084546/WordPress/WordPressTest/AccountServiceRxTests.swift#L7
notifyAccountChange();
} else {
dispatch_async(dispatch_get_main_queue(), notifyAccountChange);
}
}

/**
Removes the default WordPress.com account

@see defaultWordPressComAccount
@see setDefaultWordPressComAccount:
*/
- (void)removeDefaultWordPressComAccount
{
NSAssert([NSThread isMainThread], @"This method should only be called from the main thread");

[[PushNotificationsManager shared] unregisterDeviceToken];

WPAccount *account = [WPAccount lookupDefaultWordPressComAccountInContext:self.coreDataStack.mainContext];
if (account == nil) {
return;
}

[self.coreDataStack performAndSaveUsingBlock:^(NSManagedObjectContext *context) {
WPAccount *accountInContext = [context existingObjectWithID:account.objectID error:nil];
[context deleteObject:accountInContext];
}];

// Clear WordPress.com cookies
NSArray<id<CookieJar>> *cookieJars = @[
(id<CookieJar>)[NSHTTPCookieStorage sharedHTTPCookieStorage],
(id<CookieJar>)[[WKWebsiteDataStore defaultDataStore] httpCookieStore]
];

for (id<CookieJar> cookieJar in cookieJars) {
[cookieJar removeWordPressComCookiesWithCompletion:^{}];
}

[[NSURLCache sharedURLCache] removeAllCachedResponses];

// Remove defaults
[[UserPersistentStoreFactory userDefaultsInstance] removeObjectForKey:DefaultDotcomAccountUUIDDefaultsKey];

[WPAnalytics refreshMetadata];
[[NSNotificationCenter defaultCenter] postNotificationName:WPAccountDefaultWordPressComAccountChangedNotification object:nil];

[StatsCache clearCaches];
}

- (void)isEmailAvailable:(NSString *)email success:(void (^)(BOOL available))success failure:(void (^)(NSError *error))failure
{
id<AccountServiceRemote> remote = [self remoteForAnonymous];
Expand All @@ -128,22 +41,6 @@ - (void)isEmailAvailable:(NSString *)email success:(void (^)(BOOL available))suc
}];
}

- (void)isUsernameAvailable:(NSString *)username
success:(void (^)(BOOL available))success
failure:(void (^)(NSError *error))failure
{
id<AccountServiceRemote> remote = [self remoteForAnonymous];
[remote isUsernameAvailable:username success:^(BOOL available) {
if (success) {
success(available);
}
} failure:^(NSError *error) {
if (failure) {
failure(error);
}
}];
}

- (void)requestVerificationEmail:(void (^)(void))success failure:(void (^)(NSError * _Nonnull))failure
{
NSAssert([NSThread isMainThread], @"This method should only be called from the main thread");
Expand Down Expand Up @@ -267,7 +164,7 @@ - (void)restoreDisassociatedAccountIfNecessary
// Assume we have a good candidate account and make it the default account in the app.
// Note that this should be the account with the most blogs.
// Updates user defaults here vs the setter method to avoid potential side-effects from dispatched notifications.
[[UserPersistentStoreFactory userDefaultsInstance] setObject:account.uuid forKey:DefaultDotcomAccountUUIDDefaultsKey];
[[UserPersistentStoreFactory userDefaultsInstance] setObject:account.uuid forKey:AccountService.defaultDotcomAccountUUIDDefaultsKey];
}
}

Expand Down