最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

swift - How to observe the properties of a service class from my view model? - Stack Overflow

programmeradmin1浏览0评论

I have 2 classes: UpNextViewModel and UpNextService.

How to ensure the isShuffled property between the view model and service is in sync?

The ultimate source of truth is the service class since multiple views are watching for changes to the property.

The isShuffled property is watched among multiple views in my app and is updated through a button by multiple views as well.

struct UpNextItem {
    var id = UUID()
    var audioFileId: UUID
}

// Directly works with UpNextView when user taps on button to switch on shuffle
@Observable
class UpNextViewModel {
    var repeatStatus: RepeatStatus = .none

    var isShuffled: Bool = false // Reflects the state of the shuffle status on the view. Updates the property of the service class
    
    let upNextService: UpNextService
    
    init(upNextService: UpNextService) {
        self.upNextService = upNextService
    }
}

@Observable
class UpNextService {
    var isShuffled = false // This property should notify the respective view models when changed.
    func writeItems() {
        let url = isShuffled 
            ? FileManager.shuffledUpNextQueueURL 
            : FileManager.originalUpNextQueueURL

        let (data, _) = try await URLSession.shared.data(from: url)
        
        // More writing logic
    }
    
    func readItems() -> [UpNextItem] {
        let url = isShuffled 
            ? FileManager.shuffledUpNextQueueURL 
            : FileManager.originalUpNextQueueURL

        let (data, _) = try await URLSession.shared.data(from: url)
        
        // More reading logic
    }
    
    func removeItem(at index: Int) {
        let url = isShuffled 
            ? FileManager.shuffledUpNextQueueURL 
            : FileManager.originalUpNextQueueURL

        let (data, _) = try await URLSession.shared.data(from: url)
        
        // Removing item logic
    }
}

I have 2 classes: UpNextViewModel and UpNextService.

How to ensure the isShuffled property between the view model and service is in sync?

The ultimate source of truth is the service class since multiple views are watching for changes to the property.

The isShuffled property is watched among multiple views in my app and is updated through a button by multiple views as well.

struct UpNextItem {
    var id = UUID()
    var audioFileId: UUID
}

// Directly works with UpNextView when user taps on button to switch on shuffle
@Observable
class UpNextViewModel {
    var repeatStatus: RepeatStatus = .none

    var isShuffled: Bool = false // Reflects the state of the shuffle status on the view. Updates the property of the service class
    
    let upNextService: UpNextService
    
    init(upNextService: UpNextService) {
        self.upNextService = upNextService
    }
}

@Observable
class UpNextService {
    var isShuffled = false // This property should notify the respective view models when changed.
    func writeItems() {
        let url = isShuffled 
            ? FileManager.shuffledUpNextQueueURL 
            : FileManager.originalUpNextQueueURL

        let (data, _) = try await URLSession.shared.data(from: url)
        
        // More writing logic
    }
    
    func readItems() -> [UpNextItem] {
        let url = isShuffled 
            ? FileManager.shuffledUpNextQueueURL 
            : FileManager.originalUpNextQueueURL

        let (data, _) = try await URLSession.shared.data(from: url)
        
        // More reading logic
    }
    
    func removeItem(at index: Int) {
        let url = isShuffled 
            ? FileManager.shuffledUpNextQueueURL 
            : FileManager.originalUpNextQueueURL

        let (data, _) = try await URLSession.shared.data(from: url)
        
        // Removing item logic
    }
}
Share Improve this question asked Mar 17 at 13:20 User95797654974User95797654974 6744 silver badges19 bronze badges 4
  • 1 If UpNextService is the only source of truth, why does UpNextViewModel also have a isShuffled property? – Sweeper Commented Mar 17 at 13:23
  • It updates through the view model since the view model works closely with the view – User95797654974 Commented Mar 17 at 13:24
  • 3 But why do you need a view model, why not access the service directly from the view to make things less complicated? – Joakim Danielson Commented Mar 17 at 13:32
  • In SwiftUI View structs are the view models already and use @State/@Binding for the data. @Observable is for models. – malhal Commented Mar 17 at 15:47
Add a comment  | 

1 Answer 1

Reset to default 0

you should remove isShuffled from UpNextService

so you can only use one value of isShuffled (from upNextViewModel class)

then try to pass the value of isShuffled from upNextViewModel to UpNextService in each service method.

something like this:

func writeItems(isShuffled: Bool) {
    let url = isShuffled 
        ? FileManager.shuffledUpNextQueueURL 
        : FileManager.originalUpNextQueueURL

    let (data, _) = try await URLSession.shared.data(from: url)
    
    // More writing logic
}

you can also the same thing in reverse, by keeping isShuffled in service class, and pass it to view.

the main idea is to only keep one value of isShuffled, instead of defining it in each class separately.

发布评论

评论列表(0)

  1. 暂无评论