Skip to content

Commit 7b89260

Browse files
authored
Merge pull request #839 from Iterable/feature/MOB-9677-Keep-AUT-off-until-consent-to-track-has-been-granted
Keep AUT off until consent to track has been granted
2 parents fa61f91 + 6077610 commit 7b89260

File tree

10 files changed

+112
-39
lines changed

10 files changed

+112
-39
lines changed

sample-apps/swift-sample-app/swift-sample-app/Base.lproj/Main.storyboard

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="umW-9Q-hvM">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="umW-9Q-hvM">
33
<device id="retina4_7" orientation="portrait" appearance="light"/>
44
<dependencies>
55
<deployment identifier="iOS"/>
6-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
6+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
77
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
88
<capability name="collection view cell content view" minToolsVersion="11.0"/>
99
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -19,7 +19,7 @@
1919
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
2020
<color key="tintColor" red="0.31372549020000001" green="0.71372549019999998" blue="0.98823529409999999" alpha="1" colorSpace="calibratedRGB"/>
2121
<view key="tableFooterView" contentMode="scaleToFill" id="VEA-om-wVt">
22-
<rect key="frame" x="0.0" y="121.5" width="375" height="44"/>
22+
<rect key="frame" x="0.0" y="165" width="375" height="44"/>
2323
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
2424
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
2525
</view>
@@ -35,6 +35,14 @@
3535
<segue destination="Ez8-MY-tka" kind="show" identifier="showCoffeeSegue" id="pgY-3d-VNl"/>
3636
</connections>
3737
</tableViewCell>
38+
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="checkmark" indentationWidth="10" reuseIdentifier="anonymousUsageTrackCell" id="nSd-28-WlN">
39+
<rect key="frame" x="0.0" y="93.5" width="375" height="43.5"/>
40+
<autoresizingMask key="autoresizingMask"/>
41+
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="nSd-28-WlN" id="4YR-d9-FwM">
42+
<rect key="frame" x="0.0" y="0.0" width="335" height="43.5"/>
43+
<autoresizingMask key="autoresizingMask"/>
44+
</tableViewCellContentView>
45+
</tableViewCell>
3846
</prototypes>
3947
<connections>
4048
<outlet property="dataSource" destination="AsM-Cj-iLA" id="zCP-mf-9X0"/>

sample-apps/swift-sample-app/swift-sample-app/CoffeeListTableViewController.swift

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,42 @@ class CoffeeListTableViewController: UITableViewController {
6060
}
6161

6262
// MARK: - TableViewDataSourceDelegate Functions
63-
64-
override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int {
65-
filtering ? filteredCoffees.count : coffees.count
63+
override func numberOfSections(in tableView: UITableView) -> Int {
64+
return 2
65+
}
66+
override func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
67+
if section == 0 {
68+
return 1
69+
} else {
70+
return filtering ? filteredCoffees.count : coffees.count
71+
}
72+
6673
}
67-
6874
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
69-
let cell = tableView.dequeueReusableCell(withIdentifier: "coffeeCell", for: indexPath)
70-
71-
let coffeeList = filtering ? filteredCoffees : coffees
72-
let coffee = coffeeList[indexPath.row]
73-
cell.textLabel?.text = coffee.name
74-
cell.imageView?.image = coffee.image
75-
76-
return cell
75+
if indexPath.section == 0 {
76+
let cell = tableView.dequeueReusableCell(withIdentifier: "anonymousUsageTrackCell", for: indexPath)
77+
cell.textLabel?.text = IterableAPI.getAnonymousUsageTracked() ? "Tap to enable Anonymous Usage Track" : "Tap to disable Anonymous Usage Track"
78+
cell.textLabel?.numberOfLines = 0
79+
cell.accessoryType = IterableAPI.getAnonymousUsageTracked() ? .checkmark : .none
80+
return cell
81+
} else {
82+
let cell = tableView.dequeueReusableCell(withIdentifier: "coffeeCell", for: indexPath)
83+
let coffeeList = filtering ? filteredCoffees : coffees
84+
let coffee = coffeeList[indexPath.row]
85+
cell.textLabel?.text = coffee.name
86+
cell.imageView?.image = coffee.image
87+
return cell
88+
}
7789
}
78-
90+
91+
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
92+
if indexPath.section == 0 {
93+
let permissionToTrack = IterableAPI.getAnonymousUsageTracked()
94+
IterableAPI.setAnonymousUsageTracked(isAnonymousUsageTracked: !permissionToTrack)
95+
self.tableView.reloadData()
96+
}
97+
}
98+
7999
// MARK: Tap Handlers
80100

