Comments (6)
done.
#30
from katana-swift.
@smaramba this is another source of inspiration https://github.com/ReSwift/ReSwift
from katana-swift.
some inputs, use them if you wish:
History, why we have created Katana
we like react/redux but we wanted to use the native environment: we are more proficient and we find it easier to debug
Why do we release Katana as OSS
Why | |
---|---|
❤️ | We use may OSS projects and we want to give back something valuable to the community |
😎 | We feel proud of Katana and we want to show the world we are cool |
💥 | We want to get people involved in the project so they can improve it |
Plastic
Plastic is very tight to Katana ATM. We should promote this as feature rather than a problem. My personal opinion is that Plastic a great (probably the best 😎) layout system. I would get inspired from Plastic (objc) README to explain its key strengths.
from katana-swift.
@bolismauro @lucaquerella here the first draft of the readme.
I've looked at pretty much every readme of every significant swift framework, this is (excluding the copy that is work in progress) my best summary of what a readme should contain.
feel free to suggest or question everything.
my suggestion to improve this:
- insert/update the items in the roadmap (under features)
- introduce also the advanced stuff (i.e. asyncActions)
- tune the example to something comprehensive that we will also release as a complete example
- include more examples, even complex ones
Katana
A modern framework for well-behaved apps
Katana is a modern swift framework for writing iOS apps originated from our love for the react/redux philosophy and the lack of an existing native swift implementation.
Katana gives structure to all the aspects of your app from the Logic to the UI, encapsulating state management and updating the UI automatically:
- logic: like in Redux, in a Katana app all the state is entirely described by a single serializable data structure (store) and the only way to change the state is to emit an action. An action is an intent to transform the state and contains all the informations to do so. Because all the changes are centralized and are happening in a strict order, there are no subtle race conditions to watch out for.
- UI: like in React, you define your UI in terms of a tree of components declaratively described by props (external world) and state (internal world). This approach lets you think about components as an isolated, reusable piece of UI, since the way a component is rendered only depends on the current props and state of the component itself.
- logic<->UI: in Katana your UI components are attached to the store and will be automatically updated on every state change. You control how they change, connecting the store state to the component props.
- layout: Katana defines a concise language to describe fully responsive layouts that will gracefully scale at every aspect ratio or size, including font sizes and images.
We feel that Katana helped us a lot since we started using it in production for more than X apps with XXXX active users per day. At BendingSpoons we use a lot of Open Sourced projects ourselves and we wanted to give something back to the community, hoping you will find this useful and possibly contribute. <3
features
- Immutable state
- unidirectional data flow
- sync/async/sideEffect actions
- middlewares
- automatic UI update
- native redux-like implementation
- native react-like implementation
- declarative UI
- leverage Plastic layout engine
- support other layout engines
- insert other missing thing here
Installation
Katana is available through CocoaPods and [Carthage](insert link here), you can also drop Katana.project
into your XCode project.
Requirements
-
iOS 8.4+
-
Xcode 8.0+
-
Swift 3.0+
CocoaPods
CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:
$ sudo gem install cocoapods
To integrate Katana into your XCode project using CocoaPods, add it to your Podfile
:
use_frameworks!
source [include project source here]
platform :ios, '8.4'
pod 'KatanaSwift'
And run:
$ pod install
Carthage
Carthage is a decentralized dependency manager for Cocoa projects.
You can install Carthage downloading and running the Carthage.pkg
file you can download from here or you can install it using Homebrew simply by running:
$ brew update
$ brew install carthage
To integrate Katana into your XCode project using Carthage, add it to your Cartfile
:
github "Bendingspoons/KatanaSwift"
And Run:
$ carthage update
Then drag the built Katana.framework
into your XCode project
Overview
defining the logic of your app
your entire app State
is defined in a single struct:
struct ToDoState: State {
var todos: [String]
}
the app state
can only be modified by an Action
. An action defines, in its reduce()
method, the new app state based on the current app state and the action itself.
struct AddTodo: SyncAction {
var payload: String
static func reduce(state: State, action: AddToDo) -> State {
guard var state = state as? ToDoState else { fatalError() }
state.todos.append(action.payload)
return state
}
}
the Store
stores your entire app state
and it is responsible for dispatching the actions
let store = Store<ToDoState>()
store.dispatch(AddTodo("remember the milk"))
you can ask the Store
to be notified for every change in the app state
store.addListener() {
tableView.reloadData()
}
defining the UI
Katana is inspired by React, you declaratively define your UI components called NodesDescriptions
. Each NodeDescription
will describe itself in terms of its internal state
, the inputs coming from outside, called the props
and the UIKit component this NodeDescription will be rendered as, the NativeView
.
struct ToDoScreen: NodeDescription {
typealias StateType = EmptyState
typealias PropsType = ToDoScreenProps
typealias NativeView = UIView
var props: ToDoScreenProps
}
Inside the props
you want to specify all the inputs needed to render your NativeView
and to feed your children components
struct ToDoScreenProps: NodeProps {
var frame: CGRect = .zero
var todos: [String] = []
}
When it's time to render the component, the method applyPropsToNativeView
is called, this is where we need to adjust our nativeView to reflect the props
and the state
struct ToDoScreen: NodeDescription {
...
public static func applyPropsToNativeView(props: ToDoScreenProps,
state: EmptyState,
view: UIView, ...) {
view.frame = props.frame
}
}
NodeDescriptions
lets you split the UI into small independent, reusable pieces. That's why it is very common for a NodeDescription
to be composed by others NodeDescription
as children. To define child components implement the method childrenDescriptions
struct ToDoScreen: NodeDescription {
...
public static func childrenDescriptions(props: ToDoScreenProps,
state: EmptyState, ...) -> [AnyNodeDescription] {
return [
Text(props: TextProps())
.key(.title)
.text("My awesome todos", fontSize: 15)
.borderColor(UIColor("#d54a0c"))
),
Table(props: TableProps()
.key(.todoList)
.delegate(ToDoListDelegate(todos: props.todos))
)
]
}
}
attaching the UI to the Logic
The Root
object is responsible for connecting the Store
to the tree of nodes that compose our UI.
You create a root object starting from the top level NodeDescription and the store.
let root = ToDoScreen(props: ToDoProps()).makeRoot(store: store)
Everytime a new app state is available the store emits an event that is captured by the Root and dispatched down to the tree of UI components.
If you want a node to receive updates from the Store
just declare its NodeDescription
as ConnectedNodeDescription
and implement the method connect
to attach the app Store
to the component props
struct ToDoScreen: ConnectedNodeDescription {
...
static func connect(props: inout ToDoScreenProps, to storeState: ToDoState) {
props.todos = storeState.todos
}
}
layout of the UI
Katana have its own language to programmatically define fully responsive layouts that will gracefully scale at every aspect ratio or size, including font sizes and images.
EachNodeDescription
is responsible to define the layout of its children implementing the method layout
.
struct ToDoScreen: ConnectedNodeDescription {
...
static func layout(views: ViewsContainer<ToDoKeys>, props: ToDoScreenProps, state: EmptyState) {
let rootView = views.nativeView
let title = views[.title]!
let todoList = views[.todoList]!
title.asHeader(rootView, insets: .scalable(30, 0, 0, 0))
title.height = .scalable(60)
todoList.fillHorizontally(rootView)
todoList.top = title.bottom
todoList.bottom = rootView.bottom
}
}
You can find the complete example [here](insert link to the complete example)
Where to go from here
Explore sample projects
[insert here list of sample projects]
Check out the documentation
[insert here link to the documentation]
Communication
-
If you need help, use Stack Overflow with tag 'katanaswift'
-
if you have any questions you can find us on twitter: @handle, @handle, @handle, ...
-
If you found a bug, open an issue
-
If you have a feature request, open an issue
-
If you want to contribute, submit a pull request
License
Katana is available under the [MIT license](insert link to LICENSE file here)
from katana-swift.
@smaramba can you move that to a pull request? it's hard to review this way. I don't know anything about Swift or Katana, I just wanted to give some generic inputs
from katana-swift.
sure, will do right now
from katana-swift.
Related Issues (20)
- Improve state mocking
- Managed children of native view don't update correctly in collectionviews
- Store queue management should be refactored
- Katana Refs
- undefined is not an object (evaluting 'Proptypes.number') HOT 2
- Fail carthage build HOT 1
- Dead links in README HOT 2
- ChangeLog.md Request
- Are there any drawbacks to having a mutable store? HOT 1
- Interface Builder HOT 1
- Reduce boilerplate in Actions HOT 7
- Is there any co-currency management for a single store? HOT 2
- [experimental] Catching errors when dispatching HOT 2
- [experimental] ObserverInterceptor items executed more than once HOT 1
- StoreListener change HOT 4
- Katana for SwiftUI HOT 1
- Can't build with Carthage HOT 2
- Provide Sample Project HOT 1
- SPM Installation (v4.0.0) failed
- Update Swift version HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from katana-swift.