Clean Actor Model Architecture

Related tags

Patterns cama
Overview

CAMA

Eonil, 2021.

CAMA is short for "Clean Actor Model Architecture". As like it says, its CA(Clean Architecture) + AM(Actor model). AM here means AM introduced in Swift 5.5 that comes with async/await support.

Core idea of CA is "isolation via minimally abstracted interface surface". Core idea of AM is "message passing between isolated & concurrently working actors".

Both focuses on "isolation", because this is one of the important thing to build programs at arbitrary complexity.

There are also differences. CA focuses more on "abstraction", and AM focuses more on "concurrency". Good news is, we can take both of two greatness.

By combining two, we get very simple, extensive and recursive way to organize human-facing interactive applications at arbitrary complexity in manageable way.

Getting Started

Let's start with our first CAMA-based app, "ToDo". It starts with Root which is the top-most unique owner of the application. And the Root is an actor.

actor Root {
}

An app is divided into two parts; (1) Core and (2) Shell. Core is "business logic" in CA terms, and Shell is UI.

Why do we divide it into two parts? By diviging them into two parts, we can test them individually. Also we are going to show how to "divide" an app into smaller parts in same way here.

actor Core {
}
actor Shell {
}

Those two components (Core and Shell) need to communicate. In CAMA, everything communicates only with "messages". Therefore, we need to define messages to exchange.

enum Action {
    case addNewItemAtLast(String)
    case removeAll
}

enum Rendition {
    case snapshot(State)
}

And connect them so they can exchange messages.

actor Root {
    init() {
        /// Make up components.
        let core = Core()
        let shell = Shell()
        /// Prepare message receiving channels.
        let actions = Chan<Action>()
        let renditions = Chan<Rendition>()
        
        /// Spawn coroutines for each component.
        /// Wait for incoming messages.
        /// Process the incoming messages by sending to each other.
        Task {
            for await x in await core.run(actions) {
                await renditions <- x
            }
        }
        Task {
            await renditions <- .snapshot(State())
            for await x in shell.run(renditions) {
                await actions <- x
            }
        }
    }
}

actor Core {
    func run(_:Chan<Action>) -> Chan<Rendition> {
        /// ...
    }
}

actor Shell {
    func run(_:Chan<Rendition>) -> Chan<Action> {
        /// ...
    }
}

Implement message processors.

And convert some actors into MainActor as they require to run in main thread to work properly.

@MainActor
public final class Root {
    public init() {
        /// Make up components.
        let core = Core()
        let shell = Shell()
        /// Prepare message receiving channels.
        let actions = Chan<Action>()
        let renditions = Chan<Rendition>()
        
        /// Spawn coroutines for each component.
        /// Wait for incoming messages.
        /// Process the incoming messages by sending to each other.
        Task {
            for await x in await core.run(actions) {
                await renditions <- x
            }
        }
        Task {
            await renditions <- .snapshot(State())
            for await x in shell.run(renditions) {
                await actions <- x
            }
        }
    }
}

actor Core {
    private var state = State()
    func run(_ recv:Chan<Action>) -> Chan<Rendition> {
        let send = Chan<Rendition>()
        Task {
            for await x in recv {
                dump(x)
            }
        }
        return send
    }
}

/// App's abstracted state.
struct State {
    var items = [String]()
}

@MainActor
final class Shell {
    func run(_ recv:Chan<Rendition>) -> Chan<Action> {
        let send = Chan<Action>()
        Task {
            /// Prints computation output.
            for await x in recv {
                dump(x)
            }
        }
        return send
    }
}

enum Action {
    case addNewItemAtLast(String)
    case removeAll
}

enum Rendition {
    case snapshot(State)
}

Now you get an idea how this works.

Next Steps

  • Check ToDo example source code for full implementations.
  • Check another example source code "CoinBook".

License

