A library for managing complex workflows in Swift

Overview

SwiftCurrent

Supported Platforms Swift Package Manager Pod Version License Build Status Code Coverage

Welcome

SwiftCurrent is a library that lets you easily manage journeys through your Swift application.

It comes with built-in support for UIKit and SwiftUI app-routing. In SwiftCurrent, workflows are a sequence of operations. Those operations usually display views in an application. The workflow describes the sequence of views and manages which view should come next. Your views are responsible for performing necessary tasks before proceeding forward in the workflow, like processing user input.

Introducing.SwiftCurrent-low-quality.mp4

Why Should I Use SwiftCurrent?

Architectural patterns and libraries that attempt to create a separation between views and workflows already exist. However, SwiftCurrent is different. We took a new design approach that focuses on:

  • A Developer-Friendly API. The library was built with developers in mind. It started with a group of developers talking about the code experience they desired. Then the library team took on whatever complexities were necessary to bring them that experience.
  • Compile-Time Safety. At compile-time, we tell you everything we can so you know things will work.
  • Minimal Boilerplate. We have hidden this as much as possible. We hate it as much as you do and are constantly working on cutting the cruft.

From There, We Created a Library

This library:

  • Isolates Your Views. Design your views so that they are unaware of the view that will come next.
  • Easily Reorders Views. Changing view order is as easy as โŒ˜+โŒฅ+[ (moving the line up or down).
  • Composes Workflows Together. Create branching flows easily by joining workflows together.
  • Creates Conditional Flows. Make your flows robust and handle ever-changing designs. Need a screen to only to show up sometimes? Need a flow for person A and another for person B? We've got you covered.

Quick Start

Why show a quick start when we have an example app? Because it's so easy to get started, we can drop in two code snippets, and you're ready to go! This quick start uses Swift Package Manager and SwiftUI, but for other approaches, see our installation instructions.

.package(url: "https://github.com/wwt/SwiftCurrent.git", .upToNextMajor(from: "4.5.0")),
...
.product(name: "SwiftCurrent", package: "SwiftCurrent"),
.product(name: "SwiftCurrent_SwiftUI", package: "SwiftCurrent")

Then make your first FlowRepresentable view:

Bool { input.isEmpty } } struct ExampleView: View, PassthroughFlowRepresentable { weak var _workflowPointer: AnyFlowRepresentable? var body: some View { Text("This is ExampleView!") } } ">
import SwiftCurrent
import SwiftUI
struct OptionalView: View, FlowRepresentable {
    weak var _workflowPointer: AnyFlowRepresentable?
    let input: String
    init(with args: String) { input = args }
    var body: some View { Text("Only shows up if no input") }
    func shouldLoad() -> Bool { input.isEmpty }
}
struct ExampleView: View, PassthroughFlowRepresentable {
    weak var _workflowPointer: AnyFlowRepresentable?
    var body: some View { Text("This is ExampleView!") }
}

Then from your ContentView or whatever view (or app) you'd like to contain the workflow, add the following view to the body:

import SwiftCurrent_SwiftUI
// ...
var body: some View { 
    // ... other view code (if any)
    WorkflowLauncher(isLaunched: .constant(true), startingArgs: "Skip optional screen") {
        thenProceed(with: OptionalView.self) {
            thenProceed(with: ExampleView.self)
        }
    }
}

And just like that, you've got a workflow! You can now add more items to it or reorder the items that are there. To understand more of how this works, check out our developer docs.

Look at Our Example Apps

We have example apps for both SwiftUI and UIKit that show SwiftCurrent in action. They've already been tested, so you can see what it's like to test SwiftCurrent code. To run it locally, start by cloning the repo, open SwiftCurrent.xcworkspace and then run the SwiftUIExample scheme or the UIKitExample scheme.

Click Here to Learn More

For specific documentation check out:

Feedback

If you like what you've seen, consider giving us a star! If you don't, let us know how we can improve.

Stars Twitter

Special Thanks

