Skip to content

Commit

Permalink
Feature #6434 - AB Test New Onboarding (#6601)
Browse files Browse the repository at this point in the history
Feature #6434 - AB Test New Onboarding

Combined two intro view controllers into one and move some logic from browser view controller to a simple view model
  • Loading branch information
nbhasin2 committed May 14, 2020
1 parent f1c79e0 commit d1760b7
Show file tree
Hide file tree
Showing 16 changed files with 1,166 additions and 300 deletions.
28 changes: 24 additions & 4 deletions Client.xcodeproj/project.pbxproj
Expand Up @@ -250,6 +250,12 @@
435D660323D793DF0046EFA2 /* UpdateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D660223D793DF0046EFA2 /* UpdateModel.swift */; };
435D660523D794B90046EFA2 /* UpdateViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D660423D794B90046EFA2 /* UpdateViewModel.swift */; };
435D660723D7962C0046EFA2 /* UpdateCoverSheetTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D660623D7962C0046EFA2 /* UpdateCoverSheetTableViewCell.swift */; };
435D7CC02461EFCB0043ACB9 /* IntroScreenWelcomeViewV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D7CBF2461EFCB0043ACB9 /* IntroScreenWelcomeViewV2.swift */; };
435D7CC32461EFDD0043ACB9 /* IntroScreenSyncViewV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D7CC22461EFDD0043ACB9 /* IntroScreenSyncViewV2.swift */; };
435D7CC5246209AA0043ACB9 /* IntroViewControllerV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D7CC4246209AA0043ACB9 /* IntroViewControllerV2.swift */; };
4390F7F1246C76E700570811 /* IntroWelcomeAndSyncViewV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4390F7F0246C76E700570811 /* IntroWelcomeAndSyncViewV1.swift */; };
4390F7F5246CE04300570811 /* IntroViewModelV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4390F7F4246CE04300570811 /* IntroViewModelV2.swift */; };
4390F7FF246DAFBE00570811 /* FirefoxColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4390F7FE246DAFBE00570811 /* FirefoxColors.swift */; };
43A5643823CD1E1C00B6857D /* UpdateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A5643523CD1E1B00B6857D /* UpdateViewController.swift */; };
43A5643923CD1E1C00B6857D /* Update.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 43A5643623CD1E1B00B6857D /* Update.xcassets */; };
43B137F223A181A200CB7FA0 /* NSUserDefaultsPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B137F123A181A200CB7FA0 /* NSUserDefaultsPrefs.swift */; };
Expand Down Expand Up @@ -524,7 +530,6 @@
E487B24E1AC1C66400F3E86F /* FiraSans-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E4B7B7571A793CF20022C5E0 /* FiraSans-SemiBold.ttf */; };
E487B24F1AC1CC9200F3E86F /* FiraSans-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E4ECCDAD1AB131770005E717 /* FiraSans-Medium.ttf */; };
E487B2501AC1CC9800F3E86F /* FiraSans-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E4B7B7521A793CF20022C5E0 /* FiraSans-Light.ttf */; };
E49943F51AE6879C00BF9DE4 /* IntroViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E49943F41AE6879C00BF9DE4 /* IntroViewController.swift */; };
E49943F71AE69EDD00BF9DE4 /* Intro.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E49943F61AE69EDD00BF9DE4 /* Intro.xcassets */; };
E4A888161A95679500CDC337 /* FxA.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28CE83D01A1D1D5100576538 /* FxA.framework */; };
E4A960061ABB9C450069AD6F /* ReaderModeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A960051ABB9C450069AD6F /* ReaderModeUtils.swift */; };
Expand Down Expand Up @@ -1387,7 +1392,13 @@
435D660223D793DF0046EFA2 /* UpdateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateModel.swift; sourceTree = "<group>"; };
435D660423D794B90046EFA2 /* UpdateViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateViewModel.swift; sourceTree = "<group>"; };
435D660623D7962C0046EFA2 /* UpdateCoverSheetTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateCoverSheetTableViewCell.swift; sourceTree = "<group>"; };
435D7CBF2461EFCB0043ACB9 /* IntroScreenWelcomeViewV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroScreenWelcomeViewV2.swift; sourceTree = "<group>"; };
435D7CC22461EFDD0043ACB9 /* IntroScreenSyncViewV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroScreenSyncViewV2.swift; sourceTree = "<group>"; };
435D7CC4246209AA0043ACB9 /* IntroViewControllerV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroViewControllerV2.swift; sourceTree = "<group>"; };
435FAB17242404B400AE9310 /* FullscreenHelper.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FullscreenHelper.js; path = Client/Frontend/UserContent/UserScripts/AllFrames/AtDocumentStart/FullscreenHelper.js; sourceTree = SOURCE_ROOT; };
4390F7F0246C76E700570811 /* IntroWelcomeAndSyncViewV1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroWelcomeAndSyncViewV1.swift; sourceTree = "<group>"; };
4390F7F4246CE04300570811 /* IntroViewModelV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntroViewModelV2.swift; sourceTree = "<group>"; };
4390F7FE246DAFBE00570811 /* FirefoxColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirefoxColors.swift; sourceTree = "<group>"; };
43A5643523CD1E1B00B6857D /* UpdateViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateViewController.swift; sourceTree = "<group>"; };
43A5643623CD1E1B00B6857D /* Update.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Update.xcassets; sourceTree = "<group>"; };
43B137F123A181A200CB7FA0 /* NSUserDefaultsPrefs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSUserDefaultsPrefs.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1647,7 +1658,6 @@
E4424B3B1AC71FB400F44C38 /* FiraSans-Book.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "FiraSans-Book.ttf"; sourceTree = "<group>"; };
E46175F21EBB73A10021AE8A /* Sentry.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sentry.framework; path = Carthage/Build/iOS/Sentry.framework; sourceTree = "<group>"; };
E47616C61AB74CA600E7DD25 /* ReaderModeBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReaderModeBarView.swift; sourceTree = "<group>"; };
E49943F41AE6879C00BF9DE4 /* IntroViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntroViewController.swift; sourceTree = "<group>"; };
E49943F61AE69EDD00BF9DE4 /* Intro.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Intro.xcassets; sourceTree = "<group>"; };
E4A960051ABB9C450069AD6F /* ReaderModeUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReaderModeUtils.swift; sourceTree = "<group>"; };
E4A961171AC041C40069AD6F /* ReadabilityService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadabilityService.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3031,8 +3041,12 @@
E49943F31AE6879C00BF9DE4 /* Intro */ = {
isa = PBXGroup;
children = (
E49943F41AE6879C00BF9DE4 /* IntroViewController.swift */,
E49943F61AE69EDD00BF9DE4 /* Intro.xcassets */,
4390F7F4246CE04300570811 /* IntroViewModelV2.swift */,
435D7CC4246209AA0043ACB9 /* IntroViewControllerV2.swift */,
435D7CBF2461EFCB0043ACB9 /* IntroScreenWelcomeViewV2.swift */,
435D7CC22461EFDD0043ACB9 /* IntroScreenSyncViewV2.swift */,
4390F7F0246C76E700570811 /* IntroWelcomeAndSyncViewV1.swift */,
);
path = Intro;
sourceTree = "<group>";
Expand Down Expand Up @@ -3548,6 +3562,7 @@
children = (
2816EFFF1B33E05400522243 /* UIConstants.swift */,
2C49854D206173C800893DAE /* photon-colors.swift */,
4390F7FE246DAFBE00570811 /* FirefoxColors.swift */,
392ED7D51D0AEEEE009D9B62 /* Accessors */,
E692E3271C46E62D009D1240 /* AuthenticationManager */,
D3A994941A368691008AD1AC /* Browser */,
Expand Down Expand Up @@ -5039,6 +5054,7 @@
D3B6923F1B9F9A58004B87A4 /* FindInPageHelper.swift in Sources */,
EB9A179C20E69A7F00B12184 /* DarkTheme.swift in Sources */,
EB1C84BF212EFFBF001489DF /* BrowserViewController+ReaderMode.swift in Sources */,
4390F7F1246C76E700570811 /* IntroWelcomeAndSyncViewV1.swift in Sources */,
EBA3B2CD2268F27500728BDB /* PhotonActionSheetWidgets.swift in Sources */,
D3C3696E1CC6B78800348A61 /* LocalRequestHelper.swift in Sources */,
E4B423DD1ABA0318007E66C8 /* ReaderModeHandlers.swift in Sources */,
Expand Down Expand Up @@ -5117,6 +5133,7 @@
EB9854FF2422686F0040F24B /* AppDelegate+PushNotifications.swift in Sources */,
E64ED8FA1BC55AE300DAF864 /* UIAlertControllerExtensions.swift in Sources */,
39CE74F821A83105007AE4F2 /* TranslationSettingsController.swift in Sources */,
435D7CC02461EFCB0043ACB9 /* IntroScreenWelcomeViewV2.swift in Sources */,
282DA4731A68C1E700A406E2 /* OpenSearch.swift in Sources */,
39CE74F421A72309007AE4F2 /* TranslationToastHandler.swift in Sources */,
D04CD74B216CF86B004FF5B0 /* DevicePickerViewController.swift in Sources */,
Expand All @@ -5141,10 +5158,12 @@
C4F3B29A1CFCF93A00966259 /* ButtonToast.swift in Sources */,
EBA3B2D02268F40C00728BDB /* SyncMenuButton.swift in Sources */,
D31A0FC71A65D6D000DC8C7E /* SearchSuggestClient.swift in Sources */,
435D7CC5246209AA0043ACB9 /* IntroViewControllerV2.swift in Sources */,
A83E5AB71C1D993D0026D912 /* UIPasteboardExtensions.swift in Sources */,
D8EFFA0C1FF5B1FA001D3A09 /* NavigationRouter.swift in Sources */,
D0E55C4F1FB4FD23006DC274 /* FormPostHelper.swift in Sources */,
E650754E1E37F6AE006961AC /* GeometryExtensions.swift in Sources */,
4390F7F5246CE04300570811 /* IntroViewModelV2.swift in Sources */,
D3972BF41C22412B00035B87 /* TitleActivityItemProvider.swift in Sources */,
D38A1BEE1A9FA2CA00F6A386 /* SiteTableViewController.swift in Sources */,
7BA0601B1C0F4DE200DFADB6 /* TabPeekViewController.swift in Sources */,
Expand Down Expand Up @@ -5191,6 +5210,7 @@
EBB89504219398E500EB91A0 /* TrackingProtectionPageStats.swift in Sources */,
D31F95E91AC226CB005C9F3B /* ScreenshotHelper.swift in Sources */,
28EADE5D1AFC3A78007FB2FB /* UIImageViewExtensions.swift in Sources */,
435D7CC32461EFDD0043ACB9 /* IntroScreenSyncViewV2.swift in Sources */,
39CE74F021A6D2B8007AE4F2 /* DocumentServicesHelper.swift in Sources */,
D3968F251A38FE8500CEFD3B /* TabManager.swift in Sources */,
C4E398601D22C409004E89BA /* TopTabsLayout.swift in Sources */,
Expand Down Expand Up @@ -5244,8 +5264,8 @@
E40FAB0C1A7ABB77009CB80D /* WebServer.swift in Sources */,
59A68D66379CFA85C4EAF00B /* TwoLineCell.swift in Sources */,
D04CD718215EBD85004FF5B0 /* SettingsLoadingView.swift in Sources */,
4390F7FF246DAFBE00570811 /* FirefoxColors.swift in Sources */,
D04CD74C216CF86B004FF5B0 /* InstructionsViewController.swift in Sources */,
E49943F51AE6879C00BF9DE4 /* IntroViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
3 changes: 3 additions & 0 deletions Client/Application/LeanplumIntegration.swift
Expand Up @@ -81,6 +81,9 @@ struct LPAttributeKey {
static let telemetryOptIn = "Telemetry Opt In"
static let fxaAccountVerified = "FxA account is verified"
static let fxaDeviceCount = "Number of devices in FxA account"
static let experimentName = "Experiment name"
static let experimentId = "Experiment id"
static let experimentVariant = "Experiment variant"
}

struct MozillaAppSchemes {
Expand Down
99 changes: 57 additions & 42 deletions Client/Frontend/Browser/BrowserViewController.swift
Expand Up @@ -453,7 +453,7 @@ class BrowserViewController: UIViewController {

NotificationCenter.default.addObserver(self, selector: #selector(self.appMenuBadgeUpdate), name: .FirefoxAccountStateChange, object: nil)

// Setup onboarding user research for A/A testing
// Setup onboarding user research for A/B testing
onboardingUserResearch = OnboardingUserResearch()
onboardingUserResearch?.lpVariableObserver()
}
Expand Down Expand Up @@ -1913,35 +1913,15 @@ extension BrowserViewController: UIAdaptivePresentationControllerDelegate {
}
}

extension BrowserViewController: IntroViewControllerDelegate {
@discardableResult func presentIntroViewController(_ force: Bool = false, animated: Bool = true) -> Bool {
onboardingUserResearchHelper()
extension BrowserViewController {
func presentIntroViewController(_ forcedType: OnboardingScreenType? = nil) {
if let deeplink = self.profile.prefs.stringForKey("AdjustDeeplinkKey"), let url = URL(string: deeplink) {
self.launchFxAFromDeeplinkURL(url)
return true
return
}

if force || profile.prefs.intForKey(PrefsKeys.IntroSeen) == nil {
let introViewController = IntroViewController()
introViewController.delegate = self
// On iPad we present it modally in a controller
if topTabsVisible {
introViewController.preferredContentSize = CGSize(width: ViewControllerConsts.PreferredSize.IntroViewController.width, height: ViewControllerConsts.PreferredSize.IntroViewController.height)
introViewController.modalPresentationStyle = .formSheet
} else {
introViewController.modalPresentationStyle = .fullScreen
}
present(introViewController, animated: animated) {
// On first run (and forced) open up the homepage in the background.
if let homePageURL = NewTabHomePageAccessors.getHomePage(self.profile.prefs), let tab = self.tabManager.selectedTab, DeviceInfo.hasConnectivity() {
tab.loadRequest(URLRequest(url: homePageURL))
}
}

return true
if forcedType != nil || profile.prefs.intForKey(PrefsKeys.IntroSeen) == nil {
onboardingUserResearchHelper(forcedType)
}

return false
}

func presentETPCoverSheetViewController(_ force: Bool = false) {
Expand Down Expand Up @@ -2015,10 +1995,59 @@ extension BrowserViewController: IntroViewControllerDelegate {
return false
}

func onboardingUserResearchHelper() {
private func onboardingUserResearchHelper(_ forcedType: OnboardingScreenType? = nil) {
print("lp initial value \(String(describing: onboardingUserResearch?.lpVariable?.boolValue()))")
if forcedType != nil {
showProperIntroVC(forcedType)
return
}
let screenType = onboardingUserResearch?.onboardingScreenType
if screenType == nil && !DeviceInfo.hasConnectivity() {
self.onboardingUserResearch?.updateValue(value: true)
showProperIntroVC()
return
}
onboardingUserResearch?.updatedLPVariables = {(lpVariable) -> () in
print("lpVariable \(String(describing: lpVariable?.boolValue()))")
if screenType == nil {
print("lp Variable from server \(String(describing: lpVariable?.boolValue()))")
self.onboardingUserResearch?.updateTelemetry()
self.onboardingUserResearch?.updateValue(value: lpVariable?.boolValue() ?? true)
self.showProperIntroVC()
}
}
}

private func showProperIntroVC(_ forcedType: OnboardingScreenType? = nil) {
let introViewController = forcedType == nil ? IntroViewControllerV2() : IntroViewControllerV2(onboardingType: forcedType)

introViewController.didFinishClosure = { controller, fxaLoginFlow in
self.profile.prefs.setInt(1, forKey: PrefsKeys.IntroSeen)
controller.dismiss(animated: true) {
if self.navigationController?.viewControllers.count ?? 0 > 1 {
_ = self.navigationController?.popToRootViewController(animated: true)
}
if let flow = fxaLoginFlow {
let fxaParams = FxALaunchParams(query: ["entrypoint": "firstrun"])
self.presentSignInViewController(fxaParams, flowType: flow)
}
}
}
self.introVCPresentHelper(introViewController: introViewController)
}

private func introVCPresentHelper(introViewController: UIViewController) {
// On iPad we present it modally in a controller
if topTabsVisible {
introViewController.preferredContentSize = CGSize(width: ViewControllerConsts.PreferredSize.IntroViewController.width, height: ViewControllerConsts.PreferredSize.IntroViewController.height)
introViewController.modalPresentationStyle = .formSheet
} else {
introViewController.modalPresentationStyle = .fullScreen
}
present(introViewController, animated: true) {
// On first run (and forced) open up the homepage in the background.
if let homePageURL = NewTabHomePageAccessors.getHomePage(self.profile.prefs), let tab = self.tabManager.selectedTab, DeviceInfo.hasConnectivity() {
tab.loadRequest(URLRequest(url: homePageURL))
}
}
}

Expand All @@ -2031,20 +2060,6 @@ extension BrowserViewController: IntroViewControllerDelegate {
self.presentSignInViewController(fxaParams)
}

func introViewControllerDidFinish(_ introViewController: IntroViewController, fxaLoginFlow: FxAPageType?) {
self.profile.prefs.setInt(1, forKey: PrefsKeys.IntroSeen)
introViewController.dismiss(animated: true) {
if self.navigationController?.viewControllers.count ?? 0 > 1 {
_ = self.navigationController?.popToRootViewController(animated: true)
}

if let flow = fxaLoginFlow {
let fxaParams = FxALaunchParams(query: ["entrypoint": "firstrun"])
self.presentSignInViewController(fxaParams, flowType: flow)
}
}
}

func getSignInOrFxASettingsVC(_ fxaOptions: FxALaunchParams? = nil, flowType: FxAPageType) -> UIViewController {
// Show the settings page if we have already signed in. If we haven't then show the signin page
guard profile.hasSyncableAccount() else {
Expand Down
11 changes: 11 additions & 0 deletions Client/Frontend/FirefoxColors.swift
@@ -0,0 +1,11 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import UIKit

extension UIColor {
struct Firefox {
static let DarkGrey10 = UIColor(rgb: 0x242327)
}
}
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "illustration-syncing-devices.pdf",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

0 comments on commit d1760b7

Please sign in to comment.