🌊 Let your code flow. Extension methods for fluent syntax in Swift.

Overview

Flow

Swift

🌊 Let your code flow.

This library provides a bunch of extension methods for a better fluent syntax in Swift. This style is very useful for some operations that benefit from being able to be chained (composed) together.

Functionality

  • .then to configure reference and value types. Useful for configuration at the point of initialization.

  • .mutate in place value types.

  • .let to transform an object into another.

  • .do to perform multiple actions with the same object.

  • Free function variants, for when you prefer this syntax or don't want to conform to the protocol:

    • with (similar to .then)
    • withLet (similar to .let)
  • run as an alternative to immediately executed closures.

.then

Use .then to perform an object configuration inline. It applies statements in the closure to the object. It's very useful to set the properties of an object when defining it.

let label = UILabel().then {
  $0.text = "Hello"
  $0.textColor = .red
  $0.font = .preferredFont(forTextStyle: .largeTitle)
  $0.sizeToFit()
}

let size = CGSize().then {
	$0.width = 20
}

There are two overloads of this method provided. One that works on AnyObject (a.k.a. classes) and another that operates on Any (intended for value types). The compiler picks the correct one appropriately.

  • In the closure you get a reference to self or an inout copy in case of value types.
  • It returns the same reference to the object, or the mutated copy for value types.

Influences:

.mutate

Mutates a value in place. It s like .then but applies to self instead of a new copy. The value needs to be defined as a var.

view.frame.mutate {
  $0.origin.y = 200
  $0.size.width = 300
}
  • In the closure you get an inout reference to self .
  • It returns nothing.

This should be used only for value types. For reference types is recommended to use .then.

.let

You can think of .let as a map operation but for all the types (not only for Functors). It lets you transform the object into an object of another type.

let dateString: String = Date().let {
    let formatter = DateFormatter()
    return formatter.string(from: $0)
}

It works especially well for type conversions based on initializers:

let number: Int? = "42".let(Int.init)

Don't overuse this when you can use just plain dot syntax. You can use it to access a member of the object Date().let { $0.timeIntervalSince1970 } but that's just the same as Date().timeIntervalSince1970.

  • You get a reference to self in the closure.
  • It returns the object returned in the closure.

Influences:

.do

Use this method to perform multiple actions (side effects) with the same object. It helps to reduce the verbosity of typing the same name multiple times.

UserDefaults.standard.do {
    $0.set(42, forKey: "number")
    $0.set("hello", forKey: "string")
    $0.set(true, forKey: "bool")
}

This behaves like other methods if you discard their return, but is preferred to use do to convey the intention better. It also lets you avoid writing the return on some occasions.

  • You get a reference to self in the closure.
  • It returns nothing.

Influences:

.debug

By default, it prints self to the console. This method is useful for debugging intermediate values of a chain of method calls.

let result = Object()
   .then { ... }
   .debug("prefix")
   .let { ... }
   .debug()
  • You get a reference to self in the closure.
  • It returns the same object without touching it.

Free function with

Executes a closure with the object. This free function it's a substitute for .then when you can't use the method or if you prefer the free function style.

let label = with(UILabel()) {
    $0.text = "Hello"
    $0.textColor = .red
    $0.font = .preferredFont(forTextStyle: .largeTitle)
    $0.sizeToFit()
}
  • You get a reference to an inout copy of self in the closure.
  • It returns the returned object in the closure.

Influences:

Free function withLet

Variant of with that let's you return a different type. It's a free function alternative of let.

Free function run

Executes a closure of statements, useful to be used when you need an expression. This is like making a closure and invoking immediately but sometimes is clearer to have a specific name for it.

let result = run { ... } // same as { ... }()

Influences:

Supported Types

Since Swift doesn't let us extend non-nominal types like Any we need to conform each type to the Flowable protocol.

The library provides out of the box conformances for a bunch of Standard Library, Foundation and UIKit types. See Conformances.swift for the entire list.

You can conform any type yourself by just extending it:

extension YourType: Flowable {}

Note that you can use the free function variants without the types conforming to the protocol.

Influences

  • devxoul/Then
  • Functional style approaches (like Overture)
  • Kotlin Scope Functions. Note that Swift can't "rebind self" inside a closure, so most of Kotlin's scope functions are redundant.
  • Other languages that have a similar with or using functions.

Author

Alejandro Martinez | https://alejandromp.com | @alexito4

