Skip to content
This repository was archived by the owner on Feb 5, 2025. It is now read-only.

Conversation

@jaclync
Copy link
Contributor

@jaclync jaclync commented Aug 10, 2022

For woocommerce/woocommerce-ios#7437

In WCiOS, we're experimenting with emphasizing the magic link in place of the password because the magic link has a much higher sign-in rate. In order not to break other apps like WPiOS, the changes are under a new configuration WordPressAuthenticatorConfiguration.isWPComMagicLinkPreferredToPassword that is default to false.

Design hHmVq03kKpvTDzV3uV4wqw-fi-14%3A2092

Screen Shot 2022-08-10 at 5 16 52 PM

Notes on the code changes

Sorry about the slightly 500+ diffs 🙇🏻‍♀️ the main changes are on the new view controller MagicLinkRequestedViewController and its xib.

I decided to implement the new screen MagicLinkRequestedViewController with a lighter weight xib than a storyboard. I ran into some rabbit holes trying to use the shared button styles with NUXButton, which is initialized with a Storyboard. After some trials and errors, I was able to use NUXButtonViewController as a child view controller in a container view. Then I ran into a problem with the "Use password to sign in" CTA because it's using link style, and the WPAuthenticator doesn't have a shared style for it. After all, I implemented the primary CTA with NUXButtonViewController and the "Use password to sign in" CTA with a UIButton and a new extension applyLinkButtonStyle similar to WCiOS.

Notes on the UX

Right now, after requesting a magic link successfully from the password screen, it still navigates to the pre-existing magic link requested screen LoginMagicLinkViewController. I'm going to confirm with design later, because otherwise it feels like an infinite loop between the password and the new magic link requested screen.

Testing steps

Please refer to the testing steps in the WCiOS PR.

Example screenshots

light dark

tablet:

Copy link
Contributor

@selanthiraiyan selanthiraiyan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work introducing a coordinator. 🙇

It works great.

I left a few questions and non-blocking nits.


/// Show the Password entry view.
///
func showPasswordView() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Nit: Now that the method doesn't always show the password view, would it make sense to rename it and update the comments?
  2. Question: This method is also being called from here. I haven't tested that flow. But, do we want the magic link behaviour there as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great question and suggestion! the SIWA flow that triggered the password view isn't easily testable, so I reverted the changes on this in 4b97bc5

loginFields: loginFields,
tracker: tracker,
configuration: WordPressAuthenticator.shared.configuration)
passwordCoordinator = coordinator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Why are we storing this in passwordCoordinator?

I tried removing this and noticed that we need this here

  • Instead of asking PasswordCoordinator to present the password view, can we pass the necessary properties to MagicLinkRequestedViewController and ask it present the screen?
  • We could even create a separate coordinator just for showing PasswordViewController and store it in MagicLinkRequestedViewController

I am sure that you considered the above and several other options, and I am curious to know your thoughts. 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes exactly, the coordinator needs to be retained during the lifetime of its possible navigation flow. because there's logic about which view controller to show, I thought it's easier to reuse this flow by using a coordinator. we could reuse it in other cases where it makes sense to prefer a magic link to password.

}

