Skip to content

Commit

Permalink
Add AsyncPreview package
Browse files Browse the repository at this point in the history
  • Loading branch information
TaimurAyaz committed Mar 14, 2024
1 parent efcd60e commit 5854aec
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 1 deletion.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
24 changes: 24 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "AsyncPreview",
platforms: [
.macOS(.v14), .iOS(.v13), .tvOS(.v13), .visionOS(.v1)
],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
name: "AsyncPreview",
targets: ["AsyncPreview"]),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "AsyncPreview",
exclude: ["README.md", "LICENSE"]),
]
)
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
# AsyncPreview
Preview asynchronous views on Xcode canvas.

Preview views with asynchronous dependencies, on Xcode canvas.

## Usage

```
#Preview {
AsyncModel { model in
SomeView().environment(model)
} model: {
try await SomeAsynchronousModel()
}
}
```
44 changes: 44 additions & 0 deletions Sources/AsyncPreview/AsyncPreview.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// AsyncPreview.swift
// Circuit
//
// Created by Alt on 2024-03-09.
//

import Foundation
import SwiftUI

struct AsyncPreview<V: View, M>: View {

var view: (M) -> V
var model: () async throws -> M?

@State internal var internalModel: M?
@State internal var error: Error?

var body: some View {
internalBody
.task {
do {
self.internalModel = try await model()
} catch {
self.error = error
print(error)
}
}
}

@ViewBuilder
internal var internalBody: some View {
if let internalModel {
view(internalModel)
}
else if let error {
Label(error.localizedDescription, systemImage: "exclamationmark.triangle.fill")
}
else {
// Note: We need an actual view to trigger the `task` in `body`
ProgressView().progressViewStyle(.circular)
}
}
}

0 comments on commit 5854aec

Please sign in to comment.