Skip to content

Commit

Permalink
Merge pull request #732 from Iterable/aut_demo
Browse files Browse the repository at this point in the history
merge all other AUT branch code
  • Loading branch information
evantk91 authored May 26, 2024
2 parents d86a75b + 8892e1d commit 67a231b
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 30 deletions.
3 changes: 3 additions & 0 deletions swift-sdk/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ enum Const {
static let userByUserId = "users/byUserId";
static let userByEmail = "users/getByEmail";
static let mergeUser = "users/merge";
static let getCriteria = "anonymoususer/list";
static let trackAnonSession = "anonymoususer/events/session";
}

public enum UserDefault {
Expand Down Expand Up @@ -178,6 +180,7 @@ enum JsonKey {
static let actionIdentifier = "actionIdentifier"
static let userText = "userText"
static let appAlreadyRunning = "appAlreadyRunning"
static let anonSessionContext = "anonSessionContext"

static let html = "html"

Expand Down
8 changes: 4 additions & 4 deletions swift-sdk/Internal/AnonymousUserManager+Functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ struct CriteriaCompletionChecker {
self.anonymousCriteria = anonymousCriteria
}

func getMatchedCriteria() -> Int? {
var criteriaId: Int? = nil
func getMatchedCriteria() -> String? {
var criteriaId: String? = nil
if let json = try? JSONSerialization.jsonObject(with: anonymousCriteria, options: []) as? [String: Any] {
// Access the criteriaList
if let criteriaList = json["criteriaList"] as? [[String: Any]] {
if let criteriaList = json["criterias"] as? [[String: Any]] {
// Iterate over the criteria
for criteria in criteriaList {
// Perform operations on each criteria
if let searchQuery = criteria["searchQuery"] as? [String: Any], let currentCriteriaId = criteria["criteriaId"] as? Int {
if let searchQuery = criteria["searchQuery"] as? [String: Any], let currentCriteriaId = criteria["criteriaId"] as? String {
// we will split purhase/updatecart event items as seperate events because we need to compare it against the single item in criteria json
var eventsToProcess = getEventsWithCartItems()
eventsToProcess.append(contentsOf: getNonCartEvents())
Expand Down
40 changes: 18 additions & 22 deletions swift-sdk/Internal/AnonymousUserManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,27 +75,33 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
// Stores an anonymous sessions locally. Updates the last session time each time when new session is created
public func updateAnonSession() {
if var sessions = localStorage.anonymousSessions {
sessions.itbl_anon_sessions.number_of_sessions += 1
sessions.itbl_anon_sessions.last_session = getUTCDateTime()
sessions.itbl_anon_sessions.totalAnonSessionCount += 1
sessions.itbl_anon_sessions.lastAnonSession = (Int(self.dateProvider.currentDate.timeIntervalSince1970) * 1000)
localStorage.anonymousSessions = sessions
} else {
// create session object for the first time
let initialAnonSessions = IterableAnonSessions(number_of_sessions: 1, last_session: getUTCDateTime(), first_session: getUTCDateTime())
let initialAnonSessions = IterableAnonSessions(totalAnonSessionCount: 1, lastAnonSession: (Int(self.dateProvider.currentDate.timeIntervalSince1970) * 1000), firstAnonSession: (Int(self.dateProvider.currentDate.timeIntervalSince1970) * 1000))
let anonSessionWrapper = IterableAnonSessionsWrapper(itbl_anon_sessions: initialAnonSessions)
localStorage.anonymousSessions = anonSessionWrapper
}
}

// Creates a user after criterias met and login the user and then sync the data through track APIs
private func createKnownUserIfCriteriaMatched(criteriaId: Int?) {
private func createKnownUserIfCriteriaMatched(criteriaId: String?) {
if (criteriaId != nil) {
var anonSessions = convertToDictionary(data: localStorage.anonymousSessions?.itbl_anon_sessions)
let userId = IterableUtil.generateUUID()
IterableAPI.setUserId(userId)
var anonSessions = convertToDictionary(data: localStorage.anonymousSessions?.itbl_anon_sessions)
anonSessions["anon_criteria_id"] = criteriaId
anonSessions["matchedCriteriaId"] = criteriaId
var appName = ""
notificationStateProvider.isNotificationsEnabled { isEnabled in
anonSessions["pushOptIn"] = isEnabled
IterableAPI.track(event: "itbl_anon_sessions", dataFields: anonSessions)
if (isEnabled) {
appName = Bundle.main.appPackageName ?? ""
}
if (!appName.isEmpty) {
anonSessions["mobilePushOptIn"] = appName
}
IterableAPI.implementation?.apiClient.trackAnonSession(createdAt: (Int(self.dateProvider.currentDate.timeIntervalSince1970) * 1000), requestJson: anonSessions)
self.syncEvents()
}
}
Expand Down Expand Up @@ -174,7 +180,7 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
}

// Checks if criterias are being met and returns criteriaId if it matches the criteria.
private func evaluateCriteriaAndReturnID() -> Int? {
private func evaluateCriteriaAndReturnID() -> String? {
guard let events = localStorage.anonymousUserEvents, let criteriaData = localStorage.criteriaData else {
return nil
}
Expand All @@ -183,19 +189,9 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
}
// Gets the anonymous criteria
public func getAnonCriteria() {
// call API when it is available and save data in userdefaults, until then just save the data in userdefaults using static data from anoncriteria_response.json
if let path = Bundle.module.path(forResource: "anoncriteria_response", ofType: "json") {
let fileURL = URL(fileURLWithPath: path)
do {
let data = try Data(contentsOf: fileURL)
// Process your data here
localStorage.criteriaData = data
} catch {
print("Error reading file: \(error)")
}
} else {
print("File not found in the package")
}
IterableAPI.implementation?.getCriteriaData { returnedData in
self.localStorage.criteriaData = returnedData
};
}

// Stores event data locally
Expand Down
10 changes: 10 additions & 0 deletions swift-sdk/Internal/ApiClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,14 @@ extension ApiClient: ApiClientProtocol {
let result = createRequestCreator().flatMap { $0.createMergeUserRequest(sourceEmail, sourceUserId, destinationEmail, destinationUserId: destinationUserId) }
return send(iterableRequestResult: result)
}

func getCriteria() -> Pending<SendRequestValue, SendRequestError> {
let result = createRequestCreator().flatMap { $0.createGetCriteriaRequest() }
return send(iterableRequestResult: result)
}

func trackAnonSession(createdAt: Int, requestJson: [AnyHashable: Any]) -> Pending<SendRequestValue, SendRequestError> {
let result = createRequestCreator().flatMap { $0.createTrackAnonSessionRequest(createdAt: createdAt, requestJson: requestJson) }
return send(iterableRequestResult: result)
}
}
4 changes: 4 additions & 0 deletions swift-sdk/Internal/ApiClientProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@ protocol ApiClientProtocol: AnyObject {
func getUserByEmail(email: String) -> Pending<SendRequestValue, SendRequestError>

func mergeUser(sourceEmail: String, sourceUserId: String, destinationEmail: String, destinationUserId: String) -> Pending<SendRequestValue, SendRequestError>

func getCriteria() -> Pending<SendRequestValue, SendRequestError>

func trackAnonSession(createdAt: Int, requestJson: [AnyHashable: Any]) -> Pending<SendRequestValue, SendRequestError>
}
19 changes: 18 additions & 1 deletion swift-sdk/Internal/InternalIterableAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,13 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
logoutPreviousUser()

_email = nil
_userId = userId
if _userId == nil {
_userId = userId
localStorage.userId = userId
anonymousUserManager.syncNonSyncedEvents()
} else {
_userId = userId
}
_successCallback = successHandler
_failureCallback = failureHandler

Expand Down Expand Up @@ -781,6 +787,17 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
}
}

func getCriteriaData(completion: @escaping (Data) -> Void) {
apiClient.getCriteria().onSuccess { data in
do {
let jsonData = try JSONSerialization.data(withJSONObject: data, options: [])
completion(jsonData)
} catch {
print("Error converting dictionary to data: \(error)")
}
}
}

deinit {
ITBInfo()
requestHandler.stop()
Expand Down
6 changes: 3 additions & 3 deletions swift-sdk/Internal/Models.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ struct CriteriaItem: Codable {
}

struct IterableAnonSessions: Codable {
var number_of_sessions: Int
var last_session: String
var first_session: String
var totalAnonSessionCount: Int
var lastAnonSession: Int
var firstAnonSession: Int
}

struct IterableAnonSessionsWrapper: Codable {
Expand Down
20 changes: 20 additions & 0 deletions swift-sdk/Internal/RequestCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,26 @@ struct RequestCreator {
return .success(.post(createPostRequest(path: Const.Path.mergeUser, body: body)))
}

func createGetCriteriaRequest() -> Result<IterableRequest, IterableError> {
let body: [AnyHashable: Any] = [:]
return .success(.get(createGetRequest(forPath: Const.Path.getCriteria, withArgs: body as! [String: String])))
}

func createTrackAnonSessionRequest(createdAt: Int, requestJson: [AnyHashable: Any]) -> Result<IterableRequest, IterableError> {
if case .none = auth.emailOrUserId {
ITBError(Self.authMissingMessage)
return .failure(IterableError.general(description: Self.authMissingMessage))
}

var body = [AnyHashable: Any]()

setCurrentUser(inDict: &body)
body.setValue(for: JsonKey.Body.createdAt, value: createdAt)
body.setValue(for: JsonKey.deviceInfo, value: deviceMetadata.asDictionary())
body.setValue(for: JsonKey.anonSessionContext, value: requestJson)
return .success(.post(createPostRequest(path: Const.Path.trackAnonSession, body: body)))
}

// MARK: - PRIVATE

private static let authMissingMessage = "Both email and userId are nil"
Expand Down

0 comments on commit 67a231b

Please sign in to comment.