diff --git a/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSIdentityOperationExecutor.swift b/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSIdentityOperationExecutor.swift index fd4674e9f..43cbcce88 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSIdentityOperationExecutor.swift +++ b/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSIdentityOperationExecutor.swift @@ -40,8 +40,8 @@ class OSIdentityOperationExecutor: OSOperationExecutor { if var deltaQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_IDENTITY_EXECUTOR_DELTA_QUEUE_KEY, defaultValue: []) as? [OSDelta] { // Hook each uncached Delta to the model in the store for (index, delta) in deltaQueue.enumerated().reversed() { - if let modelInStore = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: delta.model.modelId) { - // The model exists in the store, set it to be the Delta's model + if let modelInStore = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(delta.model.modelId) { + // The model exists in the repo, set it to be the Delta's model delta.model = modelInStore } else { // The model does not exist, drop this Delta @@ -59,14 +59,14 @@ class OSIdentityOperationExecutor: OSOperationExecutor { if var addRequestQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_IDENTITY_EXECUTOR_ADD_REQUEST_QUEUE_KEY, defaultValue: []) as? [OSRequestAddAliases] { // Hook each uncached Request to the model in the store for (index, request) in addRequestQueue.enumerated().reversed() { - if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: request.identityModel.modelId) { - // 1. The model exists in the store, so set it to be the Request's models + if let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(request.identityModel.modelId) { + // 1. The model exists in the repo, so set it to be the Request's models request.identityModel = identityModel - } else if let identityModel = OSUserExecutor.identityModels[request.identityModel.modelId] { - // 2. The model exists in the user executor - request.identityModel = identityModel - } else if !request.prepareForExecution() { - // 3. The models do not exist AND this request cannot be sent, drop this Request + } else if request.prepareForExecution() { + // 2. The request can be sent, add the model to the repo + OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(request.identityModel) + } else { + // 3. The model do not exist AND this request cannot be sent, drop this Request addRequestQueue.remove(at: index) } } @@ -79,13 +79,13 @@ class OSIdentityOperationExecutor: OSOperationExecutor { if var removeRequestQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_IDENTITY_EXECUTOR_REMOVE_REQUEST_QUEUE_KEY, defaultValue: []) as? [OSRequestRemoveAlias] { // Hook each uncached Request to the model in the store for (index, request) in removeRequestQueue.enumerated().reversed() { - if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: request.identityModel.modelId) { - // 1. The model exists in the store, so set it to be the Request's model + if let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(request.identityModel.modelId) { + // 1. The model exists in the repo, so set it to be the Request's model request.identityModel = identityModel - } else if let identityModel = OSUserExecutor.identityModels[request.identityModel.modelId] { - // 2. The model exists in the user executor - request.identityModel = identityModel - } else if !request.prepareForExecution() { + } else if request.prepareForExecution() { + // 2. The request can be sent, add the model to the repo + OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(request.identityModel) + } else { // 3. The model does not exist AND this request cannot be sent, drop this Request removeRequestQueue.remove(at: index) } diff --git a/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSPropertyOperationExecutor.swift b/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSPropertyOperationExecutor.swift index b464ce8fd..9febb8a69 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSPropertyOperationExecutor.swift +++ b/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSPropertyOperationExecutor.swift @@ -40,13 +40,9 @@ class OSPropertyOperationExecutor: OSOperationExecutor { // Read unfinished deltas from cache, if any... // Note that we should only have deltas for the current user as old ones are flushed.. if var deltaQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_PROPERTIES_EXECUTOR_DELTA_QUEUE_KEY, defaultValue: []) as? [OSDelta] { - // Hook each uncached Delta to the model in the store for (index, delta) in deltaQueue.enumerated().reversed() { - if let modelInStore = OneSignalUserManagerImpl.sharedInstance.propertiesModelStore.getModel(modelId: delta.model.modelId) { - // 1. The model exists in the properties model store, set it to be the Delta's model - delta.model = modelInStore - } else { - // 2. The model does not exist, drop this Delta + if (OneSignalUserManagerImpl.sharedInstance.getIdentityModel(delta.identityModelId) == nil) { + // The identity model does not exist, drop this Delta OneSignalLog.onesignalLog(.LL_WARN, message: "OSPropertyOperationExecutor.init dropped: \(delta)") deltaQueue.remove(at: index) } @@ -61,13 +57,13 @@ class OSPropertyOperationExecutor: OSOperationExecutor { if var updateRequestQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_PROPERTIES_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY, defaultValue: []) as? [OSRequestUpdateProperties] { // Hook each uncached Request to the model in the store for (index, request) in updateRequestQueue.enumerated().reversed() { - if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: request.identityModel.modelId) { - // 1. The identity model exist in the store, set it to be the Request's models - request.identityModel = identityModel - } else if let identityModel = OSUserExecutor.identityModels[request.identityModel.modelId] { - // 2. The model exists in the user executor + if let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(request.identityModel.modelId) { + // 1. The identity model exist in the repo, set it to be the Request's model request.identityModel = identityModel - } else if !request.prepareForExecution() { + } else if request.prepareForExecution() { + // 2. The request can be sent, add the model to the repo + OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(request.identityModel) + } else { // 3. The identitymodel do not exist AND this request cannot be sent, drop this Request OneSignalLog.onesignalLog(.LL_WARN, message: "OSPropertyOperationExecutor.init dropped: \(request)") updateRequestQueue.remove(at: index) @@ -99,11 +95,17 @@ class OSPropertyOperationExecutor: OSOperationExecutor { OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSPropertyOperationExecutor processDeltaQueue with queue: \(self.deltaQueue)") } for delta in self.deltaQueue { + guard let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(delta.identityModelId) + else { + // drop this delta + continue + } + let request = OSRequestUpdateProperties( properties: [delta.property: delta.value], deltas: nil, refreshDeviceMetadata: false, // Sort this out. - identityModel: OneSignalUserManagerImpl.sharedInstance.user.identityModel // TODO: Make sure this is ok + identityModel: identityModel ) self.updateRequestQueue.append(request) } diff --git a/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSSubscriptionOperationExecutor.swift b/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSSubscriptionOperationExecutor.swift index 499705bad..37760a48d 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSSubscriptionOperationExecutor.swift +++ b/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSSubscriptionOperationExecutor.swift @@ -75,14 +75,15 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor { subscriptionModels[request.subscriptionModel.modelId] = request.subscriptionModel } // 2. Hook up the identity model - if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: request.identityModel.modelId) { - // a. The model exist in the store + if let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(request.identityModel.modelId) { + // a. The model exist in the repo request.identityModel = identityModel - } else if let identityModel = OSUserExecutor.identityModels[request.identityModel.modelId] { - // b. The model exist in the user executor - request.identityModel = identityModel - } else if !request.prepareForExecution() { - // The model do not exist AND this request cannot be sent, drop this Request + } else if request.prepareForExecution() { + // b. The request can be sent, add the model to the repo + OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(request.identityModel) + } else { + // c. The model do not exist AND this request cannot be sent, drop this Request + OneSignalLog.onesignalLog(.LL_WARN, message: "OSSubscriptionOperationExecutor.init dropped: \(request)") continue } requestQueue.append(request) @@ -161,29 +162,31 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor { OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSSubscriptionOperationExecutor processDeltaQueue with queue: \(deltaQueue)") } for delta in deltaQueue { - guard let model = delta.model as? OSSubscriptionModel else { - // Log error + guard let subModel = delta.model as? OSSubscriptionModel, + let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(delta.identityModelId) + else { + OneSignalLog.onesignalLog(.LL_ERROR, message: "OSSubscriptionOperationExecutor processDeltaQueue dropping OSDelta: \(delta)") continue } switch delta.name { case OS_ADD_SUBSCRIPTION_DELTA: let request = OSRequestCreateSubscription( - subscriptionModel: model, - identityModel: OneSignalUserManagerImpl.sharedInstance.user.identityModel // TODO: Make sure this is ok + subscriptionModel: subModel, + identityModel: identityModel ) addRequestQueue.append(request) case OS_REMOVE_SUBSCRIPTION_DELTA: let request = OSRequestDeleteSubscription( - subscriptionModel: model + subscriptionModel: subModel ) removeRequestQueue.append(request) case OS_UPDATE_SUBSCRIPTION_DELTA: let request = OSRequestUpdateSubscription( subscriptionObject: [delta.property: delta.value], - subscriptionModel: model + subscriptionModel: subModel ) updateRequestQueue.append(request) diff --git a/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSUserExecutor.swift b/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSUserExecutor.swift index 0bb0ee47f..31282bca2 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSUserExecutor.swift +++ b/iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSUserExecutor.swift @@ -36,7 +36,6 @@ import OneSignalOSCore class OSUserExecutor { static var userRequestQueue: [OSUserRequest] = [] static var transferSubscriptionRequestQueue: [OSRequestTransferSubscription] = [] - static var identityModels: [String: OSIdentityModel] = [:] // Read in requests from the cache, do not read in FetchUser requests as this is not needed. static func start() { @@ -47,58 +46,48 @@ class OSUserExecutor { // Hook each uncached Request to the right model reference for request in cachedRequestQueue { if request.isKind(of: OSRequestFetchIdentityBySubscription.self), let req = request as? OSRequestFetchIdentityBySubscription { - if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: req.identityModel.modelId) { - // 1. The model exist in the store, set it to be the Request's model - req.identityModel = identityModel - } else if let identityModel = identityModels[req.identityModel.modelId] { - // 2. The model exists in the dict of identityModels already processed to use + if let identityModel = getIdentityModel(req.identityModel.modelId) { + // 1. The model exist in the repo, set it to be the Request's model + // It is the current user or the model has already been processed req.identityModel = identityModel } else { - // 3. The models do not exist, use the model on the request, and add to dict. - identityModels[req.identityModel.modelId] = req.identityModel + // 2. The model do not exist, use the model on the request, and add to repo. + addIdentityModel(req.identityModel) } userRequestQueue.append(req) } else if request.isKind(of: OSRequestCreateUser.self), let req = request as? OSRequestCreateUser { - if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: req.identityModel.modelId) { - // 1. The model exist in the store, set it to be the Request's model - req.identityModel = identityModel - } else if let identityModel = identityModels[req.identityModel.modelId] { - // 2. The model exists in the dict of identityModels already processed to use + if let identityModel = getIdentityModel(req.identityModel.modelId) { + // 1. The model exist in the repo, set it to be the Request's model req.identityModel = identityModel } else { - // 3. The models do not exist, use the model on the request, and add to dict. - identityModels[req.identityModel.modelId] = req.identityModel + // 2. The models do not exist, use the model on the request, and add to repo. + addIdentityModel(req.identityModel) } userRequestQueue.append(req) } else if request.isKind(of: OSRequestIdentifyUser.self), let req = request as? OSRequestIdentifyUser { - if let identityModelToIdentify = identityModels[req.identityModelToIdentify.modelId], - let identityModelToUpdate = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: req.identityModelToUpdate.modelId) { - // 1. A model exist in the dict and a model exist in the store, set it to be the Request's models - req.identityModelToIdentify = identityModelToIdentify - req.identityModelToUpdate = identityModelToUpdate - } else if let identityModelToIdentify = identityModels[req.identityModelToIdentify.modelId], - let identityModelToUpdate = identityModels[req.identityModelToUpdate.modelId] { - // 2. The two models exist in the dict, set it to be the Request's models + if let identityModelToIdentify = getIdentityModel(req.identityModelToIdentify.modelId), + let identityModelToUpdate = getIdentityModel(req.identityModelToUpdate.modelId) { + // 1. Both models exist in the repo, set it to be the Request's models req.identityModelToIdentify = identityModelToIdentify req.identityModelToUpdate = identityModelToUpdate - } else if let identityModelToIdentify = identityModels[req.identityModelToIdentify.modelId], - identityModels[req.identityModelToUpdate.modelId] == nil { - // 3. A model is in the dict, the other model does not exist + } else if let identityModelToIdentify = getIdentityModel(req.identityModelToIdentify.modelId), + getIdentityModel(req.identityModelToUpdate.modelId) == nil { + // 2. A model is in the repo, the other model does not exist req.identityModelToIdentify = identityModelToIdentify - identityModels[req.identityModelToUpdate.modelId] = req.identityModelToUpdate + addIdentityModel(req.identityModelToUpdate) } else { - // 4. Both models don't exist yet + // 3. Both models don't exist yet // Drop the request if the identityModelToIdentify does not already exist AND the request is missing OSID // Otherwise, this request will forever fail `prepareForExecution` and block pending requests such as recovery calls to `logout` or `login` guard request.prepareForExecution() else { OneSignalLog.onesignalLog(.LL_ERROR, message: "OSUserExecutor.start() dropped: \(request)") continue } - identityModels[req.identityModelToIdentify.modelId] = req.identityModelToIdentify - identityModels[req.identityModelToUpdate.modelId] = req.identityModelToUpdate + addIdentityModel(req.identityModelToIdentify) + addIdentityModel(req.identityModelToUpdate) } userRequestQueue.append(req) } @@ -128,6 +117,14 @@ class OSUserExecutor { executePendingRequests() } + static private func getIdentityModel(_ modelId: String) -> OSIdentityModel? { + return OneSignalUserManagerImpl.sharedInstance.getIdentityModel(modelId) + } + + static private func addIdentityModel(_ model: OSIdentityModel) { + OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(model) + } + static func appendToQueue(_ request: OSUserRequest) { if request.isKind(of: OSRequestTransferSubscription.self), let req = request as? OSRequestTransferSubscription { self.transferSubscriptionRequestQueue.append(req)