Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write a great README #21

Closed
bolismauro opened this issue Oct 31, 2016 · 6 comments
Closed

Write a great README #21

bolismauro opened this issue Oct 31, 2016 · 6 comments
Assignees

Comments

@bolismauro
Copy link
Contributor

bolismauro commented Oct 31, 2016

As discussed we want to touch the following points (more or less in deep) in the README

  • Background (react/redux)
  • History, why we have created Katana
  • How to use it
  • Very simple getting started (ideally max 10 lines for an hello world)
  • “We use it in production”
  • Roadmap
  • Why do we release Katana as OSS?

Let's take a look at other well done README for inspiration.

This is also an interesting resource

@lucaquerella
Copy link
Contributor

@smaramba this is another source of inspiration https://github.com/ReSwift/ReSwift

@lucaquerella
Copy link
Contributor

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.

@smaramba
Copy link
Contributor

smaramba commented Nov 3, 2016

@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)

@cosenal
Copy link

cosenal commented Nov 3, 2016

@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

@smaramba
Copy link
Contributor

smaramba commented Nov 3, 2016

sure, will do right now

@smaramba
Copy link
Contributor

smaramba commented Nov 3, 2016

done.
#30

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants