Skip to content

Commit 4da002e

Browse files
committed
Session data and purchases become Deltas first, not Requests
* session_count, session_time, and purchases are not model-driven. We were turning their data into `OSRequestUpdateProperties` instances immediately instead of enqueueing as Deltas first. This means they could not be combined with other User Updates in a single request. * Now, when they will send their data to the User Manager, it will manually enqueue a Delta onto the Operation Repo. * Previously, we used a flag to indicate if we should send these requests immediately (meaning the app is backgrounded), but that is no longer needed because the Deltas are enqueued to the Operation Repo, and then the Operation Repo has its own background task to flush.
1 parent 504f41f commit 4da002e

File tree

3 files changed

+33
-76
lines changed

3 files changed

+33
-76
lines changed

iOS_SDK/OneSignalSDK/OneSignalOSCore/Source/OSOperationRepo.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,14 @@ public class OSOperationRepo: NSObject {
100100
}
101101
}
102102

103-
func enqueueDelta(_ delta: OSDelta) {
103+
/**
104+
Enqueueing is driven by model changes and called manually by the User Manager to
105+
add session time, session count and purchase data.
106+
107+
// TODO: We can make this method internal once there is no manual adding of a Delta except through stores.
108+
This can happen when session data and purchase data use the model / store / listener infrastructure.
109+
*/
110+
public func enqueueDelta(_ delta: OSDelta) {
104111
guard !OneSignalConfigManager.shouldAwaitAppIdAndLogMissingPrivacyConsent(forMethod: nil) else {
105112
return
106113
}

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSPropertyOperationExecutor.swift

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -188,33 +188,3 @@ class OSPropertyOperationExecutor: OSOperationExecutor {
188188
}
189189
}
190190
}
191-
192-
extension OSPropertyOperationExecutor {
193-
// TODO: We can make this go through the operation repo
194-
func updateProperties(propertiesDeltas: OSPropertiesDeltas, refreshDeviceMetadata: Bool, propertiesModel: OSPropertiesModel, identityModel: OSIdentityModel, sendImmediately: Bool = false, onSuccess: (() -> Void)? = nil, onFailure: (() -> Void)? = nil) {
195-
196-
let request = OSRequestUpdateProperties(
197-
properties: [:],
198-
deltas: propertiesDeltas.jsonRepresentation(),
199-
refreshDeviceMetadata: refreshDeviceMetadata,
200-
identityModel: identityModel)
201-
202-
if sendImmediately {
203-
// Bypass the request queues
204-
OneSignalCoreImpl.sharedClient().execute(request) { _ in
205-
if let onSuccess = onSuccess {
206-
onSuccess()
207-
}
208-
} onFailure: { _ in
209-
if let onFailure = onFailure {
210-
onFailure()
211-
}
212-
}
213-
} else {
214-
self.dispatchQueue.async {
215-
self.updateRequestQueue.append(request)
216-
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_PROPERTIES_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY, withValue: self.updateRequestQueue)
217-
}
218-
}
219-
}
220-
}

iOS_SDK/OneSignalSDK/OneSignalUser/Source/OneSignalUserManagerImpl.swift

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -511,26 +511,7 @@ public class OneSignalUserManagerImpl: NSObject, OneSignalUserManager {
511511
guard !OneSignalConfigManager.shouldAwaitAppIdAndLogMissingPrivacyConsent(forMethod: "sendPurchases") else {
512512
return
513513
}
514-
guard let user = _user else {
515-
OneSignalLog.onesignalLog(ONE_S_LOG_LEVEL.LL_DEBUG, message: "Failed to send purchases because User is nil")
516-
return
517-
}
518-
// Get the identity and properties model of the current user
519-
let identityModel = user.identityModel
520-
let propertiesModel = user.propertiesModel
521-
let propertiesDeltas = OSPropertiesDeltas(sessionTime: nil, sessionCount: nil, amountSpent: nil, purchases: purchases)
522-
523-
// propertyExecutor should exist as this should be called after `start()` has been called
524-
if let propertyExecutor = self.propertyExecutor {
525-
propertyExecutor.updateProperties(
526-
propertiesDeltas: propertiesDeltas,
527-
refreshDeviceMetadata: false,
528-
propertiesModel: propertiesModel,
529-
identityModel: identityModel
530-
)
531-
} else {
532-
OneSignalLog.onesignalLog(.LL_ERROR, message: "OneSignalUserManagerImpl.sendPurchases with purchases: \(purchases) cannot be executed due to missing property executor.")
533-
}
514+
updatePropertiesDeltas(property: "purchases", value: purchases)
534515
}
535516

536517
private func fireJwtExpired() {
@@ -559,7 +540,7 @@ extension OneSignalUserManagerImpl {
559540

560541
OSUserExecutor.executePendingRequests()
561542
OSOperationRepo.sharedInstance.paused = false
562-
updateSession(sessionCount: 1, sessionTime: nil, refreshDeviceMetadata: true)
543+
updatePropertiesDeltas(property: "session_count", value: 1)
563544

564545
// Fetch the user's data if there is a onesignal_id
565546
if let onesignalId = onesignalId {
@@ -571,37 +552,36 @@ extension OneSignalUserManagerImpl {
571552
}
572553
}
573554

574-
@objc
575-
public func updateSession(sessionCount: NSNumber?, sessionTime: NSNumber?, refreshDeviceMetadata: Bool, sendImmediately: Bool = false, onSuccess: (() -> Void)? = nil, onFailure: (() -> Void)? = nil) {
576-
guard !OneSignalConfigManager.shouldAwaitAppIdAndLogMissingPrivacyConsent(forMethod: nil) else {
577-
if let onFailure = onFailure {
578-
onFailure()
579-
}
555+
/// This method accepts properties updates that not driven by model changes.
556+
/// It enqueues an OSDelta to the Operation Repo.
557+
///
558+
/// - Parameter property:Expected inputs are `"session_time"`, `"session_count"`, and `"purchases"`.
559+
func updatePropertiesDeltas(property: String, value: Any) {
560+
guard !OneSignalConfigManager.shouldAwaitAppIdAndLogMissingPrivacyConsent(forMethod: "updatePropertiesDeltas") else {
580561
return
581562
}
582563

583564
// Get the identity and properties model of the current user
584565
let identityModel = user.identityModel
585566
let propertiesModel = user.propertiesModel
586-
let propertiesDeltas = OSPropertiesDeltas(sessionTime: sessionTime, sessionCount: sessionCount, amountSpent: nil, purchases: nil)
587-
588-
// propertyExecutor should exist as this should be called after `start()` has been called
589-
if let propertyExecutor = self.propertyExecutor {
590-
propertyExecutor.updateProperties(
591-
propertiesDeltas: propertiesDeltas,
592-
refreshDeviceMetadata: refreshDeviceMetadata,
593-
propertiesModel: propertiesModel,
594-
identityModel: identityModel,
595-
sendImmediately: sendImmediately,
596-
onSuccess: onSuccess,
597-
onFailure: onFailure
598-
)
599-
} else {
600-
OneSignalLog.onesignalLog(.LL_ERROR, message: "OneSignalUserManagerImpl.updateSession with sessionCount: \(String(describing: sessionCount)) sessionTime: \(String(describing: sessionTime)) cannot be executed due to missing property executor.")
601-
if let onFailure = onFailure {
602-
onFailure()
603-
}
567+
568+
let delta = OSDelta(
569+
name: OS_UPDATE_PROPERTIES_DELTA,
570+
identityModelId: identityModel.modelId,
571+
model: propertiesModel,
572+
property: property,
573+
value: value
574+
)
575+
OSOperationRepo.sharedInstance.enqueueDelta(delta)
576+
}
577+
578+
/// Time processors forward the session time to this method.
579+
@objc
580+
public func sendSessionTime(_ sessionTime: NSNumber) {
581+
guard !OneSignalConfigManager.shouldAwaitAppIdAndLogMissingPrivacyConsent(forMethod: "sendSessionTime") else {
582+
return
604583
}
584+
updatePropertiesDeltas(property: "session_time", value: sessionTime.intValue)
605585
}
606586

607587
/**

0 commit comments

Comments
 (0)