Skip to content

Commit

Permalink
Notifies SegmentationCallbacks with only new and all new data
Browse files Browse the repository at this point in the history
  • Loading branch information
adam1929 authored Oct 11, 2024
1 parent 3b57650 commit 1107787
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 69 deletions.
30 changes: 30 additions & 0 deletions ExponeaSDK/Example/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ class AppDelegate: ExponeaAppDelegate {
static let memoryLogger = MemoryLogger()
var window: UIWindow?
var alertWindow: UIWindow?
let discoverySegmentsCallback = SegmentCallbackData(
category: .discovery(),
isIncludeFirstLoad: false
) { newSegments in
notifyNewSegments(categoryName: "discovery", segments: newSegments)
}
let contentSegmentsCallback = SegmentCallbackData(
category: .content(),
isIncludeFirstLoad: false
) { newSegments in
notifyNewSegments(categoryName: "content", segments: newSegments)
}
let merchandisingSegmentsCallback = SegmentCallbackData(
category: .merchandising(),
isIncludeFirstLoad: false
) { newSegments in
notifyNewSegments(categoryName: "merchandising", segments: newSegments)
}

override func application(
_ application: UIApplication,
Expand All @@ -29,6 +47,9 @@ class AppDelegate: ExponeaAppDelegate {
super.application(application, didFinishLaunchingWithOptions: launchOptions)
Exponea.logger = AppDelegate.memoryLogger
Exponea.logger.logLevel = .verbose
SegmentationManager.shared.addCallback(callbackData: discoverySegmentsCallback)
SegmentationManager.shared.addCallback(callbackData: contentSegmentsCallback)
SegmentationManager.shared.addCallback(callbackData: merchandisingSegmentsCallback)

UITabBar.appearance().tintColor = UIColor(red: 28/255, green: 23/255, blue: 50/255, alpha: 1.0)
UINavigationBar.appearance().backgroundColor = UIColor(red: 249/255, green: 249/255, blue: 249/255, alpha: 0.94)
Expand Down Expand Up @@ -86,6 +107,15 @@ class AppDelegate: ExponeaAppDelegate {
}
return false
}

private static func notifyNewSegments(categoryName: String, segments: [SegmentDTO]) {
Exponea.logger.log(
.verbose,
message: "Segments: New for category \(categoryName) with IDs: [" + segments.map {
return "{ segmentation_id=\($0.segmentationId), id=\($0.id) }"
}.joined() + "]"
)
}
}

extension AppDelegate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class FetchViewController: UIViewController {
typealias MyRecommendationResponse = RecommendationResponse<MyRecommendation>

@IBAction func segment(_ sender: Any) {
Exponea.shared.getSegments(force: true, category: .discovery()) { data in
Exponea.shared.getSegments(force: true, category: .content()) { data in
DispatchQueue.main.async {
let alertController = UIAlertController(title: "Segment", message: data.map { segment in
"id: \(segment.id), segmentationId: \(segment.segmentationId)\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ public protocol SegmentationManagerType {
func getNewbies() -> [SegmentCallbackData]
func getCallbacks() -> [SegmentCallbackData]
func processTriggeredBy(type: SegmentTriggerType)
func unionSegments(first: [SegmentCategory], second: [SegmentCategory]) -> [SegmentCategory]
func unionSegments(
fetchedCategories: [SegmentCategory],
cachedCategories: [SegmentCategory],
newbies: [SegmentCallbackData]
) -> [SegmentCategory]
func anonymize()
func removeAll()
func addCallback(callbackData: SegmentCallbackData)
Expand Down Expand Up @@ -150,29 +154,19 @@ extension SegmentationManager {
}
}

public func unionSegments(first: [SegmentCategory], second: [SegmentCategory]) -> [SegmentCategory] {
let source = first + second
public func unionSegments(
fetchedCategories: [SegmentCategory],
cachedCategories: [SegmentCategory],
newbies: [SegmentCallbackData]
) -> [SegmentCategory] {
let unionCategoryNames = Set(
fetchedCategories.map { $0.name } + cachedCategories.map { $0.name } + newbies.map { $0.category.name }
)
var toReturn: [SegmentCategory] = []
for s in source {
if !toReturn.contains(where: { $0.id == s.id }) {
toReturn.append(s)
} else if let found = toReturn.first(where: { $0.id == s.id }) {
switch s {
case let .content(data):
if case let .content(storeData) = found, let index = toReturn.firstIndex(where: { $0.id == s.id }) {
toReturn[index] = .content(data: Array(Set(data + storeData)))
}
case let .discovery(data):
if case let .discovery(storeData) = found, let index = toReturn.firstIndex(where: { $0.id == s.id }) {
toReturn[index] = .discovery(data: Array(Set(data + storeData)))
}
case let .merchandising(data):
if case let .merchandising(storeData) = found, let index = toReturn.firstIndex(where: { $0.id == s.id }) {
toReturn[index] = .merchandising(data: Array(Set(data + storeData)))
}
case .other: continue
}
}
for categoryName in unionCategoryNames {
toReturn.append(
fetchedCategories.first { $0.name == categoryName } ?? SegmentCategory.init(type: categoryName, data: [])
)
}
return toReturn
}
Expand All @@ -192,7 +186,7 @@ extension SegmentationManager {
}
let storeSegments = self.storedSegmentations?.segmentData.categories ?? []
let syncStatus = synchronizeSegments(customerIds: customerIds, input: result)
let union = unionSegments(first: result.categories, second: storeSegments)
let union = unionSegments(fetchedCategories: result.categories, cachedCategories: storeSegments, newbies: newbies)
guard !union.isEmpty else {
Exponea.logger.log(.verbose, message: "Segments: Empty data from server and store.")
self.newbieCallbacks.forEach { callback in
Expand All @@ -214,8 +208,6 @@ extension SegmentationManager {
callback.fireBlock(category: data)
} else if syncStatus.contains(where: { $0.id == category.id }) {
callback.fireBlock(category: data)
} else {
callback.fireBlock(category: [])
}
case .other: break
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,63 +27,38 @@ class SegmentationSpec: QuickSpec {
let discovery: SegmentCategory = .discovery(data: [
.init(id: "id1", segmentationId: "segmentationId1"),
.init(id: "id2", segmentationId: "segmentationId2"),
.init(id: "id2", segmentationId: "segmentationId3"),
.init(id: "id2", segmentationId: "segmentationId3")
])
let discovery2: SegmentCategory = .discovery(data: [
.init(id: "id2", segmentationId: "segmentationId2"),
.init(id: "id5", segmentationId: "segmentationId5"),
.init(id: "id1", segmentationId: "segmentationId1"),
])
let discovery3: SegmentCategory = .discovery(data: [
.init(id: "id6", segmentationId: "segmentationId6"),
.init(id: "id6", segmentationId: "segmentationId6"),
.init(id: "id6", segmentationId: "segmentationId6"),
.init(id: "id8", segmentationId: "segmentationId8"),
.init(id: "id7", segmentationId: "segmentationId7"),
])

let content: SegmentCategory = .content(data: [
.init(id: "id1", segmentationId: "segmentationId1"),
.init(id: "id1", segmentationId: "segmentationId1")
])
let content2: SegmentCategory = .content(data: [
let merchandising: SegmentCategory = .merchandising(data: [
.init(id: "id2", segmentationId: "segmentationId2"),
.init(id: "id3", segmentationId: "segmentationId3"),
.init(id: "id3", segmentationId: "segmentationId5"),
])
let content1: SegmentCategory = .content(data: [
.init(id: "id3", segmentationId: "segmentationId3"),
.init(id: "id4", segmentationId: "segmentationId4"),
.init(id: "id4", segmentationId: "segmentationId4"),
.init(id: "id5", segmentationId: "segmentationId5"),
.init(id: "id1", segmentationId: "segmentationId1")
])

let fetch = [discovery, content2, discovery3]
let cache = [discovery2, content1, content]

let result = manager.unionSegments(first: fetch, second: cache)
let fetch = [discovery, content]
let cache = [content, merchandising]
let unionSegments = manager.unionSegments(fetchedCategories: fetch, cachedCategories: cache, newbies: [])
// discovery + content + merchandising
expect(unionSegments.count).to(equal(3))
var numberOfDiscovery = 0
var numberOfContent = 0

for category in result {
var numberOfMerchandising = 0
for category in unionSegments {
switch category {
case let .discovery(data):
numberOfDiscovery = data.count
default: continue
}
}

for category in result {
switch category {
case let .content(data):
numberOfContent = data.count
case let .merchandising(data):
numberOfMerchandising = data.count
default: continue
}
}

expect(numberOfDiscovery).to(equal(7))
expect(numberOfContent).to(equal(5))

expect(result.filter { $0.id == SegmentCategory.discovery().id }.count).to(equal(1))
expect(result.filter { $0.id == SegmentCategory.content().id }.count).to(equal(1))
expect(numberOfDiscovery).to(equal(3)) // is in Fetch
expect(numberOfContent).to(equal(1)) // is in Fetch
expect(numberOfMerchandising).to(equal(0)) // is only in cache, so Fetch is empty
}

it("callbacks") {
Expand Down

0 comments on commit 1107787

Please sign in to comment.