Skip to content

Commit

Permalink
Releasing 4.9.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Rover Release Bot 🤖 committed Dec 18, 2024
1 parent 9c313cf commit 4f98bc8
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 42 deletions.
16 changes: 13 additions & 3 deletions Sources/AXS/AXSAuthorizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,23 @@ public protocol AXSAuthorizer {
/**
Set the user's AXS credentials after a successful sign-in.

- Parameters:
- userId: The value of the `userId` property.
- Parameter userId: The value of the `userID` property.
*/
@available(*, deprecated, renamed: "setUserID")
func setUserId(_ userId: String)


/**
Set the user's AXS credentials after a successful sign-in. If `userID` is nil, then it is treated as a sign out.

- Parameter userID: The value of the `userID` property.
- Parameter flashMemberID: A Flash Seats Member ID.
- Parameter flashMobileID: A Flash Seats Mobile ID.
*/
func setUserID(_ userID: String?, flashMemberID: String?, flashMobileID: String?)

/**
Clear the user's AXS credentials after a successful sign-out.
*/
func clearCredentials()
}

67 changes: 46 additions & 21 deletions Sources/AXS/AXSManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,46 +23,71 @@ class AXSManager: AXSAuthorizer, PrivacyListener {
private let privacyService: PrivacyService

private var userID = PersistedValue<String>(storageKey: "io.rover.axs")

private var flashMemberID = PersistedValue<String>(storageKey: "io.rover.axs.flashMemberID")
private var flashMobileID = PersistedValue<String>(storageKey: "io.rover.axs.flashMobileID")

private var axsUserInfo: [String: String]? {
guard let userID = self.userID.value else {
return nil
var dictionary = [String: String]()

if let userID = self.userID.value {
dictionary["userID"] = userID
}

if let flashMemberID = self.flashMemberID.value {
dictionary["flashMemberID"] = flashMemberID
}

if let flashMobileID = self.flashMobileID.value {
dictionary["flashMobileID"] = flashMobileID
}

return ["userID": userID]
return dictionary
}

init(userInfoManager: UserInfoManager, privacyService: PrivacyService) {
self.userInfoManager = userInfoManager
self.privacyService = privacyService
}

// MARK: AxsAuthorizer

func setUserId(_ id: String) {
setUserID(id, flashMemberID: nil, flashMobileID: nil)
}

func setUserID(_ userID: String?, flashMemberID: String?, flashMobileID: String?) {
guard privacyService.trackingMode == .default else {
return
}

self.userID.value = id
guard let userID else {
clearCredentials()
return
}

self.userID.value = userID
self.flashMemberID.value = flashMemberID
self.flashMobileID.value = flashMobileID

guard let userInfo = axsUserInfo else {
return
}

updateUserInfo(userInfo)

if let userInfo = axsUserInfo {
self.userInfoManager.updateUserInfo {
if let existingAxsUserInfo = $0.rawValue["axs"] as? Attributes {
// axs data already exists, just clobber it:
$0.rawValue["axs"] = Attributes(rawValue: existingAxsUserInfo.rawValue.merging(userInfo) { $1 })
} else {
// axs data does not already exist, so set it:
$0.rawValue["axs"] = Attributes(rawValue: userInfo)
}
}

os_log("AXSID has been set: %s", log: .general, userID.value!)
os_log("AXS IDs have been set. user ID: %s, flashMemberID: %s, flashMobileID: %s", log: .general, userID, flashMemberID ?? "nil", flashMobileID ?? "nil")
}

private func updateUserInfo(_ userInfo: [String: String]) {
self.userInfoManager.updateUserInfo {
$0.rawValue["axs"] = Attributes(rawValue: userInfo)
}
}

func clearCredentials() {
self.userID.value = nil
self.flashMemberID.value = nil
self.flashMobileID.value = nil
self.userInfoManager.updateUserInfo { attributes in
attributes.rawValue["axs"] = nil
}
Expand All @@ -72,7 +97,7 @@ class AXSManager: AXSAuthorizer, PrivacyListener {

func trackingModeDidChange(_ trackingMode: PrivacyService.TrackingMode) {
if(trackingMode != .default) {
os_log("Tracking disabled, axs data cleared", log: .axs)
os_log("Tracking disabled, AXS data cleared", log: .axs)
clearCredentials()
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Data/Context/ContextManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ extension ContextManager: StaticContextProvider {
#endif
}

var deviceIdentifier: String {
return UIDevice.current.identifierForVendor!.uuidString
var deviceIdentifier: String? {
return UIDevice.current.identifierForVendor?.uuidString
}

var deviceManufacturer: String {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Data/Context/Providers/StaticContextProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public protocol StaticContextProvider: AnyObject {
var appIdentifier: String { get }
var appVersion: String { get }
var buildEnvironment: Context.BuildEnvironment { get }
var deviceIdentifier: String { get }
var deviceIdentifier: String? { get }
var deviceManufacturer: String { get }
var deviceModel: String { get }
var deviceName: String { get }
Expand Down
4 changes: 4 additions & 0 deletions Sources/Data/EventQueue/EventQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ public class EventQueue {
public func addEvent(_ info: EventInfo) {
let context = self.contextProvider.context

guard context.deviceIdentifier != nil else {
return
}

let event = Event(
name: info.name,
context: context,
Expand Down
5 changes: 4 additions & 1 deletion Sources/Experiences/Experiences/Model/ExperienceModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class ExperienceModel: Decodable {
var gradients = [DocumentGradient]()
var localization = StringTable()
var fonts = [DocumentFont]()

/// Font download URLs
var fontURLs: [URL] {
fonts.flatMap { $0.sources.map {$0.assetUrl} }
Expand All @@ -54,6 +54,9 @@ final class ExperienceModel: Decodable {
return initialScreen!.id
}

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

/// Initialize Experience from data (JSON)
Expand Down
17 changes: 11 additions & 6 deletions Sources/Experiences/Experiences/UI/CarouselState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import Foundation
import Combine
import RoverFoundation

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

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

init(experienceId: String?) {
self.experienceId = experienceId
init(experienceUrl: String?) {
self.experienceUrl = experienceUrl
}

private func persistenceKey(for viewID: ViewID) -> String {
let urlBase64 = experienceUrl.flatMap { $0.data(using: .utf8)?.base64EncodedString() }
return "\(urlBase64 ?? "unknown")-\(viewID.toString())"
}

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

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

func getPersistedPosition(for viewID: ViewID) -> Int {
let carouselIdentifier = "\(experienceId ?? "local")-\(viewID.toString())"

let carouselIdentifier = persistenceKey(for: viewID)
guard let carouselPositions = persistedCarouselPositions.value,
let value = carouselPositions[carouselIdentifier] else {
return 0
Expand Down
8 changes: 4 additions & 4 deletions Sources/Experiences/Experiences/UI/ImageFetcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ struct ImageFetcher<Content, Placeholder>: View where Content: View, Placeholder
var body: some View {
if let uiImage = uiImage {
content(uiImage)
.onValueChanged(of: url) { _ in
startFetch()
.onValueChanged(of: url) { url in
startFetch(url: url)
}
} else {
placeholder.onAppear {
startFetch()
startFetch(url: url)
}
}
}

private func startFetch() {
private func startFetch(url: URL) {
let experienceManager = Rover.shared.resolve(ExperienceManager.self)!

func setState(_ state: FetchState) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ScreenViewController: UIViewController, UIScrollViewDelegate {
self.urlParameters = urlParameters
self.userInfo = userInfo
self.authorize = authorize
self.carouselState = CarouselState(experienceId: experience.id)
self.carouselState = CarouselState(experienceUrl: experience.sourceUrl?.absoluteString)
super.init(nibName: nil, bundle: nil)
super.restorationIdentifier = screen.id
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class ExperienceStoreService: ExperienceStore {
if url.isFileURL {
do {
if let experienceObj = try read(contentsOf: url) {
experienceObj.sourceUrl = url
let experience = LoadedExperience.file(
experience: experienceObj,
urlParameters: experienceObj.urlParameters,
Expand Down Expand Up @@ -156,7 +157,7 @@ class ExperienceStoreService: ExperienceStore {
completionHandler(.failure(.invalidExperienceData(error)))
return
}

let key = CacheKey(url: experienceUrl)
let value = CacheValue(experience: experience)
self.cache.setObject(value, forKey: key)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Foundation/Meta.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ import Foundation

public enum Meta {
public static let APIVersion: Int = 2
public static let SDKVersion: String = "4.8.1"
public static let SDKVersion: String = "4.9.0"
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class NotificationsSyncParticipant: SyncParticipant {
}

func initialRequest() -> SyncRequest? {
guard let uuidString = UIDevice.current.identifierForVendor?.uuidString else {
return nil
}

let orderBy: Attributes = [
"field": "CREATED_AT",
"direction": "DESC"
Expand All @@ -36,7 +40,7 @@ class NotificationsSyncParticipant: SyncParticipant {
values: [
"last": 500,
"orderBy": orderBy,
"deviceIdentifier": UIDevice.current.identifierForVendor!.uuidString
"deviceIdentifier": uuidString
]
)
}
Expand Down

0 comments on commit 4f98bc8

Please sign in to comment.