Skip to content

Commit f873de2

Browse files
committed
make fixes to the push subscription model
* Push observer will receive the push subscription object, so it has `optedIn`, not `enabled`. * Update the logic in firePushSubscriptionChanged as a result of the above. * Keep the `enabled` property for internal use to send to the server * Cache the notificationTypes property * Fix a bug in hydrating `enabled`. Add TODO for how to hydrate `enabled`, since it's not clear. * For now, don't hydrate token, because it can lead to wonky states where it can overwrite the updated correct token and fire the push observer. Tokens should not be changed from the server anyway.
1 parent 94e1844 commit f873de2

File tree

2 files changed

+41
-31
lines changed

2 files changed

+41
-31
lines changed

iOS_SDK/OneSignalSDK/OneSignalUser/Source/OSSubscriptionModel.swift

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,14 @@ import OneSignalNotifications
3838

3939
@objc
4040
public class OSPushSubscriptionState: NSObject {
41-
// TODO: Decide if optedIn will be observed
4241
@objc public let id: String?
4342
@objc public let token: String?
44-
@objc public let enabled: Bool
43+
@objc public let optedIn: Bool
4544

46-
init(id: String?, token: String?, enabled: Bool) {
45+
init(id: String?, token: String?, optedIn: Bool) {
4746
self.id = id
4847
self.token = token
49-
self.enabled = enabled
48+
self.optedIn = optedIn
5049
}
5150

5251
func toDictionary() -> NSDictionary {
@@ -55,7 +54,7 @@ public class OSPushSubscriptionState: NSObject {
5554
return [
5655
"id": id,
5756
"token": token,
58-
"enabled": enabled
57+
"optedIn": optedIn
5958
]
6059
}
6160
}
@@ -125,21 +124,22 @@ class OSSubscriptionModel: OSModel {
125124
}
126125
}
127126

128-
var enabled: Bool { // Note: This behaves like the current `isSubscribed`
127+
// Internal property to send to server, not meant for outside access
128+
var enabled: Bool { // Does not consider subscription_id in the calculation
129129
get {
130-
return calculateIsSubscribed(subscriptionId: subscriptionId, address: address, accepted: _accepted, isDisabled: _isDisabled)
130+
return calculateIsEnabled(address: address, accepted: _accepted, isDisabled: _isDisabled)
131131
}
132132
}
133133

134134
var optedIn: Bool {
135135
// optedIn = permission + userPreference
136136
get {
137-
return _accepted && !_isDisabled
137+
return calculateIsOptedIn(accepted: _accepted, isDisabled: _isDisabled)
138138
}
139139
}
140140

141141
// Push Subscription Only
142-
// Initialize to be -1, so not to deal with unwrapping every time
142+
// Initialize to be -1, so not to deal with unwrapping every time, and simplifies caching
143143
var notificationTypes = -1 {
144144
didSet {
145145
guard self.type == .push && notificationTypes != oldValue else {
@@ -200,6 +200,7 @@ class OSSubscriptionModel: OSModel {
200200
coder.encode(subscriptionId, forKey: "subscriptionId")
201201
coder.encode(_accepted, forKey: "_accepted")
202202
coder.encode(_isDisabled, forKey: "_isDisabled")
203+
coder.encode(notificationTypes, forKey: "notificationTypes")
203204
}
204205

205206
required init?(coder: NSCoder) {
@@ -215,6 +216,7 @@ class OSSubscriptionModel: OSModel {
215216
self.subscriptionId = coder.decodeObject(forKey: "subscriptionId") as? String
216217
self._accepted = coder.decodeBool(forKey: "_accepted")
217218
self._isDisabled = coder.decodeBool(forKey: "_isDisabled")
219+
self.notificationTypes = coder.decodeInteger(forKey: "notificationTypes")
218220
super.init(coder: coder)
219221
}
220222

@@ -228,12 +230,13 @@ class OSSubscriptionModel: OSModel {
228230
if let type = OSSubscriptionType(rawValue: property.value as? String ?? "") {
229231
self.type = type
230232
}
231-
case "token":
232-
self.address = property.value as? String
233+
// case "token":
234+
// TODO: For now, don't hydrate token
235+
// self.address = property.value as? String
233236
case "enabled":
234237
if let enabled = property.value as? Bool {
235-
if self.enabled != enabled {
236-
_isDisabled = enabled
238+
if self.enabled != enabled { // TODO: Is this right?
239+
_isDisabled = !enabled
237240
}
238241
}
239242
case "notification_types":
@@ -253,13 +256,14 @@ extension OSSubscriptionModel {
253256
var currentPushSubscriptionState: OSPushSubscriptionState {
254257
return OSPushSubscriptionState(id: self.subscriptionId,
255258
token: self.address,
256-
enabled: self.enabled
259+
optedIn: self.optedIn
257260
)
258261
}
259-
260-
// Calculates if the device is currently able to receive a push notification.
261-
func calculateIsSubscribed(subscriptionId: String?, address: String?, accepted: Bool, isDisabled: Bool) -> Bool {
262-
return (self.subscriptionId != nil) && (self.address != nil) && _accepted && !_isDisabled
262+
263+
// Calculates if the device is opted in to push notification.
264+
// Must have permission and not be opted out.
265+
func calculateIsOptedIn(accepted: Bool, isDisabled: Bool) -> Bool {
266+
return _accepted && !_isDisabled
263267
}
264268

265269
// Calculates if push notifications are enabled on the device.
@@ -280,46 +284,47 @@ extension OSSubscriptionModel {
280284
}
281285

282286
func firePushSubscriptionChanged(_ changedProperty: OSPushPropertyChanged) {
283-
var prevIsSubscribed = true
287+
var prevIsOptedIn = true
284288
var prevIsEnabled = true
285-
var prevSubscriptionState = OSPushSubscriptionState(id: "", token: "", enabled: true)
289+
var prevSubscriptionState = OSPushSubscriptionState(id: "", token: "", optedIn: true)
286290

287291
switch changedProperty {
288292
case .subscriptionId(let oldValue):
289293
prevIsEnabled = calculateIsEnabled(address: address, accepted: _accepted, isDisabled: _isDisabled)
290-
prevIsSubscribed = calculateIsSubscribed(subscriptionId: oldValue, address: address, accepted: _accepted, isDisabled: _isDisabled)
291-
prevSubscriptionState = OSPushSubscriptionState(id: oldValue, token: address, enabled: prevIsSubscribed)
294+
prevIsOptedIn = calculateIsOptedIn(accepted: _accepted, isDisabled: _isDisabled)
295+
prevSubscriptionState = OSPushSubscriptionState(id: oldValue, token: address, optedIn: prevIsOptedIn)
292296

293297
case .accepted(let oldValue):
294298
prevIsEnabled = calculateIsEnabled(address: address, accepted: oldValue, isDisabled: _isDisabled)
295-
prevIsSubscribed = calculateIsSubscribed(subscriptionId: subscriptionId, address: address, accepted: oldValue, isDisabled: _isDisabled)
296-
prevSubscriptionState = OSPushSubscriptionState(id: subscriptionId, token: address, enabled: prevIsSubscribed)
299+
prevIsOptedIn = calculateIsOptedIn(accepted: oldValue, isDisabled: _isDisabled)
300+
prevSubscriptionState = OSPushSubscriptionState(id: subscriptionId, token: address, optedIn: prevIsOptedIn)
297301

298302
case .isDisabled(let oldValue):
299303
prevIsEnabled = calculateIsEnabled(address: address, accepted: _accepted, isDisabled: oldValue)
300-
prevIsSubscribed = calculateIsSubscribed(subscriptionId: subscriptionId, address: address, accepted: _accepted, isDisabled: oldValue)
301-
prevSubscriptionState = OSPushSubscriptionState(id: subscriptionId, token: address, enabled: prevIsSubscribed)
304+
prevIsOptedIn = calculateIsOptedIn(accepted: _accepted, isDisabled: oldValue)
305+
prevSubscriptionState = OSPushSubscriptionState(id: subscriptionId, token: address, optedIn: prevIsOptedIn)
302306

303307
case .address(let oldValue):
304308
prevIsEnabled = calculateIsEnabled(address: oldValue, accepted: _accepted, isDisabled: _isDisabled)
305-
prevIsSubscribed = calculateIsSubscribed(subscriptionId: subscriptionId, address: oldValue, accepted: _accepted, isDisabled: _isDisabled)
306-
prevSubscriptionState = OSPushSubscriptionState(id: subscriptionId, token: oldValue, enabled: prevIsSubscribed)
309+
prevIsOptedIn = calculateIsOptedIn(accepted: _accepted, isDisabled: _isDisabled)
310+
prevSubscriptionState = OSPushSubscriptionState(id: subscriptionId, token: oldValue, optedIn: prevIsOptedIn)
307311
}
308312

309-
let newIsSubscribed = calculateIsSubscribed(subscriptionId: subscriptionId, address: address, accepted: _accepted, isDisabled: _isDisabled)
313+
let newIsOptedIn = calculateIsOptedIn(accepted: _accepted, isDisabled: _isDisabled)
310314

311315
let newIsEnabled = calculateIsEnabled(address: address, accepted: _accepted, isDisabled: _isDisabled)
312316

313317
if prevIsEnabled != newIsEnabled {
314318
self.set(property: "enabled", newValue: newIsEnabled)
315319
}
316320

317-
let newSubscriptionState = OSPushSubscriptionState(id: subscriptionId, token: address, enabled: newIsSubscribed)
321+
let newSubscriptionState = OSPushSubscriptionState(id: subscriptionId, token: address, optedIn: newIsOptedIn)
318322

319323
let stateChanges = OSPushSubscriptionStateChanges(to: newSubscriptionState, from: prevSubscriptionState)
320324

321325
// TODO: Don't fire observer until server is udated
322-
print("🔥 firePushSubscriptionChanged from \(prevSubscriptionState) to \(newSubscriptionState)")
326+
print("🔥 firePushSubscriptionChanged from \(prevSubscriptionState.toDictionary()) to \(newSubscriptionState.toDictionary())")
327+
323328
OneSignalUserManagerImpl.sharedInstance.pushSubscriptionStateChangesObserver.notifyChange(stateChanges)
324329
}
325330
}

iOS_SDK/OneSignalSDK/OneSignalUser/Source/OSUserRequests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,7 @@ class OSRequestUpdateSubscription: OneSignalRequest, OSUserRequest {
854854
}
855855

856856
// TODO: just need the sub model and send it
857+
// But the model may be outdated or not sync with the subscriptionObject
857858
init(subscriptionObject: [String: Any], subscriptionModel: OSSubscriptionModel) {
858859
self.subscriptionModel = subscriptionModel
859860
self.stringDescription = "OSRequestUpdateSubscription with subscriptionObject: \(subscriptionObject)"
@@ -866,6 +867,10 @@ class OSRequestUpdateSubscription: OneSignalRequest, OSUserRequest {
866867
subscriptionParams["token"] = subscriptionModel.address ?? ""
867868
subscriptionParams["notification_types"] = subscriptionModel.notificationTypes
868869
subscriptionParams["enabled"] = subscriptionModel.enabled
870+
// TODO: The above is not quite right. If we hydrate, we will over-write any pending updates
871+
// subscriptionParams["token"] = subscriptionObject["address"]
872+
// subscriptionParams["notification_types"] = subscriptionObject["notificationTypes"]
873+
// subscriptionParams["enabled"] = subscriptionObject["enabled"]
869874
self.parameters = ["subscription": subscriptionParams]
870875
self.method = PATCH
871876
_ = prepareForExecution() // sets the path property

0 commit comments

Comments
 (0)