Skip to content

Releases: 0xOpenBytes/DataDrivenUI

0.2.0

23 Nov 03:16
Compare
Choose a tag to compare
0.2.0 Pre-release
Pre-release

What Changed?

  • ComposedView protocol changed to ComposableView
  • ViewProducing's RootView changed to ComposedView
  • ViewProducing's rootView changed to view
  • Added counter test

Counter Test Example

struct CounterView: ComposableView {
    struct Content {
        let count: String
    }

    struct Capabilities {
        let increment: () -> Void
        let decrement: () -> Void
    }

    let content: Content
    let capabilities: Capabilities

    var body: some View {
        VStack {
            Text(content.count)
            HStack {
                Button(action: capabilities.decrement, label: { Text("-") })
                Button(action: capabilities.increment, label: { Text("+") })
            }
        }
        .padding()
    }
}

class CounterViewModel: ViewProducing {
    typealias ComposedView = CounterView

    @Published private var count: Int = 0

    var content: Content {
        Content(
            count: "\(count)"
        )
    }

    var capabilities: Capabilities {
        Capabilities(
            increment: increment,
            decrement: decrement
        )
    }

    private func increment() {
        count += 1
    }

    private func decrement() {
        count -= 1
    }
}

let counterViewModel = CounterViewModel()

XCTAssertEqual(counterViewModel.content.count, "0")

counterViewModel.capabilities.increment()

XCTAssertEqual(counterViewModel.content.count, "1")

counterViewModel.capabilities.decrement()
counterViewModel.capabilities.decrement()

XCTAssertEqual(counterViewModel.content.count, "-1")

Full Changelog: 0.1.0...0.2.0

0.1.0

23 Nov 01:16
89f7a33
Compare
Choose a tag to compare
0.1.0 Pre-release
Pre-release

DataDrivenUI

Producing Views from data since 2022

What is DataDrivenUI?

When did putting Classes in Structs become normal? Well, when did SwiftUI get released?

DataDrivenUI takes a data first approach, by focusing on how data is passed around. To be specific, DataDrivenUI reverses the idea of the ViewModel and View. Normally the View will own the ViewModel, a Struct owning a Class. DataDrivenUI creates a contract between the View and the object producing said View. The View determines what Content and Capabilities it needs to function. Then you can create objects that can create the needed Content and Capabilities the View needs. Doing this the View doesn't know what object produced it, but does have the needed Content and Capabilities it needs to work.

Example Usage

struct ExampleComposedView: ComposedView {
    struct Content {
        let name: String
    }

    struct Capabilities {
        let updateName: (String) -> Void
    }

    var content: Content
    var capabilities: Capabilities

    var body: some View {
        Text("Hello, \(content.name)!")
            .onAppear {
                capabilities.updateName("\(Date().timeIntervalSince1970)")
            }
    }
}

class ExampleViewProducer: ViewProducing {
    typealias RootView = ExampleComposedView

    @Published private var name: String = "Tests"

    var content: Content {
        Content(name: name)
    }

    var capabilities: Capabilities {
        Capabilities(
            updateName: update(name:)
        )
    }

    private func update(name: String) {
        self.name = name
    }
}

let viewProducer = ExampleViewProducer()

XCTAssertEqual(viewProducer.content.name, "Tests")

viewProducer.capabilities.updateName("World")

XCTAssertEqual(viewProducer.content.name, "World")