Swiftpack.co - wayfair/vsm-ios as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by wayfair.
wayfair/vsm-ios v0.3.0
An iOS framework for the VSM Architecture
⭐️ 1
🕓 4 weeks ago
iOS macOS
.package(url: "https://github.com/wayfair/vsm-ios.git", from: "v0.3.0")

Release Lint CI Contributor Covenant Maintainer

VSM for iOS

VSM is a reactive architecture that is unidirectional, highly type-safe, behavior-driven, and clean. This repository hosts an open-source swift package framework for easily building features in VSM on iOS.

Overview

VSM stands for both "View State Model" and "Viewable State Machine". The first definition describes how a feature in VSM is structured, the second definition illustrates how information flows.

VSM Architecture Diagram)

In VSM, the View renders the State. Each state may provide a Model. Each model contains the data and actions available in a given state. Each action in a model returns one or more new states. Any state changes will update the view.

Learning Resources

  • The VSM Documentation contains a complete framework reference, guides, and other learning resources
  • Open the Demo App to see many different working examples of how to build features using the VSM pattern

Code Introduction

The following are code excerpts of a feature that shows a blog entry from a data repository.

State Definition

The state is usually defined as an enum or a struct and represents the states that the view can have. It also declares the data and actions available for each model. Actions return one or more new states.

enum BlogEntryViewState {
    case initialized(loaderModel: LoaderModeling)
    case loading(errorModel: ErrorModeling?)
    case loaded(blogModel: LoadedModeling)
}

protocol LoaderModeling {
    func load() -> AnyPublisher<BlogArticleViewState, Never>
}

protocol ErrorModeling {
    var message: String { get }
    func retry() -> AnyPublisher<BlogArticleViewState, Never>
}

protocol LoadedModeling {
    var title: String { get }
    var text: String { get }
}

Model Definition

The models provide the data for a given view state and implement the business logic.

struct LoaderModel: LoaderModeling {
    func load() -> AnyPublisher<BlogArticleViewState, Never> {
        ...
    }
}

struct ErrorModel: ErrorModeling {
    var message: String
    func retry() -> AnyPublisher<BlogArticleViewState, Never> {
        ...
    }
}

struct LoadedModel: LoadedModeling {
    var title: String
    var body: String
}

View Definition

The view observes and renders the state using the StateContainer type. State changes will automatically update the view.

struct BlogEntryView: View, ViewStateRendering {
    @StateObject var container: StateContainer<BlogEntryViewState>

    init() {
        _container = .init(state: .initialized(LoaderModel()))
    }

    var body: some View {
        switch state {
        case .initialized(loaderModel: let loaderModel):            
            ...
        case .loading(errorModel: let errorModel):
            ...
        case .loaded(loadedModel: let loadedModel)
            ...
        }
    }
}

This example uses SwiftUI, but the framework is also designed to work seamlessly with UIKit.

For more detailed tutorials and documentation, visit the VSM Documentation

Project Information

Credits

VSM for iOS is owned and maintained by Wayfair.

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md.

License

VSM for iOS is released under the MIT license. See LICENSE for details.

GitHub

link
Stars: 1
Last commit: 1 minute ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Release Notes

Initial Release
7 weeks ago

Contains the minimum viable implementation of VSM for iOS:

  • Support for SwiftUI and UIKit
  • ViewStateRendering aids pattern adherence for Views
  • StateContainer for managing observation of current and future states
  • Convenient overloads that allow for flexible State/Model design and minimal boilerplate

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics