Skip to content

Commit

Permalink
✨ Add push status device properties
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaatttt authored and iujames committed Sep 17, 2024
1 parent 349aed8 commit dbd4a7a
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
1 change: 1 addition & 0 deletions Sources/AppcuesKit/Appcues.swift
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ public class Appcues: NSObject {
container.registerLazy(ActivityProcessing.self, initializer: ActivityProcessor.init)
container.registerLazy(ActivityStoring.self, initializer: ActivityFileStorage.init)
container.registerLazy(AnalyticsBroadcaster.self, initializer: AnalyticsBroadcaster.init)
container.registerLazy(PushMonitoring.self, initializer: PushMonitor.init)

if #available(iOS 13.0, *) {
container.registerLazy(DeepLinkHandling.self, initializer: DeepLinkHandler.init)
Expand Down
8 changes: 5 additions & 3 deletions Sources/AppcuesKit/Data/Analytics/AutoPropertyDecorator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ internal class AutoPropertyDecorator: AnalyticsDecorating {

private weak var appcues: Appcues?
private let storage: DataStoring
private let pushMonitor: PushMonitoring
private let config: Appcues.Config

// these are the fixed values for the duration of the app runtime
Expand Down Expand Up @@ -50,6 +51,7 @@ internal class AutoPropertyDecorator: AnalyticsDecorating {
init(container: DIContainer) {
self.appcues = container.owner
self.storage = container.resolve(DataStoring.self)
self.pushMonitor = container.resolve(PushMonitoring.self)
self.config = container.resolve(Appcues.Config.self)
}

Expand Down Expand Up @@ -123,7 +125,7 @@ internal class AutoPropertyDecorator: AnalyticsDecorating {
}

switch tracking.type {
case .event(Events.Session.sessionStarted.rawValue, _),
case .event(Events.Session.sessionStarted.rawValue, _),
.event(Events.Device.deviceUpdated.rawValue, _),
.event(Events.Device.deviceUnregistered.rawValue, _):
decorated.deviceAutoProperties = deviceAutoProperties().merging(applicationProperties)
Expand All @@ -143,10 +145,10 @@ internal class AutoPropertyDecorator: AnalyticsDecorating {
var properties = [
"_deviceId": storage.deviceID,
"_pushToken": pushToken,
"_pushEnabled": pushMonitor.pushEnabled,
"_pushEnabledBackground": pushMonitor.pushBackgroundEnabled,
// TODO: more properties
// _pushSubscriptionStatus
// _pushEnabled
// _pushEnabledBackground
]

if let language = deviceLanguage {
Expand Down
64 changes: 64 additions & 0 deletions Sources/AppcuesKit/Data/PushMonitor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// PushMonitor.swift
// AppcuesKit
//
// Created by Matt on 2024-02-22.
// Copyright © 2024 Appcues. All rights reserved.
//

import UIKit

internal protocol PushMonitoring: AnyObject {
var pushEnabled: Bool { get }
var pushBackgroundEnabled: Bool { get }
}

internal class PushMonitor: PushMonitoring {

private let storage: DataStoring

private var pushAuthorizationStatus: UNAuthorizationStatus = .notDetermined

var pushEnabled: Bool {
pushAuthorizationStatus == .authorized && storage.pushToken != nil
}

var pushBackgroundEnabled: Bool {
storage.pushToken != nil
}

init(container: DIContainer) {
self.storage = container.resolve(DataStoring.self)

refreshPushStatus()

NotificationCenter.default.addObserver(
self,
selector: #selector(applicationWillEnterForeground),
name: UIApplication.willEnterForegroundNotification,
object: nil
)
}

@objc
private func applicationWillEnterForeground(notification: Notification) {
refreshPushStatus()
}

private func refreshPushStatus() {
// Skip call to UNUserNotificationCenter.current() in tests to avoid crashing in package tests
#if DEBUG
guard ProcessInfo.processInfo.environment["XCTestBundlePath"] == nil else { return }
#endif

UNUserNotificationCenter.current().getNotificationSettings { [weak self] settings in
self?.pushAuthorizationStatus = settings.authorizationStatus
}
}

#if DEBUG
func mockPushStatus(_ status: UNAuthorizationStatus) {
pushAuthorizationStatus = status
}
#endif
}

0 comments on commit dbd4a7a

Please sign in to comment.