override var sourceTag: WordPressSupportSourceTag {
.loginMagicLink
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:
This being a new screen should we consider adding sourceTag?
This might be helpful when we work on help center experiment. 😅 Internal ref - pe5sF9-n8-p2

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, added in 31ef4e4


tracker.set(flow: .loginWithMagicLink)

if isMovingToParent {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Kindly consider using isBeingPresentedInAnyWay.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, updated in f40cc75

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2022-08-11 at 9 50 00 AM

IMHO, it might be helpful to fix these constraints to make changes to this file in future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really tricky, these IB errors are confusing because these 3 views are in a UIStackView and their Y position or height is supposed to be dynamic. The actual layout was all fine from my testing on various font sizes in different simulators, the scroll view is scrollable on larger font sizes. I ended up adding minimum placeholder constraints to be removed at build time in 51f90cd, please let me know if you have better suggestions on this Auto Layout challenge 🙇🏻‍♀️

@IBOutlet private weak var emailLabel: UILabel!
@IBOutlet private weak var cannotFindEmailLabel: UILabel!
@IBOutlet weak var buttonContainerView: UIView!
@IBOutlet weak var loginWithPasswordButton: UIButton!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We could make buttonContainerView and loginWithPasswordButton private as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 6ff631a

}

func start() async {
if configuration.isWPComMagicLinkPreferredToPassword {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nit: What do you think about using guard?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is an experiment, I don't think the magic link preferred flow is the assumed path. It's also a configuration that WPiOS isn't adopting yet.

Copy link
Contributor Author

@jaclync jaclync left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review and for catching a few things @selanthiraiyan! I responded to your questions in woocommerce/woocommerce-ios#7449 (review) to consolidate all the responses in the same PR 🙂 See if you'd like to take another look or I'll merge it early Friday, I tested a few more times.

In the Login with site address flow

After the following step,

Enter a valid non-A8C WP.com email and tap "Continue" --> after a little bit (requesting magic link), a new magic link requested screen should be shown with two CTAs at the bottom

the below event is tracked,

Tracked unified_login_interaction, properties: [AnyHashable("click"): "request_magic_link", AnyHashable("step"): "start", AnyHashable("flow"): "login_site_address", AnyHashable("source"): "default"]

Would it be alright to track a click property even though the user didn't manually request magic link?

Thanks for catching this logging mistake, this click event shouldn't have been tracked. I removed this in 2cb71a6


❓ Just curious
Do you have a sequence of analytics events planned to measure the success of this iteration? (To compare with other iterations and etc)

According to the metric for this experiment/iteration in pe5sF9-iy-p2, we want to measure the % of users that enter the magic link login flow and end up successfully logging in goes up.

In this PR, I added a new event to track this step in f40cc75:

🔵 Tracked unified_login_step, properties: [AnyHashable("source"): "default", AnyHashable("flow"): "login_magic_link", AnyHashable("step"): "magic_link_auto_requested"]

so we can measure the successful sign-in rate in a funnel with this new step.

}

func start() async {
if configuration.isWPComMagicLinkPreferredToPassword {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is an experiment, I don't think the magic link preferred flow is the assumed path. It's also a configuration that WPiOS isn't adopting yet.

loginFields: loginFields,
tracker: tracker,
configuration: WordPressAuthenticator.shared.configuration)
passwordCoordinator = coordinator
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes exactly, the coordinator needs to be retained during the lifetime of its possible navigation flow. because there's logic about which view controller to show, I thought it's easier to reuse this flow by using a coordinator. we could reuse it in other cases where it makes sense to prefer a magic link to password.

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really tricky, these IB errors are confusing because these 3 views are in a UIStackView and their Y position or height is supposed to be dynamic. The actual layout was all fine from my testing on various font sizes in different simulators, the scroll view is scrollable on larger font sizes. I ended up adding minimum placeholder constraints to be removed at build time in 51f90cd, please let me know if you have better suggestions on this Auto Layout challenge 🙇🏻‍♀️

@IBOutlet private weak var emailLabel: UILabel!
@IBOutlet private weak var cannotFindEmailLabel: UILabel!
@IBOutlet weak var buttonContainerView: UIView!
@IBOutlet weak var loginWithPasswordButton: UIButton!
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 6ff631a

}

override var sourceTag: WordPressSupportSourceTag {
.loginMagicLink
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, added in 31ef4e4


/// Show the Password entry view.
///
func showPasswordView() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great question and suggestion! the SIWA flow that triggered the password view isn't easily testable, so I reverted the changes on this in 4b97bc5


tracker.set(flow: .loginWithMagicLink)

if isMovingToParent {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, updated in f40cc75

@selanthiraiyan
Copy link
Contributor

Thanks for making the changes Jaclyn. This looks great now. 🚀

@jaclync jaclync merged commit b20a8de into trunk Aug 12, 2022
@jaclync jaclync deleted the wcios/7437-magic-link-auto-sent branch August 12, 2022 02:59
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants