Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
318 changes: 145 additions & 173 deletions Stepic.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Stepic/ActiveSplitTestsContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ class ActiveSplitTestsContainer {
private static let splitTestingService = SplitTestingService(analyticsService: AnalyticsUserProperties(), storage: UserDefaults.standard)

static func setActiveTestsGroups() {
splitTestingService.fetchSplitTest(AuthAfterOnboardingSplitTest.self).setSplitTestGroup()
splitTestingService.fetchSplitTest(JoinCourseStringSplitTest.self).setSplitTestGroup()
}
}
2 changes: 0 additions & 2 deletions Stepic/Alerts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,5 @@ import Foundation
Class, which contains different alert managers
*/
class Alerts {
static let streaks = StreaksStepikAlertManager()
static let rate = RateAppAlertManager()
static let notificationRequest = NotificationRequestAlertManager()
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,49 @@ struct AmplitudeAnalyticsEvents {
]
)
}

static func defaultAlertShown(source: String) -> AnalyticsEvent {
return AnalyticsEvent(
name: "Default notification alert shown",
parameters: [
"source": source
]
)
}

static func defaultAlertInteracted(source: String, result: InteractionResult) -> AnalyticsEvent {
return AnalyticsEvent(
name: "Default notification alert interacted",
parameters: [
"source": source,
"result": result.rawValue
]
)
}

static func customAlertShown(source: String) -> AnalyticsEvent {
return AnalyticsEvent(
name: "Custom notification alert shown",
parameters: [
"source": source
]
)
}

static func customAlertInteracted(source: String, result: InteractionResult) -> AnalyticsEvent {
return AnalyticsEvent(
name: "Custom notification alert interacted",
parameters: [
"source": source,
"result": result.rawValue
]
)
}

enum InteractionResult: String {
case yes
case no
}
}

