diff --git a/Sources/Amplitude/Amplitude.swift b/Sources/Amplitude/Amplitude.swift index f14bd79b..e73b95f2 100644 --- a/Sources/Amplitude/Amplitude.swift +++ b/Sources/Amplitude/Amplitude.swift @@ -278,6 +278,13 @@ public class Amplitude { return sessions.sessionId } + @discardableResult + public func setSessionId(timestamp: Int64) -> Amplitude { + let sessionEvents = sessions.assignEventId(events: sessions.startNewSession(timestamp: timestamp)) + sessionEvents.forEach { e in timeline.processEvent(event: e) } + return self + } + @discardableResult public func reset() -> Amplitude { _ = setUserId(userId: nil) diff --git a/Sources/Amplitude/ObjC/ObjCAmplitude.swift b/Sources/Amplitude/ObjC/ObjCAmplitude.swift index eb47b46b..eea95c44 100644 --- a/Sources/Amplitude/ObjC/ObjCAmplitude.swift +++ b/Sources/Amplitude/ObjC/ObjCAmplitude.swift @@ -200,6 +200,13 @@ public class ObjCAmplitude: NSObject { amplitude.getSessionId() } + @objc(setSessionId:) + @discardableResult + public func setSessionId(timestamp: Int64) -> ObjCAmplitude { + amplitude.setSessionId(timestamp: timestamp) + return self + } + @objc @discardableResult public func reset() -> ObjCAmplitude { diff --git a/Sources/Amplitude/Sessions.swift b/Sources/Amplitude/Sessions.swift index 424e684d..c8786a61 100644 --- a/Sources/Amplitude/Sessions.swift +++ b/Sources/Amplitude/Sessions.swift @@ -81,9 +81,13 @@ public class Sessions { result.append(event) } + return assignEventId(events: result) + } + + func assignEventId(events: [BaseEvent]) -> [BaseEvent] { var newLastEventId = self.lastEventId - result.forEach({ event in + events.forEach({ event in if event.eventId == nil { newLastEventId += 1 event.eventId = newLastEventId @@ -92,7 +96,7 @@ public class Sessions { self.lastEventId = newLastEventId - return result + return events } private func isWithinMinTimeBetweenSessions(timestamp: Int64) -> Bool { diff --git a/Tests/AmplitudeTests/AmplitudeSessionTests.swift b/Tests/AmplitudeTests/AmplitudeSessionTests.swift index aa3d8eab..905af594 100644 --- a/Tests/AmplitudeTests/AmplitudeSessionTests.swift +++ b/Tests/AmplitudeTests/AmplitudeSessionTests.swift @@ -419,6 +419,103 @@ final class AmplitudeSessionTests: XCTestCase { XCTAssertEqual(event.eventId, lastEventId+4) } + func testSetSessionIdInBackgroundShouldStartNewSession() throws { + let lastEventId: Int64 = 123 + try storageMem.write(key: StorageKey.LAST_EVENT_ID, value: lastEventId) + + let amplitude = Amplitude(configuration: configuration) + + let eventCollector = EventCollectorPlugin() + amplitude.add(plugin: eventCollector) + + amplitude.track(event: BaseEvent(userId: "user", timestamp: 100, eventType: "test event 1")) + amplitude.setSessionId(timestamp: 150) + amplitude.track(event: BaseEvent(userId: "user", timestamp: 200, eventType: "test event 2")) + + let collectedEvents = eventCollector.events + + XCTAssertEqual(collectedEvents.count, 5) + + var event = collectedEvents[0] + XCTAssertEqual(event.eventType, Constants.AMP_SESSION_START_EVENT) + XCTAssertEqual(event.sessionId, 100) + XCTAssertEqual(event.timestamp, 100) + XCTAssertEqual(event.eventId, lastEventId+1) + + event = collectedEvents[1] + XCTAssertEqual(event.eventType, "test event 1") + XCTAssertEqual(event.sessionId, 100) + XCTAssertEqual(event.timestamp, 100) + XCTAssertEqual(event.eventId, lastEventId+2) + + event = collectedEvents[2] + XCTAssertEqual(event.eventType, Constants.AMP_SESSION_END_EVENT) + XCTAssertEqual(event.sessionId, 100) + XCTAssertEqual(event.timestamp, 100) + XCTAssertEqual(event.eventId, lastEventId+3) + + event = collectedEvents[3] + XCTAssertEqual(event.eventType, Constants.AMP_SESSION_START_EVENT) + XCTAssertEqual(event.sessionId, 150) + XCTAssertEqual(event.timestamp, 150) + XCTAssertEqual(event.eventId, lastEventId+4) + + event = collectedEvents[4] + XCTAssertEqual(event.eventType, "test event 2") + XCTAssertEqual(event.sessionId, 150) + XCTAssertEqual(event.timestamp, 200) + XCTAssertEqual(event.eventId, lastEventId+5) + } + + func testSetSessionIdInForegroundShouldStartNewSession() throws { + let lastEventId: Int64 = 123 + try storageMem.write(key: StorageKey.LAST_EVENT_ID, value: lastEventId) + + let amplitude = Amplitude(configuration: configuration) + + let eventCollector = EventCollectorPlugin() + amplitude.add(plugin: eventCollector) + + amplitude.onEnterForeground(timestamp: 1000) + amplitude.track(event: BaseEvent(userId: "user", timestamp: 1050, eventType: "test event 1")) + amplitude.setSessionId(timestamp: 1100) + amplitude.track(event: BaseEvent(userId: "user", timestamp: 2000, eventType: "test event 2")) + + let collectedEvents = eventCollector.events + + XCTAssertEqual(collectedEvents.count, 5) + + var event = collectedEvents[0] + XCTAssertEqual(event.eventType, Constants.AMP_SESSION_START_EVENT) + XCTAssertEqual(event.sessionId, 1000) + XCTAssertEqual(event.timestamp, 1000) + XCTAssertEqual(event.eventId, lastEventId+1) + + event = collectedEvents[1] + XCTAssertEqual(event.eventType, "test event 1") + XCTAssertEqual(event.sessionId, 1000) + XCTAssertEqual(event.timestamp, 1050) + XCTAssertEqual(event.eventId, lastEventId+2) + + event = collectedEvents[2] + XCTAssertEqual(event.eventType, Constants.AMP_SESSION_END_EVENT) + XCTAssertEqual(event.sessionId, 1000) + XCTAssertEqual(event.timestamp, 1050) + XCTAssertEqual(event.eventId, lastEventId+3) + + event = collectedEvents[3] + XCTAssertEqual(event.eventType, Constants.AMP_SESSION_START_EVENT) + XCTAssertEqual(event.sessionId, 1100) + XCTAssertEqual(event.timestamp, 1100) + XCTAssertEqual(event.eventId, lastEventId+4) + + event = collectedEvents[4] + XCTAssertEqual(event.eventType, "test event 2") + XCTAssertEqual(event.sessionId, 1100) + XCTAssertEqual(event.timestamp, 2000) + XCTAssertEqual(event.eventId, lastEventId+5) + } + func getDictionary(_ props: [String: Any?]) -> NSDictionary { return NSDictionary(dictionary: props as [AnyHashable: Any]) }