Use of this content is licensed under "CC-BY-4.0 License". You can do whatever you want. Just please don't forget to linking this repo so people can find out the original text.

Copyright(C) Eonil, Hoon H., 2021. All rights reserved.

You might also like...
An actor model library for swift.

Aojet Aojet is an actor model implemetion for swift. Features Asynchronous, non-blocking and highly performant message-driven programming model Safe a

A fast, convenient and nonintrusive conversion framework between JSON and model. Your model class doesn't need to extend any base class. You don't need to modify any model file.

MJExtension A fast, convenient and nonintrusive conversion framework between JSON and model. 转换速度快、使用简单方便的字典转模型框架 📜 ✍🏻Release Notes: more details Co

RippleQueries is an iOS application built as assessment task at Ripple Egypt. Built Using MVVM (Model-View-ViewModel) and Clean Architecture concepts
RippleQueries is an iOS application built as assessment task at Ripple Egypt. Built Using MVVM (Model-View-ViewModel) and Clean Architecture concepts

RippleRepositories RippleRepositories is an iOS application built as an assessment task at Ripple Egypt. Built Using RxSwift & MVVM (Model-View-ViewMo

🎭 Swift async/await & Actor-powered effectful state-management framework.
🎭 Swift async/await & Actor-powered effectful state-management framework.

🎭 Actomaton 🧑‍🎤 Actor + 🤖 Automaton = 🎭 Actomaton Actomaton is Swift async/await & Actor-powered effectful state-management framework inspired by

Prototype actor and async/await toolkit for Swift 5.5+

Prototype actor and async/await toolkit for Swift 5.5+

**`withCheckedContinuation`'s body will run on background thread in case of starting from main-actor.**
**`withCheckedContinuation`'s body will run on background thread in case of starting from main-actor.**

ConcurrencyContinuationReproduce Differences of Concurrency behaviors between Xcode 14.0 and 14.1 Xcode 14.0 iOS 13+: Runs on main (inherited same con

CoreMLSample - CoreML Example for in app model and download model

CoreMLSample Sample for CoreML This project is CoreML Example for in app model a

Example of Clean Architecture of iOS app using RxSwift
Example of Clean Architecture of iOS app using RxSwift

Clean architecture with RxSwift Contributions are welcome and highly appreciated!! You can do this by: opening an issue to discuss the current solutio

SwiftUI sample app using Clean Architecture. Examples of working with CoreData persistence, networking, dependency injection, unit testing, and more.
SwiftUI sample app using Clean Architecture. Examples of working with CoreData persistence, networking, dependency injection, unit testing, and more.

Articles related to this project Clean Architecture for SwiftUI Programmatic navigation in SwiftUI project Separation of Concerns in Software Design C

iOS architectures - MVC, MVP, MVVM, MVVM-C, ReactorKit, VIPER, Clean Architecture
iOS architectures - MVC, MVP, MVVM, MVVM-C, ReactorKit, VIPER, Clean Architecture

iOS architectures - MVC, MVP, MVVM, MVVM-C, ReactorKit, VIPER, Clean Architecture, RIBs; Repository Pattern, Rxflow, Swinject, Tuist, Xcodegen, Cocoapods, SPM, Carthage + Rome

Simple sample of using the VIP (Clean Swift) architecture for iOS

MyAnimeList Simple sample of using the VIP (Clean Swift) architecture for iOS. ViewController: controls the event handling, view life cycle and displa

Weather Forecast App (OpenWeather API & CLLocationManager). Clean Swift VIP architecture.
Weather Forecast App (OpenWeather API & CLLocationManager). Clean Swift VIP architecture.

WeatherApp Weather Forecast App (OpenWeather API & CLLocationManager). Clean Swift VIP architecture. Without storyboard or xib. The application shows

SwiftUI sample app using Clean Architecture. Examples of working with CoreData persistence, networking, dependency injection, unit testing, and more.
SwiftUI sample app using Clean Architecture. Examples of working with CoreData persistence, networking, dependency injection, unit testing, and more.

Articles related to this project Clean Architecture for SwiftUI Programmatic navigation in SwiftUI project Separation of Concerns in Software Design C

A sample iOS app built using the Clean Swift architecture

Main Purpose is to create a simple project for Clean-Swift This project wrote with using Clean-Swift and MVP Design Pattern

Weather Forecast Assigment is an iOS application built to highlight MVP and Clean Architecture concepts

Weather Forecast Assigment - iOS - MVP + Clean Architecture Description Weather Forecast Assigment is an iOS application built to highlight MVP (Model

This is an example of clean architecture and MVVM pattern written in swift

Swift Clean Architecture MVVM This is an example of clean architecture and MVVM pattern written in swift First of all thanks to all of those who made

SpaceX rocket listing app using RxSwift and CLEAN Architecture with MVVM
SpaceX rocket listing app using RxSwift and CLEAN Architecture with MVVM

Jibble SpaceX rocket listing app using RxSwift and CLEAN Architecture with MVVM Demo Features Reactive Bindings URL / JSON Parameter Encoding Filter Y

App for displaying VK news feed (VKSDK API). Clean Swift VIP architecture
App for displaying VK news feed (VKSDK API). Clean Swift VIP architecture

VKNewsFeed VKNewsFeed - application for displaying VK news feed with dynamic cells and a collection of images in the post. Data request occurs from th

Owner
Eonil
Hobo.
Eonil
SwiftUI sample app using Clean Architecture. Examples of working with CoreData persistence, networking, dependency injection, unit testing, and more.

Articles related to this project Clean Architecture for SwiftUI Programmatic navigation in SwiftUI project Separation of Concerns in Software Design C

Alexey Naumov 4k Dec 31, 2022
This is an example of clean architecture and MVVM pattern written in swift

Swift Clean Architecture MVVM This is an example of clean architecture and MVVM pattern written in swift First of all thanks to all of those who made

null 19 Oct 12, 2022
Sample Code of the App Architecture Book

App Architecture iOS Application Design Patterns in Swift Welcome to the repository of the App Architecture book! This repository hosts all sample cod

objc.io 2k Dec 29, 2022
Reactant is a reactive architecture for iOS

Reactant Reactant is a foundation for rapid and safe iOS development. It allows you to cut down your development costs by improving reusability, testa

Brightify 374 Nov 22, 2022
Swift Interaction with VIPER Architecture

SwiftyVIPER SwiftyVIPER allows easy use of VIPER architecture throughout your iOS application. VIPER Architecture What is VIPER? Great question! VIPER

Cody Winton 121 Jan 2, 2023
YARCH iOS Architecture

YARCH is an architecture pattern developed primarly for iOS applications. You can ask any questions in our telegram channel. Russian version of the re

Alfa Digital 196 Jan 3, 2023
This repository contains a detailed sample app that implements VIPER architecture in iOS using libraries and frameworks like Alamofire, AlamofireImage, PKHUD, CoreData etc.

iOS Viper Architecture: Sample App This repository contains a detailed sample app that implements VIPER architecture using libraries and frameworks li

MindOrks 653 Jan 2, 2023
MoneySafe - Application for tracking income and expenses and analyzing expenses. VIPER architecture, CoreData, Charts

?? MoneySafe ?? Application for tracking income and expenses and analyzing expen

Vladislav 5 Dec 27, 2022
Sample project using VIPER architecture

VIPER-Persons Small project using a master and detail view Demonstrates the use of the following features: VIPER architecture (https://mutualmobile.co

Sebastian Wramba 43 Feb 11, 2022
Challenge-viper-finance - Project for VIPER Architecture Dev Sprints on Devpass

VIPER Challenge - Finance App ?? Neste desafio, aplicaremos conceitos da arquite

Devpass 15 Oct 11, 2022