struct Home {
Expand Down Expand Up @@ -302,7 +345,7 @@ struct AmplitudeAnalyticsEvents {

static func buttonPressed(id: Int, position: Int) -> AnalyticsEvent {
return AnalyticsEvent(
name: "Button pressed",
name: "Story button pressed",
parameters: [
"id": id,
"position": position
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,22 @@ class AnalyticsUserProperties: ABAnalyticsServiceProtocol {
setProperty(key: "courses_count", value: count)
}

//Not supported yet, commented out
// func setPushPermission(isGranted: Bool) {
// setProperty(key: "push_permission", value: isGranted ? "granted" : "not_granted")
// }

// func setStreaksNotificationsEnabled(isEnabled: Bool) {
// setProperty(key: "streaks_notifications_enabled", value: isEnabled ? "enabled" : "disabled")
// }
func setPushPermissionStatus(_ status: NotificationPermissionStatus) {
let key = "push_permission"

switch status {
case .authorized:
self.setProperty(key: key, value: "granted")
case .denied:
self.setProperty(key: key, value: "not_granted")
case .notDetermined:
self.setProperty(key: key, value: "not_determined")
}
}

func setStreaksNotificationsEnabled(_ enabled: Bool) {
self.setProperty(key: "streaks_notifications_enabled", value: enabled ? "enabled" : "disabled")
}

func setScreenOrientation(isPortrait: Bool) {
setProperty(key: "screen_orientation", value: isPortrait ? "portrait" : "landscape")
Expand Down
69 changes: 69 additions & 0 deletions Stepic/Analytics/NotificationAlertsAnalytics.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// NotificationAlertsAnalytics.swift
// Stepic
//
// Created by Ivan Magda on 30/10/2018.
// Copyright © 2018 Alex Karpov. All rights reserved.
//

import Foundation

struct NotificationAlertsAnalytics {
let source: Source

func reportDefaultAlertShown() {
AmplitudeAnalyticsEvents.Notifications.defaultAlertShown(
source: self.source.description
).send()
}

func reportDefaultAlertInteractionResult(
_ result: AmplitudeAnalyticsEvents.Notifications.InteractionResult
) {
AmplitudeAnalyticsEvents.Notifications.defaultAlertInteracted(
source: self.source.description,
result: result
).send()
}

func reportCustomAlertShown() {
AmplitudeAnalyticsEvents.Notifications.customAlertShown(
source: self.source.description
).send()
}

func reportCustomAlertInteractionResult(
_ result: AmplitudeAnalyticsEvents.Notifications.InteractionResult
) {
AmplitudeAnalyticsEvents.Notifications.customAlertInteracted(
source: self.source.description,
result: result
).send()
}

enum Source {
case streakControl
case notificationsTab
case courseSubscription
case streakAfterLogin
case streakAfterSubmission(shownCount: Int)
case personalDeadline

var description: String {
switch self {
case .streakControl:
return "streak control"
case .notificationsTab:
return "notifications tab"
case .courseSubscription:
return "course subscription"
case .streakAfterLogin:
return "streak after login"
case .streakAfterSubmission(let shownCount):
return "streak after submission - \(shownCount)"
case .personalDeadline:
return "create personal deadline"
}
}
}
}
27 changes: 18 additions & 9 deletions Stepic/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?

private let userNotificationsCenterDelegate = UserNotificationsCenterDelegate()
private let notificationsRegistrationService: NotificationsRegistrationServiceProtocol = NotificationsRegistrationService()

deinit {
NotificationCenter.default.removeObserver(self)
Expand Down Expand Up @@ -93,10 +94,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
self.checkForUpdates()
}

if AuthInfo.shared.isAuthorized {
NotificationRegistrator.shared.registerForRemoteNotificationsIfAlreadyAsked()
}

self.notificationsRegistrationService.renewDeviceToken()
LocalNotificationsMigrator().migrateIfNeeded()
NotificationsService().handleLaunchOptions(launchOptions)
self.userNotificationsCenterDelegate.attachNotificationDelegate()
Expand All @@ -116,6 +114,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

// MARK: - Responding to App State Changes and System Events

func applicationWillEnterForeground(_ application: UIApplication) {
self.notificationsRegistrationService.renewDeviceToken()
}

func applicationDidBecomeActive(_ application: UIApplication) {
NotificationsBadgesManager.shared.set(number: application.applicationIconBadgeNumber)
AppsFlyerTracker.shared().trackAppLaunch()
Expand All @@ -138,14 +140,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
NotificationRegistrator.shared.getGCMRegistrationToken(deviceToken: deviceToken)
self.notificationsRegistrationService.handleDeviceToken(deviceToken)
}

func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error
) {
print("error while registering to remote notifications: \(error)")
self.notificationsRegistrationService.handleRegistrationError(error)
}

func application(
Expand All @@ -160,6 +162,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
NotificationsService().handleLocalNotification(with: notification.userInfo)
}

func application(
_ application: UIApplication,
didRegister notificationSettings: UIUserNotificationSettings
) {
self.notificationsRegistrationService.handleRegisteredNotificationSettings(notificationSettings)
}

// MARK: Private Helpers

@objc
Expand All @@ -168,11 +177,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return
}

InstanceID.instanceID().instanceID { (result, error) in
InstanceID.instanceID().instanceID { [weak self] (result, error) in
if let error = error {
print("Error fetching Firebase remote instanse ID: \(error)")
print("Error fetching Firebase remote instance ID: \(error)")
} else if let result = result {
NotificationRegistrator.shared.registerDevice(result.token)
self?.notificationsRegistrationService.registerDevice(result.token)
}
}
}
Expand Down
41 changes: 0 additions & 41 deletions Stepic/AuthAfterOnboardingSplitTest.swift

This file was deleted.

2 changes: 1 addition & 1 deletion Stepic/AuthInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class AuthInfo: NSObject {
performLogoutActions()
#else
//Unregister from notifications
NotificationRegistrator.shared.unregisterFromNotifications(completion: {
NotificationsRegistrationService().unregisterFromNotifications(completion: {
performLogoutActions()
})
#endif
Expand Down
18 changes: 8 additions & 10 deletions Stepic/AuthNavigationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

import UIKit

class AuthNavigationViewController: UINavigationController {

var streaksAlertPresentationManager: StreaksAlertPresentationManager = StreaksAlertPresentationManager(source: .login)
var streaksNotificationSuggestionManager: NotificationSuggestionManager = NotificationSuggestionManager()
final class AuthNavigationViewController: UINavigationController {
private let streaksAlertPresentationManager = StreaksAlertPresentationManager(source: .login)
private let notificationSuggestionManager = NotificationSuggestionManager()
private let userActivitiesAPI = UserActivitiesAPI()

enum Controller {
case social
Expand Down Expand Up @@ -40,12 +40,10 @@ class AuthNavigationViewController: UINavigationController {
guard let userId = AuthInfo.shared.userId else {
return
}
let userActivitiesAPI = UserActivitiesAPI()
checkToken().then {
userActivitiesAPI.retrieve(user: userId)
}.done { userActivity in
if userActivity.didSolveThisWeek && self.streaksNotificationSuggestionManager.canShowAlert(context: .streak, after: .login) {
self.streaksNotificationSuggestionManager.didShowAlert(context: .streak)

self.userActivitiesAPI.retrieve(user: userId).done { userActivity in
if userActivity.didSolveThisWeek
&& self.notificationSuggestionManager.canShowAlert(context: .streak, after: .login) {
self.streaksAlertPresentationManager.suggestStreak(streak: userActivity.currentStreak)
}
}.catch { error in
Expand Down
20 changes: 19 additions & 1 deletion Stepic/BaseCardsStepsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,25 @@ class BaseCardsStepsViewController: CardsStepsViewController {
progressBar.progress = 0

if presenter == nil {
presenter = BaseCardsStepsPresenter(stepsAPI: StepsAPI(), lessonsAPI: LessonsAPI(), recommendationsAPI: RecommendationsAPI(), unitsAPI: UnitsAPI(), viewsAPI: ViewsAPI(), ratingsAPI: AdaptiveRatingsAPI(), ratingManager: AdaptiveRatingManager(courseId: course.id), statsManager: AdaptiveStatsManager(courseId: course.id), storageManager: AdaptiveStorageManager(), lastViewedUpdater: LocalProgressLastViewedUpdater(), notificationSuggestionManager: NotificationSuggestionManager(), notificationPermissionManager: NotificationPermissionManager(), course: course, view: self)
presenter = BaseCardsStepsPresenter(
stepsAPI: StepsAPI(),
lessonsAPI: LessonsAPI(),
recommendationsAPI: RecommendationsAPI(),
unitsAPI: UnitsAPI(),
viewsAPI: ViewsAPI(),
ratingsAPI: AdaptiveRatingsAPI(),
ratingManager: AdaptiveRatingManager(courseId: course.id),
statsManager: AdaptiveStatsManager(courseId: course.id),
storageManager: AdaptiveStorageManager(),
lastViewedUpdater: LocalProgressLastViewedUpdater(),
notificationSuggestionManager: NotificationSuggestionManager(),
notificationsRegistrationService: NotificationsRegistrationService(
presenter: NotificationsRequestAlertPresenter(context: .courseSubscription),
analytics: .init(source: .courseSubscription)
),
course: course,
view: self
)
presenter?.refresh()
}
}
Expand Down
Loading