Skip to content

Commit

Permalink
chore: added abstract layer for push notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
rnr committed Jan 24, 2024
1 parent fe14ca8 commit a6fc40d
Show file tree
Hide file tree
Showing 14 changed files with 259 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Core/Core.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
07DDFCBD29A780BB00572595 /* UINavigationController+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07DDFCBC29A780BB00572595 /* UINavigationController+Animation.swift */; };
07E0939F2B308D2800F1E4B2 /* Data_Certificate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07E0939E2B308D2800F1E4B2 /* Data_Certificate.swift */; };
A53A32352B233DEC005FE38A /* ThemeConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = A53A32342B233DEC005FE38A /* ThemeConfig.swift */; };
A5F4E7B52B61544A00ACD166 /* BrazeConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5F4E7B42B61544A00ACD166 /* BrazeConfig.swift */; };
BA30427F2B20B320009B64B7 /* SocialAuthError.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA30427D2B20B299009B64B7 /* SocialAuthError.swift */; };
BA593F1C2AF8E498009ADB51 /* ScrollSlidingTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA593F1B2AF8E498009ADB51 /* ScrollSlidingTabBar.swift */; };
BA593F1E2AF8E4A0009ADB51 /* FrameReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA593F1D2AF8E4A0009ADB51 /* FrameReader.swift */; };
Expand Down Expand Up @@ -294,6 +295,7 @@
60153262DBC2F9E660D7E11B /* Pods-App-Core.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Core.release.xcconfig"; path = "Target Support Files/Pods-App-Core/Pods-App-Core.release.xcconfig"; sourceTree = "<group>"; };
9D5B06CAA99EA5CD49CBE2BB /* Pods-App-Core.debugdev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Core.debugdev.xcconfig"; path = "Target Support Files/Pods-App-Core/Pods-App-Core.debugdev.xcconfig"; sourceTree = "<group>"; };
A53A32342B233DEC005FE38A /* ThemeConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeConfig.swift; sourceTree = "<group>"; };
A5F4E7B42B61544A00ACD166 /* BrazeConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrazeConfig.swift; sourceTree = "<group>"; };
BA30427D2B20B299009B64B7 /* SocialAuthError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocialAuthError.swift; sourceTree = "<group>"; };
BA593F1B2AF8E498009ADB51 /* ScrollSlidingTabBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollSlidingTabBar.swift; sourceTree = "<group>"; };
BA593F1D2AF8E4A0009ADB51 /* FrameReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrameReader.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -749,6 +751,7 @@
0604C9A92B22FACF00AD5DBF /* UIComponentsConfig.swift */,
0727876F28D23411002E9142 /* Config.swift */,
DBF6F2402B014ADA0098414B /* FirebaseConfig.swift */,
A5F4E7B42B61544A00ACD166 /* BrazeConfig.swift */,
DBF6F2492B0380E00098414B /* FeaturesConfig.swift */,
DBF6F2452B01DAFE0098414B /* AgreementConfig.swift */,
BAFB99812B0E2354007D09F9 /* FacebookConfig.swift */,
Expand Down Expand Up @@ -1054,6 +1057,7 @@
DBF6F2412B014ADA0098414B /* FirebaseConfig.swift in Sources */,
072787B628D37A0E002E9142 /* Validator.swift in Sources */,
0236961D28F9A2D200EEF206 /* Data_AuthResponse.swift in Sources */,
A5F4E7B52B61544A00ACD166 /* BrazeConfig.swift in Sources */,
02AFCC182AEFDB24000360F0 /* ThirdPartyMailClient.swift in Sources */,
0233D5712AF13EC800BAC8BD /* SelectMailClientView.swift in Sources */,
BAFB99842B0E282E007D09F9 /* MicrosoftConfig.swift in Sources */,
Expand Down
32 changes: 32 additions & 0 deletions Core/Core/Configuration/Config/BrazeConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// BrazeConfig.swift
// Core
//
// Created by Anton Yarmolenka on 24/01/2024.
//

import Foundation

private enum BrazeKeys: String {
case enabled = "ENABLED"
case pushNotificationsEnabled = "PUSH_NOTIFICATIONS_ENABLED"
}

public final class BrazeConfig: NSObject {
public var enabled: Bool = false
public var pushNotificationsEnabled: Bool = false

init(dictionary: [String: AnyObject]) {
super.init()
enabled = dictionary[BrazeKeys.enabled.rawValue] as? Bool == true
let pushNotificationsEnabled = dictionary[BrazeKeys.pushNotificationsEnabled.rawValue] as? Bool ?? false
self.pushNotificationsEnabled = enabled && pushNotificationsEnabled
}
}

