diff --git a/iphone/Maps/UI/Authorization/AuthorizationViewController.swift b/iphone/Maps/UI/Authorization/AuthorizationViewController.swift index f35dc0b8ab..1e3f661cd9 100644 --- a/iphone/Maps/UI/Authorization/AuthorizationViewController.swift +++ b/iphone/Maps/UI/Authorization/AuthorizationViewController.swift @@ -96,7 +96,14 @@ final class AuthorizationViewController: MWMViewController { } } - private let completion: (() -> Void)? + typealias SuccessHandler = (MWMSocialTokenType) -> Void + typealias ErrorHandler = (MWMAuthorizationError) -> Void + typealias CompletionHandler = (AuthorizationViewController) -> Void + + private let sourceComponent: MWMAuthorizationSource + private let successHandler: SuccessHandler? + private let errorHandler: ErrorHandler? + private let completionHandler: CompletionHandler private func addConstraints(v1: UIView, v2: UIView) { [NSLayoutAttribute.top, .bottom, .left, .right].forEach { @@ -104,16 +111,24 @@ final class AuthorizationViewController: MWMViewController { } } - @objc init(barButtonItem: UIBarButtonItem?, completion: (() -> Void)? = nil) { - self.completion = completion + @objc + init(barButtonItem: UIBarButtonItem?, sourceComponent: MWMAuthorizationSource, successHandler: SuccessHandler? = nil, errorHandler: ErrorHandler? = nil, completionHandler: @escaping CompletionHandler) { + self.sourceComponent = sourceComponent + self.successHandler = successHandler + self.errorHandler = errorHandler + self.completionHandler = completionHandler transitioningManager = AuthorizationTransitioningManager(barButtonItem: barButtonItem) super.init(nibName: toString(type(of: self)), bundle: nil) transitioningDelegate = transitioningManager modalPresentationStyle = .custom } - @objc init(popoverSourceView: UIView? = nil, permittedArrowDirections: UIPopoverArrowDirection = .unknown, completion: (() -> Void)? = nil) { - self.completion = completion + @objc + init(popoverSourceView: UIView? = nil, permittedArrowDirections: UIPopoverArrowDirection = .unknown, sourceComponent: MWMAuthorizationSource, successHandler: SuccessHandler?, errorHandler: ErrorHandler?, completionHandler: @escaping CompletionHandler) { + self.sourceComponent = sourceComponent + self.successHandler = successHandler + self.errorHandler = errorHandler + self.completionHandler = completionHandler transitioningManager = AuthorizationTransitioningManager(popoverSourceView: popoverSourceView, permittedArrowDirections: permittedArrowDirections) super.init(nibName: toString(type(of: self)), bundle: nil) transitioningDelegate = transitioningManager @@ -138,10 +153,8 @@ final class AuthorizationViewController: MWMViewController { @IBAction func onCancel() { Statistics.logEvent(kStatUGCReviewAuthDeclined) - dismiss(animated: true, completion: { - (UIApplication.shared.keyWindow?.rootViewController as? - UINavigationController)?.popToRootViewController(animated: true) - }) + errorHandler?(.cancelled) + completionHandler(self) } private func process(error: Error, type: MWMSocialTokenType) { @@ -155,8 +168,14 @@ final class AuthorizationViewController: MWMViewController { private func process(token: String, type: MWMSocialTokenType) { Statistics.logEvent(kStatUGCReviewAuthExternalRequestSuccess, withParameters: [kStatProvider: type == .facebook ? kStatFacebook : kStatGoogle]) - ViewModel.authenticate(withToken: token, type: type) - dismiss(animated: true, completion: completion) + ViewModel.authenticate(withToken: token, type: type, source: sourceComponent) { success in + if success { + self.successHandler?(type) + } else { + self.errorHandler?(.passportError) + } + } + completionHandler(self) } } diff --git a/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.h b/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.h index 98c274538b..50a479799f 100644 --- a/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.h +++ b/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.h @@ -3,9 +3,27 @@ typedef NS_ENUM(NSInteger, MWMSocialTokenType) { MWMSocialTokenTypeFacebook }; +typedef NS_ENUM(NSInteger, MWMAuthorizationSource) { + MWMAuthorizationSourceUGC, + MWMAuthorizationSourceBookmarks +}; + +typedef NS_ENUM(NSInteger, MWMAuthorizationError) { + MWMAuthorizationErrorCancelled, + MWMAuthorizationErrorPassportError +}; + +typedef void (^MWMAuthorizationCompleteBlock)(BOOL); + @interface MWMAuthorizationViewModel : NSObject ++ (void)checkAuthenticationWithSource:(MWMAuthorizationSource)source + onComplete:(MWMAuthorizationCompleteBlock _Nonnull)onComplete; ++ (BOOL)hasSocialToken; + (BOOL)isAuthenticated; -+ (void)authenticateWithToken:(NSString * _Nonnull)token type:(enum MWMSocialTokenType)type; ++ (void)authenticateWithToken:(NSString * _Nonnull)token + type:(MWMSocialTokenType)type + source:(MWMAuthorizationSource)source + onComplete:(MWMAuthorizationCompleteBlock _Nonnull)onComplete; @end diff --git a/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.mm b/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.mm index 054a062112..bb2037c40a 100644 --- a/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.mm +++ b/iphone/Maps/UI/Authorization/MWMAuthorizationViewModel.mm @@ -9,29 +9,49 @@ @implementation MWMAuthorizationViewModel -+ (BOOL)isAuthenticated ++ (void)checkAuthenticationWithSource:(MWMAuthorizationSource)source + onComplete:(MWMAuthorizationCompleteBlock)onComplete { - if (GetFramework().GetUser().IsAuthenticated()) - return YES; + if ([self isAuthenticated]) + { + onComplete(YES); + return; + } auto googleToken = [GIDSignIn sharedInstance].currentUser.authentication.idToken; if (googleToken) { - [self authenticateWithToken:googleToken type:MWMSocialTokenTypeGoogle]; - return YES; + [self authenticateWithToken:googleToken + type:MWMSocialTokenTypeGoogle + source:source + onComplete:onComplete]; + return; } auto fbToken = [FBSDKAccessToken currentAccessToken].tokenString; if (fbToken) { - [self authenticateWithToken:fbToken type:MWMSocialTokenTypeFacebook]; - return YES; + [self authenticateWithToken:fbToken + type:MWMSocialTokenTypeFacebook + source:source + onComplete:onComplete]; + return; } - - return NO; + onComplete(NO); } -+ (void)authenticateWithToken:(NSString * _Nonnull)token type:(enum MWMSocialTokenType)type ++ (BOOL)hasSocialToken +{ + return [GIDSignIn sharedInstance].currentUser.authentication.idToken != nil || + [FBSDKAccessToken currentAccessToken].tokenString != nil; +} + ++ (BOOL)isAuthenticated { return GetFramework().GetUser().IsAuthenticated(); } + ++ (void)authenticateWithToken:(NSString * _Nonnull)token + type:(MWMSocialTokenType)type + source:(MWMAuthorizationSource)source + onComplete:(MWMAuthorizationCompleteBlock)onComplete { auto & user = GetFramework().GetUser(); User::SocialTokenType socialTokenType; @@ -47,16 +67,27 @@ socialTokenType = User::SocialTokenType::Facebook; break; } - auto s = std::make_unique(); s->m_postCallAction = User::Subscriber::Action::RemoveSubscriber; - s->m_onAuthenticate = [provider](bool success) { + s->m_onAuthenticate = [provider, source, onComplete](bool success) { + NSString * event = nil; + switch (source) + { + case MWMAuthorizationSourceUGC: + event = success ? kStatUGCReviewAuthRequestSuccess : kStatUGCReviewAuthError; + break; + case MWMAuthorizationSourceBookmarks: + event = success ? kStatBookmarksAuthRequestSuccess : kStatBookmarksAuthRequestError; + break; + } + if (success) - [Statistics logEvent:kStatUGCReviewAuthRequestSuccess - withParameters:@{kStatProvider: provider}]; + [Statistics logEvent:event withParameters:@{kStatProvider: provider}]; else - [Statistics logEvent:kStatUGCReviewAuthError - withParameters:@{kStatProvider: kStatMapsme, kStatError: @""}]; + [Statistics logEvent:event withParameters:@{kStatProvider: kStatMapsme, kStatError: @""}]; + dispatch_async(dispatch_get_main_queue(), ^{ + onComplete(success); + }); }; user.AddSubscriber(std::move(s)); user.Authenticate(token.UTF8String, socialTokenType); diff --git a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.swift b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.swift index 5ba2cc4799..ce34d2295a 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.swift +++ b/iphone/Maps/UI/PlacePage/PlacePageLayout/Content/UGC/UGCAddReview/UGCAddReviewController.swift @@ -55,19 +55,23 @@ final class UGCAddReviewController: MWMTableViewController { @objc private func onDone() { guard let text = textCell?.reviewText else { - assert(false) + assertionFailure() return } Statistics.logEvent(kStatUGCReviewSuccess) model.text = text onSave(model) guard let nc = navigationController else { return } - if MWMPlatform.networkConnectionType() == .none || MWMAuthorizationViewModel.isAuthenticated() { + if MWMPlatform.networkConnectionType() == .none { nc.popViewController(animated: true) + } else if MWMAuthorizationViewModel.hasSocialToken() { + MWMAuthorizationViewModel.checkAuthentication(with: .UGC, onComplete: { _ in }) + nc.popToRootViewController(animated: true) } else { Statistics.logEvent(kStatUGCReviewAuthShown, withParameters: [kStatFrom: kStatAfterSave]) let authVC = AuthorizationViewController(barButtonItem: navigationItem.rightBarButtonItem!, - completion: { nc.popToRootViewController(animated: true) }) + sourceComponent: .UGC, + completionHandler: { _ in nc.popToRootViewController(animated: true) }) present(authVC, animated: true, completion: nil) } }