SwiftCurrent would not be nearly as amazing without all of the great work done by the authors of our test dependencies:

Comments
  • Data Driven Workflows

    Data Driven Workflows

    This issue is here to help track some ideas and things related to the milestone. It's also here so the Milestone will stop bouncing between not-complete and complete.

    So far we have spike branches: data-spike1 through data-spike3 so far.

    The main PR that will bring in Data-Driven Workflows will be the branch data-driven

    enhancement 
    opened by Richard-Gist 23
  • SwiftUI NavigationLink

    SwiftUI NavigationLink

    • add support for NavLinks as launchStyle on WorkflowView and WorkflowItem

    • Add 10 screen test, beginning to end and back. don't forget to test wiggle/oscillation between 2 screens in the navigation view. what happens if someone hits back on nav view?

    • test abandoning

    enhancement 
    opened by brianlombardo 19
  • AnyView implementation for SwiftUI Presenter

    AnyView implementation for SwiftUI Presenter

    [x] Testing [x] Implementation [x] Docs [x] Example app

    LIMIT: We do not need Modals or Navigation. Just view swapping.

    This card is not getting merged into trunk until we have completed our investigation into NOT using AnyView (the card: Don't use AnyView for SwiftUI Presenter).

    documentation enhancement 
    opened by Richard-Gist 14
  • Adds Passthrough representable

    Adds Passthrough representable

    Linked Issue: Closes #21

    Checklist:


    If Public API Has Changed:

    • [x] Did you deprecate (rather than remove) any old methods/variables/etc? Our philosophy for deprecation.
    • [x] Have you done the best that you can to make sure that the compiler guides people to changing to the new API? (Example: the renamed attribute)
    • [x] If necessary, have you tested the upgrade path for at least N-1 versions? For example, if data persists between v1 and v2 then that upgrade should be tested and as easy as we can make it.
    documentation enhancement 
    opened by Tyler-Keith-Thompson 12
  • removedAfterProceeding on last item in Workflow

    removedAfterProceeding on last item in Workflow

    Describe the bug

    If you have .removedAfterProceeding as the FlowPersistence on an item in a workflow it does not properly remove that item (UIKit)

    To Reproduce

    Steps to reproduce the behavior: Create 3 FlowRepresentables the last of which has a flowPersistence of .removedAfterProceeding Call proceedInWorkflow() on all items in that flow Observe after OnFinish is called the final UIViewController is still displayed

    Expected behavior

    The UIViewController should not be displayed after the onFinish block has executed

    Screenshots

    NO

    bug 
    opened by Tyler-Keith-Thompson 12
  • Allow `thenProceed` in preview providers

    Allow `thenProceed` in preview providers

    Is your feature request related to a problem? Please describe.

    I want to use previews to view my FlowRepresentable as it'll appear in a workflow, even if that's just a single item workflow. However, right now thenProceed is not available.

    Describe the solution you'd like

    Either make thenProceed globally available so we quit having one-off "I need it added" or add it to PreviewProvider.

    Describe alternatives you've considered

    I could write my own extension for this, but it should just work out of the box. Additionally, I suppose we could wrap thenProceed in some new protocol? However, I don't like the idea that I have to conform to a protocol just to define a workflow. There may be something to investigating resultBuilders in a future version of Swift where they allow those scoped functions. I've seen proposals about it, but for now I don't think we should go that route.

    invalid 
    opened by Tyler-Keith-Thompson 9
  • Updating trunk.yml for Testing framework

    Updating trunk.yml for Testing framework

    Linked Issue: Closes #110

    Checklist:

    enhancement 
    opened by morganzellers 8
  • [Beta] Removes usage of AnyView

    [Beta] Removes usage of AnyView

    Linked Issue: #76

    Checklist:


    If Applicable:

    • [x] Did you test when the first item is skipped?
    • [x] Did you test when the last item is skipped?
    • [x] Did you test when middle items are skipped?
    • [x] Did you test when incorrect data is passed forward?
    • [x] Did you test proceeding backwards?

    If Public API Has Changed:

    • [ ] Did you deprecate (rather than remove) any old methods/variables/etc? Our philosophy for deprecation.
    • [ ] Have you done the best that you can to make sure that the compiler guides people to changing to the new API? (Example: the renamed attribute)
    • [ ] If necessary, have you tested the upgrade path for at least N-1 versions? For example, if data persists between v1 and v2 then that upgrade should be tested and as easy as we can make it.
    enhancement 
    opened by Tyler-Keith-Thompson 8
  • Updates README.md to be more compelling

    Updates README.md to be more compelling

    Linked Issue:

    Checklist:


    If Applicable:

    • [ ] Did you test when the first item is skipped?
    • [ ] Did you test when the last item is skipped?
    • [ ] Did you test when middle items are skipped?
    • [ ] Did you test when incorrect data is passed forward?
    • [ ] Did you test proceeding backwards?

    If Public API Has Changed:

    • [ ] Did you deprecate (rather than remove) any old methods/variables/etc? Our philosophy for deprecation.
    • [ ] Have you done the best that you can to make sure that the compiler guides people to changing to the new API? (Example: the renamed attribute)
    • [ ] If necessary, have you tested the upgrade path for at least N-1 versions? For example, if data persists between v1 and v2 then that upgrade should be tested and as easy as we can make it.
    documentation cla-signed 
    opened by Richard-Gist 8
  • Expands platform support to include macOS, watchOS, and tvOS.

    Expands platform support to include macOS, watchOS, and tvOS.

    opened by Richard-Gist 7
  • Create github pages for current library name to host Developer docs and wiki.

    Create github pages for current library name to host Developer docs and wiki.

    Splitable: Add to the pipeline pushing to that repo.

    Milestone: Great Onboarding Experience

    https://github.com/marketplace/actions/deploy-to-github-pages

    documentation 
    opened by Richard-Gist 7
  • [fix-nav-links] - Use new navigation destination API with iOS 16+ - TT

    [fix-nav-links] - Use new navigation destination API with iOS 16+ - TT

    opened by Tyler-Keith-Thompson 1
  • [Bug]: Navigation seems to only work once

    [Bug]: Navigation seems to only work once

    What happened?

    I think this is entirely related to a known SwiftUI bug and the deprecation of NavLinks with isActive bindings. Effectively, isActive never gets set to false. You can confirm this by adding an onChange modifier and pressing the built in "back" button. Because it never gets set to false, setting it to true triggers no changes.

    Version

    iOS 16

    Relevant code sample

    // Here's a reproducible example:
    
    import SwiftUI
    import Combine
    
    struct ContentView: View {
        var body: some View {
            NavigationStack {
                VStack {
                    Combiner(current: Screen1(), next: Combiner(current: Screen2(), next: Combiner(current: Screen3())))
                }
            }
            .padding()
        }
    }
    
    protocol FlowRepresentableView: View { }
    
    extension Never: FlowRepresentableView { }
    
    class Workflow: ObservableObject {
        let proceedPublisher = PassthroughSubject<Void, Never>()
    }
    
    struct Combiner<Current: FlowRepresentableView, Next: FlowRepresentableView>: FlowRepresentableView {
        @State var current: Current
        @State var next: Next?
        @State var isActive: Bool = false
        @StateObject var workflow = Workflow()
    
        init(current: Current, next: Next) {
            _current = State(wrappedValue: current)
            _next = State(wrappedValue: next)
        }
    
        init(current: Current) where Next == Never {
            _current = State(wrappedValue: current)
            _next = State(wrappedValue: nil)
        }
    
        var body: some View {
            Group {
                if let next {
                    NavigationLink(destination: next, isActive: $isActive) { }
                        .isDetailLink(false)
                }
                current
            }
            .onReceive(workflow.proceedPublisher) {
                isActive = true
            }
            .environmentObject(workflow)
        }
    }
    
    struct Screen1: FlowRepresentableView {
        @EnvironmentObject var workflow: Workflow
        var body: some View {
            Text("\(String(describing: Self.self))")
                .onTapGesture {
                    workflow.proceedPublisher.send()
                }
        }
    }
    
    struct Screen2: FlowRepresentableView {
        @EnvironmentObject var workflow: Workflow
        var body: some View {
            Text("\(String(describing: Self.self))")
                .onTapGesture {
                    workflow.proceedPublisher.send()
                }
        }
    }
    
    struct Screen3: FlowRepresentableView {
        @EnvironmentObject var workflow: Workflow
        var body: some View {
            Text("\(String(describing: Self.self))")
                .onTapGesture {
                    workflow.proceedPublisher.send()
                }
        }
    }
    
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    

    Relevant log output

    No response

    Code of Conduct

    • [X] I agree to follow this project's Code of Conduct
    bug 
    opened by Tyler-Keith-Thompson 1
  • [Feature]: Use Swift Package Plugins for codegen (server driven workflows)

    [Feature]: Use Swift Package Plugins for codegen (server driven workflows)

    What prompted this feature request?

    Our current approach to create an aggregator for WorkflowDecodable is a little cumbersome. It involves running a standalone CLI utility.

    Describe the solution you'd like

    If we used swift package plugins we could integrate into the build system better, meaning people can set it and forget it.

    Describe alternatives you've considered

    Keep doing it the way we are?

    Code of Conduct

    • [X] I agree to follow this project's Code of Conduct
    enhancement 
    opened by Tyler-Keith-Thompson 0
  • Codecov report on README is lying

    Codecov report on README is lying

    What happened?

    Our codecov badge says 0% coverage but we have something like 90% coverage

    Version

    5.1.4 and 5.1.5

    Relevant code sample

    None
    

    Relevant log output

    None
    

    Code of Conduct

    • [X] I agree to follow this project's Code of Conduct
    good first issue 
    opened by Tyler-Keith-Thompson 3
  • [Bug] [Triaged]: SwiftCurrent_CLI not building successfully in consuming iOS application

    [Bug] [Triaged]: SwiftCurrent_CLI not building successfully in consuming iOS application

    What happened?

    While testing aspects of the new data-driven workflow feature, I created a brand new SwiftUI Project and added the SwiftCurrent, SwiftCurrent_SwiftUI, and SwiftCurrent_CLI dependencies via SPM.

    Building after doing this resulted in 15 build errors in the SwiftCurrent_CLI target stemming from a library called "_InternalSwiftSyntaxParser". Likely due to this bit from the SwiftSyntax README:

    Embedding SwiftSyntax in an Application

    SwiftSyntax depends on the lib_InternalSwiftSyntaxParser.dylib/.so library which provides a C interface to the underlying Swift C++ parser. When you do swift build SwiftSyntax links and uses the library included in the Swift toolchain. If you are building an application make sure to embed _InternalSwiftSyntaxParser as part of your application's libraries.

    You can either copy lib_InternalSwiftSyntaxParser.dylib/.so directly from the toolchain or even build it yourself from the Swift repository, as long as you are matching the same tags or branches in both the SwiftSyntax and Swift repositories. To build it for the host os (macOS/linux) use the following steps:

    git clone https://github.com/apple/swift.git
    ./swift/utils/update-checkout --clone
    ./swift/utils/build-parser-lib --release --no-assertions --build-dir /tmp/parser-lib-build
    

    Embedding in an iOS Application

    You need to build lib_InternalSwiftSyntaxParser.dylib yourself, you cannot copy it from the toolchain. Follow the instructions above and change the invocation of build-parser-lib accordingly:

    ./swift/utils/build-parser-lib --release --no-assertions --build-dir /tmp/parser-lib-build-iossim --host iphonesimulator --architectures x86_64
    ./swift/utils/build-parser-lib --release --no-assertions --build-dir /tmp/parser-lib-build-ios --host iphoneos --architectures arm64
    

    Version

    SwiftCurrent Version 5.1.3 Xcode Version 13.3 macOS version 12.3

    Relevant code sample

    No response

    Relevant log output

    ld: warning: Could not find or use auto-linked library '_InternalSwiftSyntaxParser'
    Undefined symbols for architecture x86_64:
      "_swiftparse_syntax_structure_versioning_identifier", referenced from:
          static SwiftSyntax.SyntaxParser.verifyNodeDeclarationHash() -> Swift.Bool in SwiftSyntax.o
      "_swiftparse_diagnostic_get_fixit", referenced from:
          closure #2 (Swift.UInt32) -> SwiftSyntax.FixIt in SwiftSyntax.Diagnostic.init(diag: Swift.UnsafeRawPointer, using: SwiftSyntax.SourceLocationConverter?) -> SwiftSyntax.Diagnostic in SwiftSyntax.o
      "_swiftparse_diagnostic_get_range", referenced from:
          closure #1 (Swift.UInt32) -> SwiftSyntax.SourceRange in SwiftSyntax.Diagnostic.init(diag: Swift.UnsafeRawPointer, using: SwiftSyntax.SourceLocationConverter?) -> SwiftSyntax.Diagnostic in SwiftSyntax.o
      "_swiftparse_diagnostic_get_message", referenced from:
          SwiftSyntax.Diagnostic.Message.init(Swift.UnsafeRawPointer) -> SwiftSyntax.Diagnostic.Message in SwiftSyntax.o
      "_swiftparse_diagnostic_get_range_count", referenced from:
          SwiftSyntax.Diagnostic.init(diag: Swift.UnsafeRawPointer, using: SwiftSyntax.SourceLocationConverter?) -> SwiftSyntax.Diagnostic in SwiftSyntax.o
      "_swiftparse_diagnostic_get_fixit_count", referenced from:
          SwiftSyntax.Diagnostic.init(diag: Swift.UnsafeRawPointer, using: SwiftSyntax.SourceLocationConverter?) -> SwiftSyntax.Diagnostic in SwiftSyntax.o
      "_swiftparse_parse_string", referenced from:
          closure #4 (Swift.UnsafePointer<Swift.Int8>) -> Swift.UnsafeMutableRawPointer? in static SwiftSyntax.SyntaxParser.(parseRaw in _FF480AC1827F0899EF1492D28392D5EA)(Swift.String, SwiftSyntax.IncrementalParseTransition?, Swift.String, SwiftSyntax.DiagnosticEngine?) -> SwiftSyntax.RawSyntax in SwiftSyntax.o
      "_swiftparse_diagnostic_get_source_loc", referenced from:
          SwiftSyntax.Diagnostic.init(diag: Swift.UnsafeRawPointer, using: SwiftSyntax.SourceLocationConverter?) -> SwiftSyntax.Diagnostic in SwiftSyntax.o
      "_swiftparse_diagnostic_get_severity", referenced from:
          closure #3 (Swift.UnsafeRawPointer?) -> () in static SwiftSyntax.SyntaxParser.(parseRaw in _FF480AC1827F0899EF1492D28392D5EA)(Swift.String, SwiftSyntax.IncrementalParseTransition?, Swift.String, SwiftSyntax.DiagnosticEngine?) -> SwiftSyntax.RawSyntax in SwiftSyntax.o
          SwiftSyntax.Diagnostic.Message.init(Swift.UnsafeRawPointer) -> SwiftSyntax.Diagnostic.Message in SwiftSyntax.o
      "_swiftparse_parser_create", referenced from:
          static SwiftSyntax.SyntaxParser.(parseRaw in _FF480AC1827F0899EF1492D28392D5EA)(Swift.String, SwiftSyntax.IncrementalParseTransition?, Swift.String, SwiftSyntax.DiagnosticEngine?) -> SwiftSyntax.RawSyntax in SwiftSyntax.o
      "_swiftparse_parser_set_node_handler", referenced from:
          static SwiftSyntax.SyntaxParser.(parseRaw in _FF480AC1827F0899EF1492D28392D5EA)(Swift.String, SwiftSyntax.IncrementalParseTransition?, Swift.String, SwiftSyntax.DiagnosticEngine?) -> SwiftSyntax.RawSyntax in SwiftSyntax.o
      "_swiftparse_parser_set_node_lookup", referenced from:
          static SwiftSyntax.SyntaxParser.(parseRaw in _FF480AC1827F0899EF1492D28392D5EA)(Swift.String, SwiftSyntax.IncrementalParseTransition?, Swift.String, SwiftSyntax.DiagnosticEngine?) -> SwiftSyntax.RawSyntax in SwiftSyntax.o
      "_swiftparse_parser_dispose", referenced from:
          $defer #1 () -> () in static SwiftSyntax.SyntaxParser.(parseRaw in _FF480AC1827F0899EF1492D28392D5EA)(Swift.String, SwiftSyntax.IncrementalParseTransition?, Swift.String, SwiftSyntax.DiagnosticEngine?) -> SwiftSyntax.RawSyntax in SwiftSyntax.o
      "_swiftparse_parser_set_diagnostic_handler", referenced from:
          static SwiftSyntax.SyntaxParser.(parseRaw in _FF480AC1827F0899EF1492D28392D5EA)(Swift.String, SwiftSyntax.IncrementalParseTransition?, Swift.String, SwiftSyntax.DiagnosticEngine?) -> SwiftSyntax.RawSyntax in SwiftSyntax.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    Code of Conduct

    • [X] I agree to follow this project's Code of Conduct
    bug 
    opened by morganzellers 2
  • [Feature]: Server Driven Workflows in UIKit

    [Feature]: Server Driven Workflows in UIKit

    What prompted this feature request?

    I love SwiftUI but sometimes have to use UIKit and would love to use server driven workflows there too.

    Describe the solution you'd like

    I want to be able to use server driven payloads to create my Workflows

    Describe alternatives you've considered

    No response

    Code of Conduct

    • [X] I agree to follow this project's Code of Conduct
    enhancement 
    opened by morganzellers 0
Releases(5.1.12)
Owner
WWT
World Wide Technology, Inc.
WWT
URL routing library for iOS with a simple block-based API

JLRoutes What is it? JLRoutes is a URL routing library with a simple block-based API. It is designed to make it very easy to handle complex URL scheme

Joel Levin 5.6k Jan 6, 2023
Marshroute is an iOS Library for making your Routers simple but extremely powerful

Marshroute Contents Overview Detailes Tuning the transition animation 3d touch support PeekAndPopUtility Peek and pop state observing Demo Requirement

avito.tech 215 Jan 4, 2023
Eugene Kazaev 713 Dec 25, 2022
An open source library for building deep-linkable SwiftUI applications with composition, testing and ergonomics in mind

Composable Navigator An open source library for building deep-linkable SwiftUI applications with composition, testing and ergonomics in mind Vanilla S

Bahn-X 538 Dec 8, 2022
An App-specific Simple Routing Library

TrieRouter An App-specific Simple Routing Library Usage let r = Router() r.addRoute("tbx://index") { _ in print("root") } r.addRoute("tbx://intTes

TBXark 2 Mar 3, 2022
Appz ๐Ÿ“ฑ Launch external apps, and deeplink, with ease using Swift!

Appz ?? Deeplinking to external applications made easy Highlights Web Fallback Support: In case the app can't open the external application, it will f

Kitz 1.1k May 5, 2021
LiteRoute is easy transition for your app. Written on Swift 4

LiteRoute Description LiteRoute is easy transition between VIPER modules, who implemented on pure Swift. We can transition between your modules very e

Vladislav Prusakov 90 Mar 12, 2021
๐ŸŽฏLinker Lightweight way to handle internal and external deeplinks in Swift for iOS

Linker Lightweight way to handle internal and external deeplinks in Swift for iOS. Installation Dependency Managers CocoaPods CocoaPods is a dependenc

Maksim Kurpa 128 May 20, 2021
Monarch Router is a Declarative URL- and state-based router written in Swift.

Monarch Router is a declarative routing handler that is capable of managing complex View Controllers hierarchy transitions automatically, decoupling View Controllers from each other via Coordinator and Presenters. It fits right in with Redux style state flow and reactive frameworks.

Eliah Snakin 31 May 19, 2021
SwiftRouter - A URL Router for iOS, written in Swift

SwiftRouter A URL Router for iOS, written in Swift, inspired by HHRouter and JLRoutes. Installation SwiftRouter Version Swift Version Note Before 1.0.

Chester Liu 259 Apr 16, 2021
๐Ÿ“ฑ๐Ÿ“ฒ Navigate between view controllers with ease. ๐Ÿ’ซ ๐Ÿ”œ More stable version (written in Swift 5) coming soon.

CoreNavigation ?? ?? Navigate between view controllers with ease. ?? ?? More stable version (written in Swift 5) coming soon. Getting Started API Refe

Aron Balog 69 Sep 21, 2022
Interface-oriented router for discovering modules, and injecting dependencies with protocol in Objective-C and Swift.

ZIKRouter An interface-oriented router for managing modules and injecting dependencies with protocol. The view router can perform all navigation types

Zuik 631 Dec 26, 2022
ZPPRouter ็ป„ไปถๅŒ–่ทฏ็”ฑ swift

ZPPRouter ้ขๅ‘็ป„ไปถๅ่ฎฎ ็ป„ไปถ่Žทๅ–ๅฎžไพ‹ไธบๅ่ฎฎ็ฑปๅž‹ ๆณจ๏ผš SPM ๆฏไธ€ไธช็ป„ไปถๆœ€็ปˆ็”Ÿๆˆ็š„้ƒฝๆ˜ฏ framworkๅบ“ ๆ„ๅ‘ณ็€็ป„ไปถๅญ˜ๅœจๅ‘ฝๅ็ฉบ้—ด๏ผˆไผ˜็‚น๏ผ‰ Example To run the example project, clone the repo, and run pod install fro

Zpp 5 Jun 6, 2022
A deep copy of Pinterest in Swift

Demo YouTube: Demo (2 minutes) ไผ˜้…ท๏ผšhttp://v.youku.com/v_show/id_XMzE3OTc5NDY2MA==.html?spm=a2h3j.8428770.3416059.1 The app is actually smoother than sh

Andy Tong 73 Sep 14, 2022
A simple, powerful and elegant implementation of the coordinator template in Swift for UIKit

A simple, powerful and elegant implementation of the coordinator template in Swift for UIKit Installation Swift Package Manager https://github.com/bar

Aleksei Artemev 22 Oct 16, 2022
Build complex, conducted animations declaratively without manually managing state.

Maestro Build complex, conducted animations declaratively without manually managing state. Code struct AnimatedPieChart: View { private enum Trim

Ryan Wachowski 5 Nov 20, 2022
A powerful SwiftUI Architecture that merges Redux to the functional world of Swift. While bringing powerful workflows to streamline CoreML/Metal/IPFS usage in the Apple ecosystem.

GraniteUI - v0.0 - WIP A powerful SwiftUI Architecture that merges Redux event handling and state management with functional programming. While bringi

Kala 2 Dec 22, 2022
Compose is a library that helps you compose complex and dynamic views.

Compose is a data driven library that will help compose your complex and dynamic Views. It helps you create complex and dynamic Views using easy and s

OLX Brasil 123 Jun 9, 2021
SmartString - A powerful and small library that will allow the creation of complex String Styles

SmartString A powerful and small library that will allow the creation of complex

Valerio 7 Oct 26, 2022
ShogibanKit is a framework (not yet) for implementing complex Japanese Chess (Shogii) in Swift. No UI, nor AI.

ShogibanKit Framework Shogi, or Japanese Chess, is based on very complex rules, and it is hard to implement all basic rules. This ShogibanKit aims to

Kaz Yoshikawa 62 Jul 16, 2022