mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-17 15:09:31 +02:00
MESSENGER-4101 matomo consent changes
This commit is contained in:
2
Podfile
2
Podfile
@@ -74,7 +74,7 @@ abstract_target 'RiotPods' do
|
||||
pod 'WeakDictionary', '~> 2.0'
|
||||
|
||||
# Piwik for analytics
|
||||
pod 'MatomoTracker', '~> 7.4.1'
|
||||
pod 'MatomoTracker', '~> 7.5.2'
|
||||
|
||||
# PostHog for analytics
|
||||
pod 'PostHog', '~> 2.0.0'
|
||||
|
||||
@@ -1867,7 +1867,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
matrixSessionStateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
MXSession *mxSession = (MXSession*)notif.object;
|
||||
|
||||
[BWIAnalytics.sharedTracker trackEvent:@"initMatrixSessions" action:[NSString stringWithFormat:@"%ld", mxSession.state]];
|
||||
//[BWIAnalytics.sharedTracker trackEvent:@"initMatrixSessions" action:[NSString stringWithFormat:@"%ld", mxSession.state]];
|
||||
|
||||
// Check whether the concerned session is a new one
|
||||
if (mxSession.state == MXSessionStateInitialised)
|
||||
@@ -2251,6 +2251,8 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
[topVC startActivityIndicator];
|
||||
}
|
||||
|
||||
[BWIAnalytics.sharedTracker trackEvent:@"Session" action:@"Logout"];
|
||||
|
||||
[self logoutSendingRequestServer:YES completion:^(BOOL isLoggedOut) {
|
||||
if (completion)
|
||||
{
|
||||
@@ -2258,7 +2260,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
{
|
||||
//[RiotSettings.shared reset];
|
||||
[BWIBuildSettings.shared reset];
|
||||
[BWIAnalytics.sharedTracker trackEvent:@"Session" action:@"Logout"];
|
||||
[BWIAnalytics.sharedTracker resetUserdefaults];
|
||||
|
||||
}
|
||||
completion (YES);
|
||||
@@ -2329,6 +2331,8 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
[topVC startActivityIndicator];
|
||||
}
|
||||
|
||||
[BWIAnalytics.sharedTracker trackEvent:@"Session" action:@"Logout"];
|
||||
|
||||
[self logoutSendingRequestServer:YES completion:^(BOOL isLoggedOut) {
|
||||
if (completion)
|
||||
{
|
||||
@@ -2336,7 +2340,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
{
|
||||
//[RiotSettings.shared reset];
|
||||
[BWIBuildSettings.shared reset];
|
||||
[BWIAnalytics.sharedTracker trackEvent:@"Session" action:@"Logout"];
|
||||
[BWIAnalytics.sharedTracker resetUserdefaults];
|
||||
|
||||
}
|
||||
completion (YES);
|
||||
@@ -2431,7 +2435,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
|
||||
if (mainSession)
|
||||
{
|
||||
[BWIAnalytics.sharedTracker trackEvent:@"handleAppState" action:[MXTools readableSessionState:mainSession.state]];
|
||||
//[BWIAnalytics.sharedTracker trackEvent:@"handleAppState" action:[MXTools readableSessionState:mainSession.state]];
|
||||
|
||||
switch (mainSession.state)
|
||||
{
|
||||
@@ -2616,7 +2620,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
MXLogDebug(@"[AppDelegate] hideLaunchAnimation: LaunchAnimation was shown for %.3fms", launchTaskProfile.duration * 1000);
|
||||
}
|
||||
|
||||
[BWIAnalytics.sharedTracker trackEvent:@"hideLaunchAnimation" action:@"Hide"];
|
||||
//[BWIAnalytics.sharedTracker trackEvent:@"hideLaunchAnimation" action:@"Hide"];
|
||||
[self->launchAnimationContainerView removeFromSuperview];
|
||||
self->launchAnimationContainerView = nil;
|
||||
}
|
||||
@@ -3980,7 +3984,6 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||
[(MXLegacyCrypto *)crypto setOutgoingKeyRequestsEnabled:YES onComplete:nil];
|
||||
}
|
||||
[self dismissKeyVerificationCoordinatorBridgePresenter];
|
||||
[BWIAnalytics.sharedTracker trackEvent:@"Session" action:@"Login"];
|
||||
}
|
||||
|
||||
- (void)keyVerificationCoordinatorBridgePresenterDelegateDidCancel:(KeyVerificationCoordinatorBridgePresenter * _Nonnull)coordinatorBridgePresenter
|
||||
|
||||
@@ -154,6 +154,8 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
self.bwiCheckForMatomoPromt()
|
||||
}
|
||||
|
||||
func bwiOnUnlockedByPin() {
|
||||
@@ -702,6 +704,13 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol {
|
||||
service.createPersonalNotesRoomIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
// bwi: check if matomo promt was shown for this session
|
||||
private func bwiCheckForMatomoPromt() {
|
||||
if BWIBuildSettings.shared.bwiMatomoEnabled && BWIAnalytics.sharedTracker.needsToShowPromt() {
|
||||
self.allChatsViewController.bwiPresentMatomoConsentAlert()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension AllChatsCoordinator: SignOutFlowPresenterDelegate {
|
||||
@@ -724,6 +733,7 @@ extension AllChatsCoordinator: SignOutFlowPresenterDelegate {
|
||||
extension AllChatsCoordinator: AllChatsViewControllerDelegate {
|
||||
func allChatsViewControllerDidCompleteAuthentication(_ allChatsViewController: AllChatsViewController) {
|
||||
self.delegate?.splitViewMasterCoordinatorDidCompleteAuthentication(self)
|
||||
self.bwiCheckForMatomoPromt()
|
||||
}
|
||||
|
||||
func allChatsViewController(_ allChatsViewController: AllChatsViewController, didSelectRoomWithParameters roomNavigationParameters: RoomNavigationParameters, completion: @escaping () -> Void) {
|
||||
|
||||
@@ -292,6 +292,37 @@ class AllChatsViewController: HomeViewController {
|
||||
super.startActivityIndicator()
|
||||
}
|
||||
|
||||
func bwiPresentMatomoConsentAlert() {
|
||||
let alert = UIAlertController(title: BWIL10n.bwiAnalyticsAlertTitle,
|
||||
message: BWIL10n.bwiAnalyticsAlertBody(AppInfo.current.displayName),
|
||||
preferredStyle: .alert)
|
||||
|
||||
alert.addAction(UIAlertAction(title: BWIL10n.bwiAnalyticsAlertInfoButton,
|
||||
style: .default,
|
||||
handler: { action in
|
||||
if let webviewController = WebViewViewController(url: BWIBuildSettings.shared.applicationPrivacyPolicyUrlString) {
|
||||
webviewController.title = VectorL10n.settingsPrivacyPolicy
|
||||
|
||||
self.present(webviewController, animated: true)
|
||||
}
|
||||
}))
|
||||
|
||||
alert.addAction(UIAlertAction(title: BWIL10n.bwiAnalyticsAlertCancelButton,
|
||||
style: .default,
|
||||
handler: { action in
|
||||
BWIAnalytics.sharedTracker.running = false
|
||||
}))
|
||||
|
||||
alert.addAction(UIAlertAction(title: BWIL10n.bwiAnalyticsAlertOkButton,
|
||||
style: .cancel,
|
||||
handler: { action in
|
||||
BWIAnalytics.sharedTracker.running = true
|
||||
BWIAnalytics.sharedTracker.trackBwiValue(0, "General", "ConsentGiven", "popup")
|
||||
}))
|
||||
|
||||
self.present(alert, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc private func showSpaceSelectorAction(sender: AnyObject) {
|
||||
|
||||
@@ -1916,6 +1916,10 @@ TableViewSectionsDelegate>
|
||||
BOOL isOn = sender.on;
|
||||
|
||||
BWIAnalytics.sharedTracker.running = isOn;
|
||||
|
||||
if (isOn) {
|
||||
[BWIAnalytics.sharedTracker trackBwiValue:@0 :@"General" :@"ConsentGiven" :@"settings"];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1123,9 +1123,7 @@
|
||||
[alert addAction:[UIAlertAction actionWithTitle:BWIL10n.bwiAnalyticsAlertOkButton style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
|
||||
BWIAnalytics.sharedTracker.running = YES;
|
||||
}]];
|
||||
[self presentViewController:alert animated:YES completion:^() {
|
||||
[BWIAnalytics.sharedTracker setPromtShown:YES];
|
||||
}];
|
||||
[self presentViewController:alert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -48,7 +48,7 @@ struct DeveloperSettingsView: View {
|
||||
Alert(title: Text(BWIL10n.bwiSettingsDeveloper), dismissButton: .default(Text("Ok")))
|
||||
}
|
||||
|
||||
Button(action: { showAlert = resetMatomoInfoScreen() }) {
|
||||
Button(action: { showAlert = resetMatomoInfoScreen(mxSession: session) }) {
|
||||
Text(BWIL10n.bwiSettingsDeveloperResetMatomoInfo)
|
||||
.foregroundColor(Color(ThemeService.shared().theme.tintColor))
|
||||
.font(.system(size: 17))
|
||||
@@ -122,8 +122,12 @@ fileprivate func createNewPersonalNotesRoom(mxSession: MXSession?) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
fileprivate func resetMatomoInfoScreen() -> Bool {
|
||||
BWIAnalytics.sharedTracker.setPromtShown(false)
|
||||
fileprivate func resetMatomoInfoScreen(mxSession: MXSession?) -> Bool {
|
||||
guard let mxSession = mxSession else {
|
||||
return false
|
||||
}
|
||||
// FRROT
|
||||
BWIAnalyticsAccountDataService(mxSession: mxSession)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ import MatomoTracker
|
||||
guard let session = session else {
|
||||
return false
|
||||
}
|
||||
|
||||
return BWIAnalyticsAccountDataService(mxSession: session).isEnabled()
|
||||
}
|
||||
set(enabled) {
|
||||
guard let session = session else {
|
||||
return
|
||||
}
|
||||
fastRunning = enabled
|
||||
BWIAnalyticsAccountDataService(mxSession: session).setEnabled(enabled)
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,9 @@ import MatomoTracker
|
||||
private let appVersion: String
|
||||
private let appPlattform = "iOS"
|
||||
|
||||
// use internally to not always check for Account data
|
||||
private var fastRunning: Bool = false
|
||||
|
||||
var session: MXSession? = nil
|
||||
|
||||
private override init() {
|
||||
@@ -66,6 +69,7 @@ import MatomoTracker
|
||||
|
||||
matomo?.setCustomVariable(withIndex: 1, name: "App Platform", value: appPlattform)
|
||||
matomo?.setCustomVariable(withIndex: 2, name: "App Version", value: appVersion)
|
||||
|
||||
} else {
|
||||
matomo = nil
|
||||
}
|
||||
@@ -75,6 +79,24 @@ import MatomoTracker
|
||||
return matomo != nil
|
||||
}
|
||||
|
||||
// reset clientId on logout using internal matomo keys
|
||||
func resetUserdefaults() {
|
||||
|
||||
if let userdefaults = UserDefaults(suiteName: "1https://matomo.example.com/matomo.php") {
|
||||
userdefaults.removeObject(forKey: "PiwikTotalNumberOfVistsKey")
|
||||
userdefaults.removeObject(forKey: "PiwikCurrentVisitTimestampKey")
|
||||
userdefaults.removeObject(forKey: "PiwikPreviousVistsTimestampKey")
|
||||
userdefaults.removeObject(forKey: "PiwikFirstVistsTimestampKey")
|
||||
userdefaults.removeObject(forKey: "PiwikVisitorIDKey")
|
||||
userdefaults.removeObject(forKey: "PiwikForcedVisitorIDKey")
|
||||
userdefaults.removeObject(forKey: "PiwikVisitorUserIDKey")
|
||||
userdefaults.removeObject(forKey: "PiwikOptOutKey")
|
||||
userdefaults.removeObject(forKey: "PiwikLastOrderDateKey")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Uses Userdefaults instead of Account Data because it needs to be shown on every login
|
||||
func needsToShowPromt() -> Bool {
|
||||
if !BWIBuildSettings.shared.bwiEnableErrorTracking {
|
||||
return false
|
||||
@@ -84,43 +106,35 @@ import MatomoTracker
|
||||
return false
|
||||
}
|
||||
|
||||
return !BWIAccountNotificationService(mxSession: session).isNotificationShown(BWIAccountNotificationService.AccountNotifications.CodingKeys.analyticsPromt.rawValue)
|
||||
}
|
||||
|
||||
func setPromtShown(_ shown: Bool) {
|
||||
guard let session = session else {
|
||||
return
|
||||
}
|
||||
|
||||
BWIAccountNotificationService(mxSession: session).setNotification(BWIAccountNotificationService.AccountNotifications.CodingKeys.analyticsPromt.rawValue, shown: shown)
|
||||
return BWIAnalyticsAccountDataService(mxSession: session).needsToShowPromt()
|
||||
}
|
||||
|
||||
func trackScreen(_ screenName: String) {
|
||||
if running {
|
||||
if fastRunning {
|
||||
matomo?.track(view: ["ios", appName, appVersion, screenName], url: nil)
|
||||
}
|
||||
}
|
||||
|
||||
func trackEvent(_ category: String, action: String) {
|
||||
if running {
|
||||
if fastRunning {
|
||||
matomo?.track(eventWithCategory: category, action: action, url:nil)
|
||||
}
|
||||
}
|
||||
|
||||
func trackBwiDuration(_ duration: TimeInterval, _ category: String, _ name: String) {
|
||||
if running {
|
||||
if fastRunning {
|
||||
matomo?.track(eventWithCategory: "Metrics", action: category, name: name, number: NSNumber(value: duration), url:nil)
|
||||
}
|
||||
}
|
||||
|
||||
func trackBwiValue(_ value: NSNumber, _ category: String, _ action: String) {
|
||||
if running {
|
||||
if fastRunning {
|
||||
matomo?.track(eventWithCategory: category, action: action, name: nil, number: value, url:nil)
|
||||
}
|
||||
}
|
||||
|
||||
func trackBwiValue(_ value: NSNumber, _ category: String, _ action: String, _ name: String) {
|
||||
if running {
|
||||
if fastRunning {
|
||||
matomo?.track(eventWithCategory: category, action: action, name: name, number: value, url:nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,21 @@ import Foundation
|
||||
private struct AccountAnalytics: Codable {
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case analyticsEnabled = "enabled"
|
||||
case consent
|
||||
case time
|
||||
case platform
|
||||
case appVersion = "app_version"
|
||||
}
|
||||
|
||||
let consent: Bool
|
||||
let time: Int
|
||||
let platform: String
|
||||
let appVersion: String
|
||||
|
||||
func toJsonDict() -> [String : Any] {
|
||||
return [CodingKeys.consent.rawValue:consent, CodingKeys.time.rawValue:time, CodingKeys.platform.rawValue:platform, CodingKeys.appVersion.rawValue:appVersion]
|
||||
}
|
||||
|
||||
let analyticsEnabled: Bool
|
||||
}
|
||||
|
||||
private enum AccountDataTypes {
|
||||
@@ -36,17 +47,32 @@ import Foundation
|
||||
private lazy var serializationService: SerializationServiceType = SerializationService()
|
||||
|
||||
init(mxSession: MXSession) {
|
||||
self.session = mxSession
|
||||
session = mxSession
|
||||
}
|
||||
|
||||
func needsToShowPromt() -> Bool {
|
||||
guard let analyticsArray = session.accountData.accountData(forEventType: AccountDataTypes.analytics) as? [String: Any] else {
|
||||
return true
|
||||
}
|
||||
guard analyticsArray[session.myDeviceId] is [String: Any] else {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isEnabled() -> Bool {
|
||||
guard let analyticsDict = session.accountData.accountData(forEventType: AccountDataTypes.analytics) as? [String: Any] else {
|
||||
guard let analyticsArray = session.accountData.accountData(forEventType: AccountDataTypes.analytics) as? [String: Any] else {
|
||||
return false
|
||||
}
|
||||
|
||||
guard let deviceId = session.myDeviceId, let analyticsDict = analyticsArray[deviceId] as? [String: Any] else {
|
||||
return false
|
||||
}
|
||||
|
||||
do {
|
||||
let analytics: AccountAnalytics = try serializationService.deserialize(analyticsDict)
|
||||
|
||||
return analytics.analyticsEnabled
|
||||
return analytics.consent
|
||||
} catch {
|
||||
|
||||
}
|
||||
@@ -56,8 +82,11 @@ import Foundation
|
||||
|
||||
func setEnabled(_ enabled: Bool) {
|
||||
var analyticsDict = session.accountData.accountData(forEventType: AccountDataTypes.analytics) ?? [:]
|
||||
analyticsDict[AccountAnalytics.CodingKeys.analyticsEnabled.rawValue] = enabled
|
||||
|
||||
let currentConsent = AccountAnalytics(consent: enabled, time: Int(Date().timeIntervalSince1970*1000), platform: "ios", appVersion: AppInfo.current.appVersion?.bundleShortVersion ?? "")
|
||||
|
||||
analyticsDict[session.myDeviceId] = currentConsent.toJsonDict()
|
||||
|
||||
session.setAccountData(analyticsDict, forType: AccountDataTypes.analytics, success: nil, failure: nil)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user