You might also like...
Have you ever wanted to just throw your optional like a table?

JebStolem Have you ever wanted to just throw your optional like a table? Or mayb

SwiftLint - A tool to enforce Swift style and conventions, loosely based on Swift Style Guide.
SwiftLint - A tool to enforce Swift style and conventions, loosely based on Swift Style Guide.

SwiftLint - A tool to enforce Swift style and conventions, loosely based on Swift Style Guide.

Sweet-swift - Make Swift Sweet by Gracefully Introducing Syntactic Sugar, Helper Functions and Common Utilities

Sweet Swift Make Swift Sweet by Gracefully Introducing Syntactic Sugar, Helper F

Airbnb's Swift Style Guide.

Airbnb Swift Style Guide Goals Following this style guide should: Make it easier to read and begin understanding unfamiliar code. Make code easier to

LinkedIn's Official Swift Style Guide

Swift Style Guide Make sure to read Apple's API Design Guidelines. Specifics from these guidelines + additional remarks are mentioned below. This guid

 The Official raywenderlich.com Swift Style Guide.
The Official raywenderlich.com Swift Style Guide.

The Official raywenderlich.com Swift Style Guide. Updated for Swift 5 This style guide is different from others you may see, because the focus is cent

A self-taught project to learn Swift.
A self-taught project to learn Swift.

30 Days of Swift Hi Community I am Allen Wang, a product designer and currently learning Swift. This project was totally inspired by Sam Lu's 100 Days

Explanations and samples about the Swift programming language
Explanations and samples about the Swift programming language

About Swift Contents Explanations and samples about: Swift Programming Language Swift Standard Library Target audience Developers familiar with object

A collection useful tips for the Swift language
A collection useful tips for the Swift language

SwiftTips The following is a collection of tips I find to be useful when working with the Swift language. More content is available on my Twitter acco

Releases(1.0.0)
Owner
Alejandro Martínez
Captain of the Mobile Team @workivate
Alejandro Martínez
A Collection of Tree-Sitter Parsers for Syntax Highlighting

CodeEditLanguages A collection of tree-sitter languages for syntax highlighting. Overview This package includes a binary framework CodeLanguagesContai

CodeEdit 16 Dec 30, 2022
Swift extension which adds start, animating and completion closures for CAAnimation objects. Aka, CAAnimation + Closure / Block

Swift-CAAnimation-Closure Swift extension which adds start, animating and completion closures for CAAnimation objects. Aka, CAAnimation + Closure or C

HongHao Zhang 112 Jun 17, 2022
FinderEx - MacOS Finder Sync Extension to Allow Adding Custom Actions

FinderEx MacOS Finder Sync Extension to Allow Adding Custom Actions Description

null 4 Jul 21, 2022
This is an iOS Safari Extension Sample that adds a "Develop menu" to Safari on iOS to allow you to analyze websites.

Develop Menu for Mobile Safari This is an iOS Safari Extension that adds a "Develop menu" to Safari on iOS to allow you to analyze websites. This is a

Watanabe Toshinori 1 Dec 7, 2022
GM-Dragable - A DragableView extension for GM

GM-Dragable A DragableView extension for GM How to use it UIViewController try?

Gavin 0 Jan 20, 2022
A browser extension for Safari that makes sure that cut, copy, and paste are enabled.

Paste for Safari A browser extension for Safari that makes sure that cut, copy, and paste are enabled. Notes This is pretty rough and does work. The v

Mark Ferlatte 1 Dec 20, 2022
A blog project where you can write your articles, upload photos, categorize them, and add them to your favorites

A blog project where you can write your articles, upload photos, categorize them, and add them to your favorites. The aim of the project is to learn the use of Core Data.

Cem 7 Mar 21, 2022
Import files into your Swift scripts!

Swiftmix is a tool aimed to make better use of Swift scripts. Right now there is no decent way to import source files in scripts without using SPM. Sw

Vitaliy Salnikov 6 Nov 19, 2022
👨‍💻Watch the latest and greatest conference videos on your Mac

Conferences.digital is the best way to watch the latest and greatest videos from your favourite developer conferences for free on your Mac. Either sea

Timon Blask 768 Jan 4, 2023
SwiftUI module library for adding seasons theme animations to your app

HolidayThemes SwiftUI module library for adding seasons theme animations to your app. Requirements iOS 13.0+ Xcode 12.0+ Installation Swift Package Ma

null 2 Mar 7, 2022