private let brazeKey = "BRAZE"
extension Config {
public var braze: BrazeConfig {
BrazeConfig(dictionary: self[brazeKey] as? [String: AnyObject] ?? [:])
}
}
1 change: 1 addition & 0 deletions Core/Core/Configuration/Config/Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public protocol ConfigProtocol {
var theme: ThemeConfig { get }
var uiComponents: UIComponentsConfig { get }
var discovery: DiscoveryConfig { get }
var braze: BrazeConfig { get }
}

public enum TokenType: String {
Expand Down
10 changes: 10 additions & 0 deletions Core/CoreTests/Configuration/ConfigTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ class ConfigTests: XCTestCase {
],
"APPLE_SIGNIN": [
"ENABLED": true
],
"BRAZE": [
"ENABLED": true,
"PUSH_NOTIFICATIONS_ENABLED": true
]
]

Expand Down Expand Up @@ -115,4 +119,10 @@ class ConfigTests: XCTestCase {

XCTAssertTrue(config.appleSignIn.enabled)
}

func testBrazeConfigInitialization() {
let config = Config(properties: properties)

XCTAssertTrue(config.braze.pushNotificationsEnabled)
}
}
64 changes: 62 additions & 2 deletions OpenEdX.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
07D5DA3E28D075AB00752FD9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 07D5DA3D28D075AB00752FD9 /* Assets.xcassets */; };
07D5DA4128D075AB00752FD9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 07D5DA3F28D075AB00752FD9 /* LaunchScreen.storyboard */; };
95C140F3BDF778364986E83B /* Pods_App_OpenEdX.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F138C15C3A2515F8F94DAA8B /* Pods_App_OpenEdX.framework */; };
A500668B2B613ED10024680B /* PushNotificationsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A500668A2B613ED10024680B /* PushNotificationsManager.swift */; };
A500668D2B6143000024680B /* FCMProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A500668C2B6143000024680B /* FCMProvider.swift */; };
A50066912B61467B0024680B /* BrazeProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50066902B61467B0024680B /* BrazeProvider.swift */; };
A50066932B614DCD0024680B /* FCMListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50066922B614DCD0024680B /* FCMListener.swift */; };
A50066952B614DEF0024680B /* BrazeListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50066942B614DEF0024680B /* BrazeListener.swift */; };
BA3042792B1F7147009B64B7 /* MSAL in Frameworks */ = {isa = PBXBuildFile; productRef = BA3042782B1F7147009B64B7 /* MSAL */; };
E0D6E6A32B1626B10089F9C9 /* Theme.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E0D6E6A22B1626B10089F9C9 /* Theme.framework */; };
E0D6E6A42B1626D60089F9C9 /* Theme.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E0D6E6A22B1626B10089F9C9 /* Theme.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
Expand Down Expand Up @@ -115,6 +120,11 @@
6F54C19C823A769E18923FA8 /* Pods-App-OpenEdX.debugstage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-OpenEdX.debugstage.xcconfig"; path = "Target Support Files/Pods-App-OpenEdX/Pods-App-OpenEdX.debugstage.xcconfig"; sourceTree = "<group>"; };
8284179FC05AEE2591573E20 /* Pods-App-OpenEdX.debugdev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-OpenEdX.debugdev.xcconfig"; path = "Target Support Files/Pods-App-OpenEdX/Pods-App-OpenEdX.debugdev.xcconfig"; sourceTree = "<group>"; };
A24D6A8E1BC4DF46AD68904C /* Pods-App-OpenEdX.releaseprod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-OpenEdX.releaseprod.xcconfig"; path = "Target Support Files/Pods-App-OpenEdX/Pods-App-OpenEdX.releaseprod.xcconfig"; sourceTree = "<group>"; };
A500668A2B613ED10024680B /* PushNotificationsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationsManager.swift; sourceTree = "<group>"; };
A500668C2B6143000024680B /* FCMProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FCMProvider.swift; sourceTree = "<group>"; };
A50066902B61467B0024680B /* BrazeProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrazeProvider.swift; sourceTree = "<group>"; };
A50066922B614DCD0024680B /* FCMListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FCMListener.swift; sourceTree = "<group>"; };
A50066942B614DEF0024680B /* BrazeListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrazeListener.swift; sourceTree = "<group>"; };
A89AD827F52CF6A6B903606E /* Pods-App-OpenEdX.releasestage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-OpenEdX.releasestage.xcconfig"; path = "Target Support Files/Pods-App-OpenEdX/Pods-App-OpenEdX.releasestage.xcconfig"; sourceTree = "<group>"; };
BB08ACD2CCA33D6DDDDD31B4 /* Pods-App-OpenEdX.releasedev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-OpenEdX.releasedev.xcconfig"; path = "Target Support Files/Pods-App-OpenEdX/Pods-App-OpenEdX.releasedev.xcconfig"; sourceTree = "<group>"; };
E0D6E6A22B1626B10089F9C9 /* Theme.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Theme.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -200,8 +210,7 @@
07D5DA3428D075AA00752FD9 /* AppDelegate.swift */,
0770DE1628D080A1006D8A5D /* RouteController.swift */,
0770DE1F28D0858A006D8A5D /* Router.swift */,
0298DF2F2A4EF7230023A257 /* AnalyticsManager.swift */,
02F175302A4DA95B0019CD70 /* MainScreenAnalytics.swift */,
A50066882B613E800024680B /* Managers */,
0293A2012A6FC9E30090A336 /* Data */,
0727878C28D347B2002E9142 /* View */,
0770DE1A28D084BC006D8A5D /* DI */,
Expand Down Expand Up @@ -248,6 +257,52 @@
path = Pods;
sourceTree = "<group>";
};
A50066872B613E4B0024680B /* PushNotificationsManager */ = {
isa = PBXGroup;
children = (
A500668A2B613ED10024680B /* PushNotificationsManager.swift */,
A50066962B614F0C0024680B /* Providers */,
A50066972B614F2B0024680B /* Listeners */,
);
path = PushNotificationsManager;
sourceTree = "<group>";
};
A50066882B613E800024680B /* Managers */ = {
isa = PBXGroup;
children = (
A50066872B613E4B0024680B /* PushNotificationsManager */,
A50066892B613E990024680B /* AnalyticsManager */,
);
path = Managers;
sourceTree = "<group>";
};
A50066892B613E990024680B /* AnalyticsManager */ = {
isa = PBXGroup;
children = (
0298DF2F2A4EF7230023A257 /* AnalyticsManager.swift */,
02F175302A4DA95B0019CD70 /* MainScreenAnalytics.swift */,
);
path = AnalyticsManager;
sourceTree = "<group>";
};
A50066962B614F0C0024680B /* Providers */ = {
isa = PBXGroup;
children = (
A500668C2B6143000024680B /* FCMProvider.swift */,
A50066902B61467B0024680B /* BrazeProvider.swift */,
);
path = Providers;
sourceTree = "<group>";
};
A50066972B614F2B0024680B /* Listeners */ = {
isa = PBXGroup;
children = (
A50066922B614DCD0024680B /* FCMListener.swift */,
A50066942B614DEF0024680B /* BrazeListener.swift */,
);
path = Listeners;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -413,21 +468,26 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A500668B2B613ED10024680B /* PushNotificationsManager.swift in Sources */,
0293A2052A6FCD430090A336 /* CoursePersistence.swift in Sources */,
020CA5D92AA0A25300970AAF /* AppStorage.swift in Sources */,
0298DF302A4EF7230023A257 /* AnalyticsManager.swift in Sources */,
A50066912B61467B0024680B /* BrazeProvider.swift in Sources */,
0293A2072A6FCDA30090A336 /* DiscoveryPersistence.swift in Sources */,
07D5DA3528D075AA00752FD9 /* AppDelegate.swift in Sources */,
02F175312A4DA95B0019CD70 /* MainScreenAnalytics.swift in Sources */,
0727878E28D347C7002E9142 /* MainScreenView.swift in Sources */,
0770DE5028D0A707006D8A5D /* NetworkAssembly.swift in Sources */,
0293A2032A6FCA590090A336 /* CorePersistence.swift in Sources */,
0770DE1E28D084E8006D8A5D /* AppAssembly.swift in Sources */,
A50066932B614DCD0024680B /* FCMListener.swift in Sources */,
A500668D2B6143000024680B /* FCMProvider.swift in Sources */,
025AD4AC2A6FB95C00AB8FA7 /* DatabaseManager.swift in Sources */,
024E69202AEFC3FB00FA0B59 /* MainScreenViewModel.swift in Sources */,
0770DE2028D0858A006D8A5D /* Router.swift in Sources */,
0293A2092A6FCDE50090A336 /* DashboardPersistence.swift in Sources */,
0770DE1728D080A1006D8A5D /* RouteController.swift in Sources */,
A50066952B614DEF0024680B /* BrazeListener.swift in Sources */,
071009C928D1DB3F00344290 /* ScreenAssembly.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
14 changes: 14 additions & 0 deletions OpenEdX/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
window?.rootViewController = RouteController()
}

// Push Notifications
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let pushManager = Container.shared.resolve(PushNotificationsManager.self)!
pushManager.didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: deviceToken)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
let pushManager = Container.shared.resolve(PushNotificationsManager.self)!
pushManager.didFailToRegisterForRemoteNotificationsWithError(error: error)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let pushManager = Container.shared.resolve(PushNotificationsManager.self)!
pushManager.didReceiveRemoteNotification(userInfo: userInfo)
completionHandler(.newData)
}
}
6 changes: 6 additions & 0 deletions OpenEdX/DI/AppAssembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ class AppAssembly: Assembly {
container.register(Validator.self) { _ in
Validator()
}.inObjectScope(.container)

container.register(PushNotificationsManager.self) { r in
PushNotificationsManager(
config: r.resolve(ConfigProtocol.self)!
)
}.inObjectScope(.container)
}
}
// swiftlint:enable function_body_length
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// BrazeListener.swift
// OpenEdX
//
// Created by Anton Yarmolenka on 24/01/2024.
//

import Foundation

class BrazeListener: PushNotificationsListener {
func didReceiveRemoteNotification(userInfo: [AnyHashable: Any]) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// FCMListener.swift
// OpenEdX
//
// Created by Anton Yarmolenka on 24/01/2024.
//

import Foundation

class FCMListener: PushNotificationsListener {
func didReceiveRemoteNotification(userInfo: [AnyHashable: Any]) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// BrazeProvider.swift
// OpenEdX
//
// Created by Anton Yarmolenka on 24/01/2024.
//

import Foundation

class BrazeProvider: PushNotificationsProvider {
func didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: Data) {

}
func didFailToRegisterForRemoteNotificationsWithError(error: Error) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// FCMProvider.swift
// OpenEdX
//
// Created by Anton Yarmolenka on 24/01/2024.
//

import Foundation

class FCMProvider: PushNotificationsProvider {
func didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: Data) {

}
func didFailToRegisterForRemoteNotificationsWithError(error: Error) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// PushNotificationManager.swift
// OpenEdX
//
// Created by Anton Yarmolenka on 24/01/2024.
//

import Foundation
import Core

public protocol PushNotificationsProvider {
func didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: Data)
func didFailToRegisterForRemoteNotificationsWithError(error: Error)
}

protocol PushNotificationsListener {
func didReceiveRemoteNotification(userInfo: [AnyHashable: Any])
}

class PushNotificationsManager {
private var providers: [PushNotificationsProvider] = []
private var listeners: [PushNotificationsListener] = []

// Init manager
public init(config: ConfigProtocol) {
self.providers = self.providersFor(config: config)
self.listeners = self.listenersFor(config: config)
}

private func providersFor(config: ConfigProtocol) -> [PushNotificationsProvider] {
var rProviders: [PushNotificationsProvider] = []
if config.firebase.cloudMessagingEnabled {
rProviders.append(FCMProvider())
}
if config.braze.pushNotificationsEnabled {
rProviders.append(BrazeProvider())
}
return rProviders
}

private func listenersFor(config: ConfigProtocol) -> [PushNotificationsListener] {
var rListeners: [PushNotificationsListener] = []
if config.firebase.cloudMessagingEnabled {
rListeners.append(FCMListener())
}
if config.braze.pushNotificationsEnabled {
rListeners.append(BrazeListener())
}
return rListeners
}

// Proccess functions from app delegate
public func didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: Data) {
for provider in providers {
provider.didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: deviceToken)
}
}
public func didFailToRegisterForRemoteNotificationsWithError(error: Error) {
for provider in providers {
provider.didFailToRegisterForRemoteNotificationsWithError(error: error)
}
}
public func didReceiveRemoteNotification(userInfo: [AnyHashable: Any]) {
for listener in listeners {
listener.didReceiveRemoteNotification(userInfo: userInfo)
}
}
}

0 comments on commit a6fc40d

Please sign in to comment.