81101
@IBAction func loginOutBarButtonTapped(_: UIBarButtonItem) {
@@ -93,7 +113,7 @@ class CoffeeListTableViewController: UITableViewController {
93113
// MARK: - Navigation
94114

95115
override func prepare(for segue: UIStoryboardSegue, sender _: Any?) {
96-
guard let indexPath = tableView.indexPathForSelectedRow else {
116+
guard let indexPath = tableView.indexPathForSelectedRow, indexPath.section == 1 else {
97117
return
98118
}
99119

swift-sdk/Constants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ enum Const {
7575
static let anonymousSessions = "itbl_anon_sessions"
7676
static let matchedCriteria = "itbl_matched_criteria"
7777
static let eventList = "itbl_event_list"
78-
78+
static let anonymousUsageTrack = "itbl_anonymous_usage_track"
7979
static let attributionInfoExpiration = 24
8080
}
8181

swift-sdk/Internal/AnonymousUserManager.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ public class AnonymousUserManager: AnonymousUserManagerProtocol {
212212

213213
// Stores event data locally
214214
private func storeEventData(type: String, data: [AnyHashable: Any], shouldOverWrite: Bool? = false) {
215+
if !self.localStorage.anonymousUsageTrack {
216+
return
217+
}
218+
215219
let storedData = localStorage.anonymousUserEvents
216220
var eventsDataObjects: [[AnyHashable: Any]] = []
217221

swift-sdk/Internal/InternalIterableAPI.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,21 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
217217
}
218218
}
219219
}
220-
220+
221+
func setAnonymousUsageTracked(isAnonymousUsageTracked: Bool) {
222+
self.localStorage.anonymousUsageTrack = isAnonymousUsageTracked
223+
self.localStorage.anonymousUserEvents = nil
224+
self.localStorage.anonymousSessions = nil
225+
if isAnonymousUsageTracked {
226+
self.anonymousUserManager.getAnonCriteria()
227+
self.anonymousUserManager.updateAnonSession()
228+
}
229+
}
230+
231+
func getAnonymousUsageTracked() -> Bool {
232+
return self.localStorage.anonymousUsageTrack
233+
}
234+
221235
// MARK: - API Request Calls
222236

223237
func register(token: Data,

swift-sdk/Internal/IterableUserDefaults.swift

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class IterableUserDefaults {
99
init(userDefaults: UserDefaults = UserDefaults.standard) {
1010
self.userDefaults = userDefaults
1111
}
12-
12+
1313
// migrated to IterableKeychain
1414
var userId: String? {
1515
get {
@@ -18,7 +18,7 @@ class IterableUserDefaults {
1818
save(string: newValue, withKey: .userId)
1919
}
2020
}
21-
21+
2222
// migrated to IterableKeychain
2323
var email: String? {
2424
get {
@@ -27,7 +27,7 @@ class IterableUserDefaults {
2727
save(string: newValue, withKey: .email)
2828
}
2929
}
30-
30+
3131
// migrated to IterableKeychain
3232
var authToken: String? {
3333
get {
@@ -36,7 +36,7 @@ class IterableUserDefaults {
3636
save(string: newValue, withKey: .authToken)
3737
}
3838
}
39-
39+
4040
// deprecated, not in use anymore
4141
var ddlChecked: Bool {
4242
get {
@@ -45,31 +45,39 @@ class IterableUserDefaults {
4545
save(bool: newValue, withKey: .ddlChecked)
4646
}
4747
}
48-
48+
4949
var deviceId: String? {
5050
get {
5151
string(withKey: .deviceId)
5252
} set {
5353
save(string: newValue, withKey: .deviceId)
5454
}
5555
}
56-
56+
5757
var sdkVersion: String? {
5858
get {
5959
string(withKey: .sdkVersion)
6060
} set {
6161
save(string: newValue, withKey: .sdkVersion)
6262
}
6363
}
64-
64+
6565
var offlineMode: Bool {
6666
get {
6767
return bool(withKey: .offlineMode)
6868
} set {
6969
save(bool: newValue, withKey: .offlineMode)
7070
}
7171
}
72-
72+
73+
var anonymousUsageTrack: Bool {
74+
get {
75+
return bool(withKey: .anonymousUsageTrack)
76+
} set {
77+
save(bool: newValue, withKey: .anonymousUsageTrack)
78+
}
79+
}
80+
7381
var anonymousUserEvents: [[AnyHashable: Any]]? {
7482
get {
7583
return eventData(withKey: .anonymousUserEvents)
@@ -284,6 +292,8 @@ class IterableUserDefaults {
284292
static let anonymousUserEvents = UserDefaultsKey(value: Const.UserDefault.offlineMode)
285293
static let criteriaData = UserDefaultsKey(value: Const.UserDefault.criteriaData)
286294
static let anonymousSessions = UserDefaultsKey(value: Const.UserDefault.anonymousSessions)
295+
static let anonymousUsageTrack = UserDefaultsKey(value: Const.UserDefault.anonymousUsageTrack)
296+
287297
}
288298
private struct Envelope: Codable {
289299
let payload: Data

swift-sdk/Internal/LocalStorage.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import Foundation
66

77
struct LocalStorage: LocalStorageProtocol {
8-
8+
99
init(userDefaults: UserDefaults = UserDefaults.standard,
1010
keychain: IterableKeychain = IterableKeychain()) {
1111
iterableUserDefaults = IterableUserDefaults(userDefaults: userDefaults)
@@ -99,7 +99,15 @@ struct LocalStorage: LocalStorageProtocol {
9999
iterableUserDefaults.criteriaData = newValue
100100
}
101101
}
102-
102+
103+
var anonymousUsageTrack: Bool {
104+
get {
105+
iterableUserDefaults.anonymousUsageTrack
106+
} set {
107+
iterableUserDefaults.anonymousUsageTrack = newValue
108+
}
109+
}
110+
103111
func getAttributionInfo(currentDate: Date) -> IterableAttributionInfo? {
104112
iterableUserDefaults.getAttributionInfo(currentDate: currentDate)
105113
}

swift-sdk/Internal/LocalStorageProtocol.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ protocol LocalStorageProtocol {
2020
var sdkVersion: String? { get set }
2121

2222
var offlineMode: Bool { get set }
23-
23+
24+
var anonymousUsageTrack: Bool { get set }
25+
2426
var anonymousUserEvents: [[AnyHashable: Any]]? { get set }
2527

2628
var criteriaData: Data? { get set }

swift-sdk/IterableAPI.swift

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,21 @@ import UIKit
126126
callback?(false)
127127
}
128128

129-
if(config.enableAnonTracking) {
130-
if let _implementation = implementation {
131-
// call this to fetch anon criteria from API and save it into userdefaults
132-
if(!_implementation.isEitherUserIdOrEmailSet()) {
133-
_implementation.anonymousUserManager.getAnonCriteria()
134-
_implementation.anonymousUserManager.updateAnonSession()
135-
}
136-
}
129+
if let _implementation = implementation, config.enableAnonTracking, !_implementation.isEitherUserIdOrEmailSet(), _implementation.getAnonymousUsageTracked() {
130+
_implementation.anonymousUserManager.getAnonCriteria()
131+
_implementation.anonymousUserManager.updateAnonSession()
137132
}
138133
}
139134

135+
public static func setAnonymousUsageTracked(isAnonymousUsageTracked: Bool) {
136+
if let _implementation = implementation {
137+
_implementation.setAnonymousUsageTracked(isAnonymousUsageTracked: isAnonymousUsageTracked)
138+
}
139+
}
140+
141+
public static func getAnonymousUsageTracked() -> Bool {
142+
return implementation?.getAnonymousUsageTracked() ?? false
143+
}
140144
// MARK: - SDK
141145

142146
public static func setEmail(_ email: String?, _ authToken: String? = nil, _ identityResolution: IterableIdentityResolution? = nil, _ successHandler: OnSuccessHandler? = nil, _ failureHandler: OnFailureHandler? = nil) {

tests/common/MockLocalStorage.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Foundation
77
@testable import IterableSDK
88

99
class MockLocalStorage: LocalStorageProtocol {
10+
1011
var userIdAnnon: String?
1112

1213
var anonymousUserEvents: [[AnyHashable : Any]]?
@@ -28,7 +29,9 @@ class MockLocalStorage: LocalStorageProtocol {
2829
var sdkVersion: String? = nil
2930

3031
var offlineMode: Bool = false
31-
32+
33+
var anonymousUsageTrack: Bool = true
34+
3235
func getAttributionInfo(currentDate: Date) -> IterableAttributionInfo? {
3336
guard !MockLocalStorage.isExpired(expiration: attributionInfoExpiration, currentDate: currentDate) else {
3437
return nil

0 commit comments

Comments
 (0)