Skip to content

Commit 96abd8b

Browse files
committed
Make more no-ops if there is no user instance
*Calling the `user` property of the `OneSignalUserManagerImpl` will return a mock user, the user instance, or call start(). * In some methods, if there is no user instance, don't trigger a start() call, to prevent deadlocks if these methods are called by start() itself. * Currently, only the properties model and subscription model may have update enqueued at the end of the start() method to enqueue any changes such as timezone and app version for the user instance, which exists by this point. * The other refactors are for safety.
1 parent d32483d commit 96abd8b

File tree

4 files changed

+30
-15
lines changed

4 files changed

+30
-15
lines changed

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,9 @@ class OSUserExecutor {
119119

120120
// Translate the last request into a Create User request, if the current user is the same
121121
if let request = transferSubscriptionRequestQueue.last,
122+
let userInstance = OneSignalUserManagerImpl.sharedInstance._user,
122123
OneSignalUserManagerImpl.sharedInstance.isCurrentUser(request.aliasId) {
123-
createUser(OneSignalUserManagerImpl.sharedInstance.user)
124+
createUser(userInstance)
124125
}
125126
}
126127
}
@@ -396,9 +397,10 @@ extension OSUserExecutor {
396397

397398
self.removeFromQueue(request)
398399

399-
if OneSignalUserManagerImpl.sharedInstance.isCurrentUser(request.identityModelToUpdate) {
400+
if let userInstance = OneSignalUserManagerImpl.sharedInstance._user,
401+
OneSignalUserManagerImpl.sharedInstance.isCurrentUser(request.identityModelToUpdate) {
400402
// Generate a Create User request, if it's still the current user
401-
self.createUser(OneSignalUserManagerImpl.sharedInstance.user)
403+
self.createUser(userInstance)
402404
} else {
403405
// This will hydrate the OneSignal ID for any pending requests
404406
self.createUser(aliasLabel: request.aliasLabel, aliasId: request.aliasId, identityModel: request.identityModelToUpdate)
@@ -544,7 +546,7 @@ extension OSUserExecutor {
544546
}
545547

546548
if let propertiesObject = parsePropertiesObjectResponse(response) {
547-
OneSignalUserManagerImpl.sharedInstance.user.propertiesModel.hydrate(propertiesObject)
549+
OneSignalUserManagerImpl.sharedInstance._user?.propertiesModel.hydrate(propertiesObject)
548550
}
549551

550552
// Now parse email and sms subscriptions

iOS_SDK/OneSignalSDK/OneSignalUser/Source/OSPropertiesModelStoreListener.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,15 @@ class OSPropertiesModelStoreListener: OSModelStoreListener {
4545
}
4646

4747
func getUpdateModelDelta(_ args: OSModelChangedArgs) -> OSDelta? {
48-
guard let _ = OSPropertiesSupportedProperty(rawValue: args.property) else {
49-
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSPropertiesModelStoreListener.getUpdateModelDelta encountered unsupported property: \(args.property)")
48+
guard let _ = OSPropertiesSupportedProperty(rawValue: args.property),
49+
let userInstance = OneSignalUserManagerImpl.sharedInstance._user
50+
else {
51+
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSPropertiesModelStoreListener.getUpdateModelDelta encountered unsupported property: \(args.property) or no user instance")
5052
return nil
5153
}
52-
5354
return OSDelta(
5455
name: OS_UPDATE_PROPERTIES_DELTA,
55-
identityModelId: OneSignalUserManagerImpl.sharedInstance.user.identityModel.modelId,
56+
identityModelId: userInstance.identityModel.modelId,
5657
model: args.model,
5758
property: args.property,
5859
value: args.newValue

iOS_SDK/OneSignalSDK/OneSignalUser/Source/OSSubscriptionModelStoreListener.swift

+16-4
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ class OSSubscriptionModelStoreListener: OSModelStoreListener {
3737
}
3838

3939
func getAddModelDelta(_ model: OSSubscriptionModel) -> OSDelta? {
40+
guard let userInstance = OneSignalUserManagerImpl.sharedInstance._user else {
41+
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSSubscriptionModelStoreListener.getAddModelDelta has no user instance")
42+
return nil
43+
}
4044
return OSDelta(
4145
name: OS_ADD_SUBSCRIPTION_DELTA,
42-
identityModelId: OneSignalUserManagerImpl.sharedInstance.user.identityModel.modelId,
46+
identityModelId: userInstance.identityModel.modelId,
4347
model: model,
4448
property: model.type.rawValue, // push, email, sms
4549
value: model.address ?? ""
@@ -50,9 +54,13 @@ class OSSubscriptionModelStoreListener: OSModelStoreListener {
5054
The `property` and `value` is not needed for a remove operation, so just pass in some model data as placeholders.
5155
*/
5256
func getRemoveModelDelta(_ model: OSSubscriptionModel) -> OSDelta? {
57+
guard let userInstance = OneSignalUserManagerImpl.sharedInstance._user else {
58+
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSSubscriptionModelStoreListener.getRemoveModelDelta has no user instance")
59+
return nil
60+
}
5361
return OSDelta(
5462
name: OS_REMOVE_SUBSCRIPTION_DELTA,
55-
identityModelId: OneSignalUserManagerImpl.sharedInstance.user.identityModel.modelId,
63+
identityModelId: userInstance.identityModel.modelId,
5664
model: model,
5765
property: model.type.rawValue, // push, email, sms
5866
value: model.address ?? ""
@@ -66,14 +74,18 @@ class OSSubscriptionModelStoreListener: OSModelStoreListener {
6674
// The user update call increases the session_count while the subscription update would update
6775
// something like the app_version. If the app_version hasn't changed since the last session, there
6876
// wouldn't be an update needed (among other system-level properties).
69-
if let onesignalId = OneSignalUserManagerImpl.sharedInstance.user.identityModel.onesignalId {
77+
guard let userInstance = OneSignalUserManagerImpl.sharedInstance._user else {
78+
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSSubscriptionModelStoreListener.getUpdateModelDelta has no user instance")
79+
return nil
80+
}
81+
if let onesignalId = userInstance.identityModel.onesignalId {
7082
let condition = OSIamFetchReadyCondition.sharedInstance(withId: onesignalId)
7183
condition.setSubscriptionUpdatePending(value: true)
7284
}
7385

7486
return OSDelta(
7587
name: OS_UPDATE_SUBSCRIPTION_DELTA,
76-
identityModelId: OneSignalUserManagerImpl.sharedInstance.user.identityModel.modelId,
88+
identityModelId: userInstance.identityModel.modelId,
7789
model: args.model,
7890
property: args.property,
7991
value: args.newValue

iOS_SDK/OneSignalSDK/OneSignalUser/Source/OneSignalUserManagerImpl.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -384,12 +384,12 @@ public class OneSignalUserManagerImpl: NSObject, OneSignalUserManager {
384384
}
385385

386386
func isCurrentUser(_ externalId: String) -> Bool {
387-
guard !externalId.isEmpty else {
388-
OneSignalLog.onesignalLog(.LL_ERROR, message: "isCurrentUser called with empty externalId")
387+
guard let userInstance = _user, !externalId.isEmpty else {
388+
OneSignalLog.onesignalLog(.LL_ERROR, message: "isCurrentUser called with empty externalId or no user instance")
389389
return false
390390
}
391391

392-
return user.identityModel.externalId == externalId
392+
return userInstance.identityModel.externalId == externalId
393393
}
394394
/**
395395
Clears the existing user's data in preparation for hydration via a fetch user call.

0 commit comments

Comments
 (0)