[Lofi Time Radio App] Station Presentation — (Part 6)
Hi, I want to show you the Presentation layer to continue this series. If you are the first time read my blog, please read the introduction post. In MVP Architecture, the Presentation layer is the gear of the architecture to connect the Model and View. The Presentation will let the View know which part needs to show on the screen.
I. LoadingView and LoadingViewModel:
LoadingView
describes the loading state of the view.
public protocol LoadingView {
func display(_ viewModel: LoadingViewModel)
}
LoadingViewModel
describes the state of loading.
public struct LoadingViewModel {
public let isLoading: Bool
public init(isLoading: Bool) {
self.isLoading = isLoading
}
}
II. SongView and SongViewModel:
SongView
describes the playing song to the view.
public protocol SongView {
func display(_ viewModel: SongViewModel)
}
SongViewModel
describes the information of the playing song such as name, artist, and image URL.
public struct SongViewModel {
public let imageURL: URL
public let name: String
public let artist: String
public init(imageURL: URL, name: String, artist: String) {
self.imageURL = imageURL
self.name = name
self.artist = artist
}
}
III. AudienceView and AudienceViewModel:
AudienceView
describes the audience listening to the playing song.
public protocol AudienceView {
func display(_ viewModel: AudienceViewModel)
}
AudienceViewModel
describes the number of audiences listening to the playing song.
public struct AudienceViewModel {
public var total: Int
public init(total: Int) {
self.total = total
}
}
IV. RuntimeView and RuntimeViewModel:
RuntimeView
describes the run time of the playing song.
public protocol RuntimeView {
func display(_ viewModel: RunTimeViewModel)
}
RuntimeViewModel
describes the information of the playing song run time such as duration, elapsed, remaining, elapsedSeconds, requestNextSong.
public struct RunTimeViewModel {
public let elapsed: String // 00:30
public let remaining: String // 01:00
public let duration: Int // 180
public let elapsedSeconds: Int // 30
public let requestNextSong: Bool // inform view request next song infor
public init(elapsed: String,
remaining: String,
duration: Int,
elapsedSeconds: Int,
requestNextSong: Bool) {
self.elapsed = elapsed
self.remaining = remaining
self.duration = duration
self.elapsedSeconds = elapsedSeconds
self.requestNextSong = requestNextSong
}
}
V. ControlView and ControlViewModel:
ControlView
describes the state of the play/pause button in the view.
public protocol ControlView {
func display(_ viewModel: ControlViewModel)
}
ControlViewModel
describes the audio state information, ex: resumed, paused…
public enum AudioState: Hashable {
case resumed
case paused
}
public struct ControlViewModel {
public let state: AudioState
public init(state: AudioState) {
self.state = state
}
public static var resumed: ControlViewModel {
return ControlViewModel(state: .resumed)
}
public static var paused: ControlViewModel {
return ControlViewModel(state: .paused)
}
}
VI. ErrorView and ErrorViewModel:
ErrorView
describes the error state of the view.
public protocol ErrorView {
func display(_ viewModel: ErrorViewModel)
}
ErrorViewModel
describes the error message when something wrong happens.
public struct ErrorViewModel: Equatable {
public let message: String?
public static var noError: ErrorViewModel {
return ErrorViewModel(message: nil)
}
public static func error(message: String) -> ErrorViewModel {
return ErrorViewModel(message: message)
}
}
That’s all for this post. In the next post, I will show you how I apply TDD to create the RadioPresenter
for using all View Protocol
s mentioned above.
Thank you for reading! See ya!