-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMPRoktLayout.swift
More file actions
135 lines (123 loc) · 5.7 KB
/
Copy pathMPRoktLayout.swift
File metadata and controls
135 lines (123 loc) · 5.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// MPRoktLayout.swift
// mParticle-Rokt
//
// Copyright 2025 Rokt Pte Ltd
//
// Licensed under the Rokt Software Development Kit (SDK) Terms of Use
// Version 2.0 (the "License");
//
// You may not use this file except in compliance with the License.
//
// You may obtain a copy of the License at https://rokt.com/sdk-license-2-0/
import SwiftUI
import Rokt_Widget
import mParticle_Apple_SDK
import mParticle_Rokt
@available(iOS 15, *)
public class MPRoktLayout {
public var roktLayout: RoktLayout? = nil
let mparticle = MParticle.sharedInstance()
public init(
sdkTriggered: Binding<Bool>,
viewName: String? = nil,
locationName: String = "",
attributes: [String: String],
config: RoktConfig? = nil,
onEvent: ((RoktEvent) -> Void)? = nil
) {
MPRoktLayout.mpLog("Initializing MPRoktLayout with arguments sdkTriggered:\(sdkTriggered.wrappedValue), viewName:\(viewName ?? "nil"), locationName:\(locationName), attributes:\(attributes)")
confirmUser(attributes: attributes) { identifyCalled in
let preparedAttributes = MPKitRokt.prepareAttributes(attributes, filteredUser: Optional<FilteredMParticleUser>.none, performMapping: true)
MPRoktLayout.mpLog("Initializing RoktLayout with arguments sdkTriggered:\(sdkTriggered.wrappedValue), viewName: \(viewName ?? "nil"), locationName:\(locationName), attributes:\(preparedAttributes)")
self.roktLayout = RoktLayout.init(
sdkTriggered: sdkTriggered,
viewName: viewName,
locationName: locationName,
attributes: preparedAttributes,
config: config,
onEvent: onEvent
)
// The Binding variable provided by the client allows us to trigger a re-render of the UI but we only want to do this if the value was true to start
if identifyCalled && sdkTriggered.wrappedValue {
MPRoktLayout.mpLog("Triggering Rokt Swift UI re-render")
DispatchQueue.main.async {
sdkTriggered.wrappedValue = false
sdkTriggered.wrappedValue = true
}
}
}
}
func confirmUser(
attributes: [String: String]?,
completion: @escaping (Bool) -> Void
) {
guard let user = mparticle.identity.currentUser else {
completion(false)
return
}
let email = attributes?["email"]
let hashedEmail = attributes?["emailsha256"]
let hashedEmailIdentity = MPKitRokt.getHashedEmailUserIdentityType()
let userEmailIdentity = user.identities[NSNumber(value: MPIdentity.email.rawValue)]
let emailMismatch: Bool = {
guard let email = email,
let userEmail = user.identities[NSNumber(value: MPIdentity.email.rawValue)] else {
return false
}
return email != userEmail
}()
let hashedEmailMismatch: Bool = {
guard let hashedEmail = hashedEmail,
let hashedEmailIdentity = hashedEmailIdentity,
let userHashedEmail = user.identities[hashedEmailIdentity] else {
return false
}
return hashedEmail != userHashedEmail
}()
if emailMismatch || hashedEmailMismatch {
// If there is an existing email or hashed email but it doesn't match what was passed in, warn the customer
if emailMismatch {
MPRoktLayout.mpLog("The existing email on the user (\(userEmailIdentity ?? "nil")) does not match the email passed in to `selectPlacements:` (\(email ?? "nil")). Please remember to sync the email identity to mParticle as soon as you receive it. We will now identify the user before creating the layout")
}
if hashedEmailMismatch {
MPRoktLayout.mpLog("The existing hashed email on the user (\(user.identities[hashedEmailIdentity ?? NSNumber(value: -1)] ?? "nil")) does not match the email passed in to `selectPlacements:` (\(hashedEmail ?? "nil")). Please remember to sync the hashed email identity to mParticle as soon as you receive it. We will now identify the user before creating the layout")
}
syncIdentities(user: user, email: email, hashedEmail: hashedEmail, hashedEmailKey: hashedEmailIdentity) {
completion(true)
}
} else {
completion(false)
}
}
func syncIdentities(
user: MParticleUser,
email: String?,
hashedEmail: String?,
hashedEmailKey: NSNumber?,
completion: @escaping () -> Void
) {
let identityRequest = MPIdentityApiRequest(user: user)
identityRequest.setIdentity(email, identityType: .email)
if let hashedEmailKey = hashedEmailKey {
identityRequest.setIdentity(hashedEmail, identityType: MPIdentity(rawValue: hashedEmailKey.uintValue) ?? .other)
}
mparticle.identity.identify(identityRequest) {apiResult, error in
if let error = error {
MPRoktLayout.mpLog("Failed to sync email from selectPlacement to user: \(error)")
completion()
} else {
if let identities = apiResult?.user.identities {
MPRoktLayout.mpLog("Updated user identity based off selectPlacement's attributes: \(identities)")
}
completion()
}
}
}
static func mpLog(_ message: String) {
let msg = "MPRokt -> \(message)"
if MParticle.sharedInstance().environment == .development {
print(msg)
}
}
}