Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MBX-3390 Added filter for innaps by operation #466

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions Mindbox/InAppMessages/InAppConfigurationMapper/InappMapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class InappMapper: InappMapperProtocol {
private let dataFacade: InAppConfigurationDataFacadeProtocol

private var shownInappIDWithHashValue: [String: Int] = [:]
private var abTests: [ABTest]?

init(targetingChecker: InAppTargetingCheckerProtocol,
inappFilterService: InappFilterProtocol,
Expand All @@ -37,7 +38,7 @@ class InappMapper: InappMapperProtocol {
_ response: ConfigResponse,
_ completion: @escaping (InAppFormData?) -> Void) {
setupEnvironment(event: event)

abTests = response.abtests
let filteredInapps = getFilteredInapps(inappsDTO: response.inapps?.elements, abTests: response.abtests)
prepareTargetingChecker(for: filteredInapps)
prepareForRemainingTargeting()
Expand Down Expand Up @@ -70,9 +71,8 @@ class InappMapper: InappMapperProtocol {

private func chooseInappToShow(filteredInapps: [InApp], completion: @escaping (InAppFormData?) -> Void) {
dataFacade.fetchDependencies(model: applicationEvent?.model) {
let inapps = self.applicationEvent == nil ? filteredInapps : self.getOperationInappsByEvent()
let filteredByAlreadyShown = self.inappFilterService.filterInappsByAlreadyShown(inapps)
let suitableInapps = self.filterByInappsEvents(inapps: filteredByAlreadyShown)
let inapps = self.applicationEvent == nil ? filteredInapps : self.getOperationInappsByEventForShow()
let suitableInapps = self.filterByInappsEvents(inapps: inapps)

if suitableInapps.isEmpty {
completion(nil)
Expand All @@ -94,6 +94,13 @@ class InappMapper: InappMapperProtocol {
return []
}

private func getOperationInappsByEventForShow() -> [InApp] {
let inapps = getOperationInappsByEvent()
let filteredByABTest = inappFilterService.filterInappsByABTests(abTests, responseInapps: inapps)
let filteredByAlreadyShown = self.inappFilterService.filterInappsByAlreadyShown(filteredByABTest)
return filteredByAlreadyShown
}

private func filterByInappsEvents(inapps: [InApp]) -> [InAppTransitionData] {
var filteredInAppsByEvent: [InAppTransitionData] = []

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import MindboxLogger

protocol InappFilterProtocol {
func filter(inapps: [InAppDTO]?, abTests: [ABTest]?) -> [InApp]
func filterInappsByABTests(_ abTests: [ABTest]?, responseInapps: [InApp]?) -> [InApp]
func filterInappsByAlreadyShown(_ inapps: [InApp]) -> [InApp]
var validInapps: [InApp] { get }
var shownInAppDictionary: [String: Date] { get }
Expand Down Expand Up @@ -46,56 +47,6 @@ final class InappsFilterService: InappFilterProtocol {
return filteredByAlreadyShown
}

func filterInappsByAlreadyShown(_ inapps: [InApp]) -> [InApp] {
let shownInAppDictionary = persistenceStorage.shownInappsDictionary ?? [:]
Logger.common(message: "Shown in-apps ids: [\(shownInAppDictionary.keys)]", level: .info, category: .inAppMessages)
let filteredInapps = inapps.filter {
Logger.common(message: "[Inapp frequency] Start checking frequency of inapp with id = \($0.id)", level: .debug, category: .inAppMessages)
let frequencyValidator = self.createFrequencyValidator()
let result = frequencyValidator.isValid(item: $0)
Logger.common(message: "[Inapp frequency] Finish checking frequency of inapp with id = \($0.id)", level: .debug, category: .inAppMessages)
return result
}

return filteredInapps
}
}

// MARK: - Private methods
private extension InappsFilterService {
func filterInappsBySDKVersion(_ inapps: [InAppDTO]) -> [InAppDTO] {
let inapps = inapps
let filteredInapps = inapps.filter {
sdkVersionValidator.isValid(item: $0.sdkVersion)
}

return filteredInapps
}

func filterValidInAppMessages(_ inapps: [InAppDTO]) -> [InApp] {
var filteredInapps: [InApp] = []
for inapp in inapps {
do {
let variants = try variantsFilter.filter(inapp.form.variants)
if !variants.isEmpty {
let formModel = InAppForm(variants: variants)
let inappModel = InApp(id: inapp.id,
sdkVersion: inapp.sdkVersion,
targeting: inapp.targeting,
frequency: inapp.frequency,
form: formModel)
filteredInapps.append(inappModel)
}
} catch {
Logger.common(message: "In-app [ID:] \(inapp.id)\n[Error]: \(error)", level: .error, category: .inAppMessages)
}
}

Logger.common(message: "Filtering process completed. \(filteredInapps.count) valid in-app(s) found.", level: .debug, category: .inAppMessages)
validInapps = filteredInapps
return filteredInapps
}

// FIXME: Rewrite this func in the future
// swiftlint:disable:next cyclomatic_complexity
func filterInappsByABTests(_ abTests: [ABTest]?, responseInapps: [InApp]?) -> [InApp] {
Expand Down Expand Up @@ -167,6 +118,56 @@ private extension InappsFilterService {
return result
}

func filterInappsByAlreadyShown(_ inapps: [InApp]) -> [InApp] {
let shownInAppDictionary = persistenceStorage.shownInappsDictionary ?? [:]
Logger.common(message: "Shown in-apps ids: [\(shownInAppDictionary.keys)]", level: .info, category: .inAppMessages)
let filteredInapps = inapps.filter {
Logger.common(message: "[Inapp frequency] Start checking frequency of inapp with id = \($0.id)", level: .debug, category: .inAppMessages)
let frequencyValidator = self.createFrequencyValidator()
let result = frequencyValidator.isValid(item: $0)
Logger.common(message: "[Inapp frequency] Finish checking frequency of inapp with id = \($0.id)", level: .debug, category: .inAppMessages)
return result
}

return filteredInapps
}
}

// MARK: - Private methods
private extension InappsFilterService {
func filterInappsBySDKVersion(_ inapps: [InAppDTO]) -> [InAppDTO] {
let inapps = inapps
let filteredInapps = inapps.filter {
sdkVersionValidator.isValid(item: $0.sdkVersion)
}

return filteredInapps
}

func filterValidInAppMessages(_ inapps: [InAppDTO]) -> [InApp] {
var filteredInapps: [InApp] = []
for inapp in inapps {
do {
let variants = try variantsFilter.filter(inapp.form.variants)
if !variants.isEmpty {
let formModel = InAppForm(variants: variants)
let inappModel = InApp(id: inapp.id,
sdkVersion: inapp.sdkVersion,
targeting: inapp.targeting,
frequency: inapp.frequency,
form: formModel)
filteredInapps.append(inappModel)
}
} catch {
Logger.common(message: "In-app [ID:] \(inapp.id)\n[Error]: \(error)", level: .error, category: .inAppMessages)
}
}

Logger.common(message: "Filtering process completed. \(filteredInapps.count) valid in-app(s) found.", level: .debug, category: .inAppMessages)
validInapps = filteredInapps
return filteredInapps
}

private func createFrequencyValidator() -> InappFrequencyValidator {
InappFrequencyValidator(persistenceStorage: persistenceStorage)
}
Expand Down