Skip to content

Commit 4f98bc8

Browse files
author
Rover Release Bot 🤖
committed
Releasing 4.9.0
1 parent 9c313cf commit 4f98bc8

12 files changed

Lines changed: 94 additions & 42 deletions

File tree

Sources/AXS/AXSAuthorizer.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,23 @@ public protocol AXSAuthorizer {
1818
/**
1919
Set the user's AXS credentials after a successful sign-in.
2020

21-
- Parameters:
22-
- userId: The value of the `userId` property.
21+
- Parameter userId: The value of the `userID` property.
2322
*/
23+
@available(*, deprecated, renamed: "setUserID")
2424
func setUserId(_ userId: String)
25-
25+
26+
/**
27+
Set the user's AXS credentials after a successful sign-in. If `userID` is nil, then it is treated as a sign out.
28+
29+
- Parameter userID: The value of the `userID` property.
30+
- Parameter flashMemberID: A Flash Seats Member ID.
31+
- Parameter flashMobileID: A Flash Seats Mobile ID.
32+
*/
33+
func setUserID(_ userID: String?, flashMemberID: String?, flashMobileID: String?)
34+
2635
/**
2736
Clear the user's AXS credentials after a successful sign-out.
2837
*/
2938
func clearCredentials()
3039
}
40+

Sources/AXS/AXSManager.swift

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,46 +23,71 @@ class AXSManager: AXSAuthorizer, PrivacyListener {
2323
private let privacyService: PrivacyService
2424

2525
private var userID = PersistedValue<String>(storageKey: "io.rover.axs")
26-
26+
private var flashMemberID = PersistedValue<String>(storageKey: "io.rover.axs.flashMemberID")
27+
private var flashMobileID = PersistedValue<String>(storageKey: "io.rover.axs.flashMobileID")
28+
2729
private var axsUserInfo: [String: String]? {
28-
guard let userID = self.userID.value else {
29-
return nil
30+
var dictionary = [String: String]()
31+
32+
if let userID = self.userID.value {
33+
dictionary["userID"] = userID
34+
}
35+
36+
if let flashMemberID = self.flashMemberID.value {
37+
dictionary["flashMemberID"] = flashMemberID
38+
}
39+
40+
if let flashMobileID = self.flashMobileID.value {
41+
dictionary["flashMobileID"] = flashMobileID
3042
}
3143

32-
return ["userID": userID]
44+
return dictionary
3345
}
34-
46+
3547
init(userInfoManager: UserInfoManager, privacyService: PrivacyService) {
3648
self.userInfoManager = userInfoManager
3749
self.privacyService = privacyService
3850
}
3951

4052
// MARK: AxsAuthorizer
41-
53+
4254
func setUserId(_ id: String) {
55+
setUserID(id, flashMemberID: nil, flashMobileID: nil)
56+
}
57+
58+
func setUserID(_ userID: String?, flashMemberID: String?, flashMobileID: String?) {
4359
guard privacyService.trackingMode == .default else {
4460
return
4561
}
4662

47-
self.userID.value = id
63+
guard let userID else {
64+
clearCredentials()
65+
return
66+
}
67+
68+
self.userID.value = userID
69+
self.flashMemberID.value = flashMemberID
70+
self.flashMobileID.value = flashMobileID
71+
72+
guard let userInfo = axsUserInfo else {
73+
return
74+
}
75+
76+
updateUserInfo(userInfo)
4877

49-
if let userInfo = axsUserInfo {
50-
self.userInfoManager.updateUserInfo {
51-
if let existingAxsUserInfo = $0.rawValue["axs"] as? Attributes {
52-
// axs data already exists, just clobber it:
53-
$0.rawValue["axs"] = Attributes(rawValue: existingAxsUserInfo.rawValue.merging(userInfo) { $1 })
54-
} else {
55-
// axs data does not already exist, so set it:
56-
$0.rawValue["axs"] = Attributes(rawValue: userInfo)
57-
}
58-
}
59-
60-
os_log("AXSID has been set: %s", log: .general, userID.value!)
78+
os_log("AXS IDs have been set. user ID: %s, flashMemberID: %s, flashMobileID: %s", log: .general, userID, flashMemberID ?? "nil", flashMobileID ?? "nil")
79+
}
80+
81+
private func updateUserInfo(_ userInfo: [String: String]) {
82+
self.userInfoManager.updateUserInfo {
83+
$0.rawValue["axs"] = Attributes(rawValue: userInfo)
6184
}
6285
}
63-
86+
6487
func clearCredentials() {
6588
self.userID.value = nil
89+
self.flashMemberID.value = nil
90+
self.flashMobileID.value = nil
6691
self.userInfoManager.updateUserInfo { attributes in
6792
attributes.rawValue["axs"] = nil
6893
}
@@ -72,7 +97,7 @@ class AXSManager: AXSAuthorizer, PrivacyListener {
7297

7398
func trackingModeDidChange(_ trackingMode: PrivacyService.TrackingMode) {
7499
if(trackingMode != .default) {
75-
os_log("Tracking disabled, axs data cleared", log: .axs)
100+
os_log("Tracking disabled, AXS data cleared", log: .axs)
76101
clearCredentials()
77102
}
78103
}

Sources/Data/Context/ContextManager.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ extension ContextManager: StaticContextProvider {
160160
#endif
161161
}
162162

163-
var deviceIdentifier: String {
164-
return UIDevice.current.identifierForVendor!.uuidString
163+
var deviceIdentifier: String? {
164+
return UIDevice.current.identifierForVendor?.uuidString
165165
}
166166

167167
var deviceManufacturer: String {

Sources/Data/Context/Providers/StaticContextProvider.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public protocol StaticContextProvider: AnyObject {
2121
var appIdentifier: String { get }
2222
var appVersion: String { get }
2323
var buildEnvironment: Context.BuildEnvironment { get }
24-
var deviceIdentifier: String { get }
24+
var deviceIdentifier: String? { get }
2525
var deviceManufacturer: String { get }
2626
var deviceModel: String { get }
2727
var deviceName: String { get }

Sources/Data/EventQueue/EventQueue.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ public class EventQueue {
130130
public func addEvent(_ info: EventInfo) {
131131
let context = self.contextProvider.context
132132

133+
guard context.deviceIdentifier != nil else {
134+
return
135+
}
136+
133137
let event = Event(
134138
name: info.name,
135139
context: context,

Sources/Experiences/Experiences/Model/ExperienceModel.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ final class ExperienceModel: Decodable {
3333
var gradients = [DocumentGradient]()
3434
var localization = StringTable()
3535
var fonts = [DocumentFont]()
36-
36+
3737
/// Font download URLs
3838
var fontURLs: [URL] {
3939
fonts.flatMap { $0.sources.map {$0.assetUrl} }
@@ -54,6 +54,9 @@ final class ExperienceModel: Decodable {
5454
return initialScreen!.id
5555
}
5656

57+
/// The URL this experience was loaded from.
58+
///
59+
/// NB. Unlike the other fields, this one is not populated from the contents of the experience JSON.
5760
var sourceUrl: URL?
5861

5962
/// Initialize Experience from data (JSON)

Sources/Experiences/Experiences/UI/CarouselState.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1414
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1515

16+
import Foundation
1617
import Combine
1718
import RoverFoundation
1819

@@ -22,16 +23,21 @@ final class CarouselState: ObservableObject {
2223
@Published var currentNumberOfPagesForCarousel: [ViewID: Int] = [:]
2324
@Published var storyStyleStatusForCarousel: [ViewID: Bool] = [:]
2425
@Published var currentBarProgressForCarousel: [ViewID: [Double]] = [:]
25-
private let experienceId: String?
26+
private let experienceUrl: String?
2627

2728
private let persistedCarouselPositions = PersistedValue<[String: Int]>(storageKey: "io.rover.experience.carouselPositions")
2829

29-
init(experienceId: String?) {
30-
self.experienceId = experienceId
30+
init(experienceUrl: String?) {
31+
self.experienceUrl = experienceUrl
32+
}
33+
34+
private func persistenceKey(for viewID: ViewID) -> String {
35+
let urlBase64 = experienceUrl.flatMap { $0.data(using: .utf8)?.base64EncodedString() }
36+
return "\(urlBase64 ?? "unknown")-\(viewID.toString())"
3137
}
3238

3339
func setPersistedPosition(for viewID: ViewID, newValue: Int) {
34-
let carouselIdentifier = "\(experienceId ?? "local")-\(viewID.toString())"
40+
let carouselIdentifier = persistenceKey(for: viewID)
3541

3642
guard var carouselPositions = persistedCarouselPositions.value else {
3743
persistedCarouselPositions.value = [carouselIdentifier: newValue]
@@ -43,8 +49,7 @@ final class CarouselState: ObservableObject {
4349
}
4450

4551
func getPersistedPosition(for viewID: ViewID) -> Int {
46-
let carouselIdentifier = "\(experienceId ?? "local")-\(viewID.toString())"
47-
52+
let carouselIdentifier = persistenceKey(for: viewID)
4853
guard let carouselPositions = persistedCarouselPositions.value,
4954
let value = carouselPositions[carouselIdentifier] else {
5055
return 0

Sources/Experiences/Experiences/UI/ImageFetcher.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ struct ImageFetcher<Content, Placeholder>: View where Content: View, Placeholder
3939
var body: some View {
4040
if let uiImage = uiImage {
4141
content(uiImage)
42-
.onValueChanged(of: url) { _ in
43-
startFetch()
42+
.onValueChanged(of: url) { url in
43+
startFetch(url: url)
4444
}
4545
} else {
4646
placeholder.onAppear {
47-
startFetch()
47+
startFetch(url: url)
4848
}
4949
}
5050
}
5151

52-
private func startFetch() {
52+
private func startFetch(url: URL) {
5353
let experienceManager = Rover.shared.resolve(ExperienceManager.self)!
5454

5555
func setState(_ state: FetchState) {

Sources/Experiences/Experiences/UI/ScreenViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ScreenViewController: UIViewController, UIScrollViewDelegate {
3535
self.urlParameters = urlParameters
3636
self.userInfo = userInfo
3737
self.authorize = authorize
38-
self.carouselState = CarouselState(experienceId: experience.id)
38+
self.carouselState = CarouselState(experienceUrl: experience.sourceUrl?.absoluteString)
3939
super.init(nibName: nil, bundle: nil)
4040
super.restorationIdentifier = screen.id
4141
}

Sources/Experiences/Services/ExperienceStore/ExperienceStoreService.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class ExperienceStoreService: ExperienceStore {
7979
if url.isFileURL {
8080
do {
8181
if let experienceObj = try read(contentsOf: url) {
82+
experienceObj.sourceUrl = url
8283
let experience = LoadedExperience.file(
8384
experience: experienceObj,
8485
urlParameters: experienceObj.urlParameters,
@@ -156,7 +157,7 @@ class ExperienceStoreService: ExperienceStore {
156157
completionHandler(.failure(.invalidExperienceData(error)))
157158
return
158159
}
159-
160+
160161
let key = CacheKey(url: experienceUrl)
161162
let value = CacheValue(experience: experience)
162163
self.cache.setObject(value, forKey: key)

0 commit comments

Comments
 (0)