✨ Super sweet syntactic sugar for Swift initializers

Overview

Then

Swift CocoaPods Build Status

Super sweet syntactic sugar for Swift initializers.

At a Glance

Initialize UILabel then set its properties.

let label = UILabel().then {
  $0.textAlignment = .center
  $0.textColor = .black
  $0.text = "Hello, World!"
}

This is equivalent to:

let label: UILabel = {
  let label = UILabel()
  label.textAlignment = .center
  label.textColor = .black
  label.text = "Hello, World!"
  return label
}()

Tips and Tricks

  • You can use then() to all of NSObject subclasses.

    let queue = OperationQueue().then {
      $0.maxConcurrentOperationCount = 1
    }
  • Want to use with your own types? Just make extensions.

    extension MyType: Then {}
    
    let instance = MyType().then {
      $0.really = "awesome!"
    }
  • Use with() when copying the value types.

    let newFrame = oldFrame.with {
      $0.size.width = 200
      $0.size.height = 100
    }
    newFrame.width // 200
    newFrame.height // 100
  • Use do() to do something with less typing.

    UserDefaults.standard.do {
      $0.set("devxoul", forKey: "username")
      $0.set("[email protected]", forKey: "email")
      $0.synchronize()
    }

Real World Example

Here's an example usage in an UIViewController subclass.

final class MyViewController: UIViewController {

  let titleLabel = UILabel().then {
    $0.textColor = .black
    $0.textAlignment = .center
  }

  let tableView = UITableView().then {
    $0.backgroundColor = .clear
    $0.separatorStyle = .none
    $0.register(MyCell.self, forCellReuseIdentifier: "myCell")
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    self.view.addSubview(self.titleLabel)
    self.view.addSubview(self.tableView)
  }

}

Installation

  • Using CocoaPods:

    pod 'Then'
  • Using Swift Package Manager:

    import PackageDescription
    
    let package = Package(
      name: "MyAwesomeApp",
      dependencies: [
        .Package(url: "https://github.com/devxoul/Then", majorVersion: 2),
      ]
    )

License

Then is under MIT license. See the LICENSE file for more info.

Comments
  • cannot install through carthage

    cannot install through carthage

    *** Skipped building Then due to the error: Dependency "Then" has no shared framework schemes

    Please follow this guide to fix -> https://github.com/Carthage/Carthage#share-your-xcode-schemes

    opened by danjiang 8
  • lazy code

    lazy code

    lazy var tableView: UITableView = { let tabView =UITableView.init(frame: .zero, style: .plain) tabView.backgroundColor = UIColor.white tabView.dataSource = self tabView.delegate = self return tabView }() I often use lazy loading, and,how to write by Then。Can you give me a test code。

    opened by hanks-hu 7
  • Add ability to call block on Optional

    Add ability to call block on Optional

    Hey!

    I really like then approach and wanted to extend it for optionals. Feature implemented in this PR is different from current Then, however similar in ideology.

    It allows calling any custom block of code on optional, if optional contains .Some. Most common case for this would be [weak self] in various kinds of completion blocks, however there are a lot more cases where you can use this approach.

    For example, let's say we need to use weak self, however pass self somewhere else as unwrapped optional, like this:

    self.doSomethingWithCompletion { [weak self] result in
        self?.parseResult(result, receivedFrom: self!)
        self?.doSomething()
    }
    

    This would require multiple optional unwrappings and possibly even force unwraps. Another way to do this is to unwrap with guard:

    self.doSomethingWithCompletion { [weak self] result in
        guard let strongSelf = self else { return }
        strongSelf.parseResult(result, receivedFrom: strongSelf)
        strongSelf.doSomething()
    }
    

    Unwraps are gone, however we introduced new variable for self, which is not really convenient. Meet Then from this PR:

    self.doSomethingWithCompletion { [weak self] result in
        self.then {
            $0.parseResult(result, receivedFrom: $0)
            $0.doSomething()
        }
    }
    
    opened by DenTelezhkin 5
  • Added

    Added "when", which will only execute when initial condition is met

    I propose we add one more function - when. This serves exactly the same purpose, but "then" is only executed when initial condition is met. This is extremely useful in a lot of cases, as it changes often used syntax

    if (true) {
        label.then {
            ...
        }
    }
    

    to

    label.when(true) {
        ...
    }
    

    The only problem is that it does not fit with name of your repository :D but I think it is okay :)

    opened by JiriTrecak 5
  • ERROR when upload to AppStore

    ERROR when upload to AppStore

    ERROR ITMS-90056: "This bundle Payload/X.app/Frameworks/Then.framework is invalid. The Info.plist file is missing the required key: CFBundleVersion."

    opened by devjia 4
  • How to use this syntax for IBOutlet views?

    How to use this syntax for IBOutlet views?

    Instead of creating a new instance for a view, is there a possibility to fetch the existing instance and set attributes to it? I want to update attributes initially for IBOutlets views.

    opened by dinarajas 4
  • cocoapods with 'Then' issues

    cocoapods with 'Then' issues

    when I use it with cocoapods ,I will get the issues "Command /bin/sh failed with exit code 1", but not appear other what like "then".it is my pods file:

    platform :ios, '9.0' use_frameworks!

    target 'MapInSwift' do pod 'Alamofire' pod 'SwiftyJSON' pod 'Then', '~> 2.1' end

    if i remove the line with "pod 'Then', '~> 2.1'", i will get no issue

    I fand the solution on the google but no way is fit me.If i need particular setting with Xcode(xcode 8.0; swift 3.0)

    opened by yanjinquan 3
  • Accessing instance variables in then block

    Accessing instance variables in then block

    I can't seem to access class variables in my then block:

    For example

    class GradientView {
       let colors = ...
       lazy var gradientLayer = CAGradientLayer().then {
           $0.colors = self.colors // also tried colors
       }
    }
    

    doesn't work, but

    class GradientView {
       let colors = ...
       lazy var gradientLayer: CAGradientLayer = {
           let layer = CAGradientLayer()
           layer.colors = self.colors
           return layer
       }()
    }
    

    does.

    Can I repeat my old pattern of accessing instance variables in a lazy init using Then?

    opened by AndrewSB 3
  • [proposal] Implementation of another method without inout

    [proposal] Implementation of another method without inout

    Problem

    The code below works in Then 1.0.1 but doesn't work in 1.0.2.

    func tempt(label: UILabel) {
        label.text = "I💞Then"
    }
    
    let label1 = UILabel()
    tempt(label1) // Works fine definitely
    UILabel().then(tempt) // Error: Cannot convert value of type '(UILabel) -> ()' to expected argument type 'inout UILabel -> Void'
    

    Adding inout keyword to the func resolves the error, but it brings another problem.

    func temptInOut(inout label: UILabel) {
        label.text = "I💞Then"
    }
    
    UILabel().then(temptInOut) // Works fine
    
    let label2 = UILabel()
    temptInOut(label2) // Error: Cannot convert value of type 'UILabel' to expected argument type 'inout UILabel'
    temptInOut(&label2) // Another Error: Cannot pass immutable value as inout argument: 'label2' is a 'let' constant
    

    To resolve all errors, I should write code as below.

    var label3 = UILabel()
    temptInOut(&label3) // Works fine but seems ugly.
    

    I don't use neither var nor &...

    Proposal

    #18 is nice-to-have modification, but old-style method(without inout keyword) is also nice in some situations.

    So why don't you implement another old-type method as (@noescape block: Self -> Void) -> Self ?

    opened by takasek 3
  • Strange issue after updating to version 1.0.0

    Strange issue after updating to version 1.0.0

    I got compiling error Cannot convert value of type '_ -> ()' to expected argument type 'inout WKWebView -> Void' with this code

    webView.then {
        $0.navigationDelegate = self
    }
    

    However, the error's gone when there are two assignments in the block

    webView.then {
        $0.navigationDelegate = self
        $0.tag = 1
    }
    
    opened by tuyendv2 3
  • Fix for CoreGraphics not being available on Linux

    Fix for CoreGraphics not being available on Linux

    I'm using this library in a Vapor project which needs to run on Linux and I found that Then won't build on Linux because CoreGraphics isn't available so I've wrapped all CoreGraphics import and all the CG* extensions in #if !os(Linux) checks.

    opened by Noobish1 2
  • [proposal] Mutating a value type

    [proposal] Mutating a value type

    Motivation

    To mutate some deeply nested value types, we have to write the whole key path at least twice:

    some.very[deep].structure.someProperty = someValue
    some.very[deep].structure.anotherProperty = anotherValue
    
    // or with Then:
    
    some.very[deep].structure = some.very[deep].structure.with {
        $0.someProperty = someValue
        $0.anotherProperty = anotherValue
    }
    

    Solution

    Let's extend Then with mutate function (alternatives: update, access, write):

    extension Then {
        public mutating func mutate(_ block: (inout Self) throws -> Void) rethrows {
            try block(&self)
        }
    }
    

    Usage:

    some.very[deep].structure.mutate {
        $0.someProperty = someValue
        $0.anotherProperty = anotherValue
    }
    

    It would be great to have this in Then library. Thank you!

    opened by dtrofimov 1
  • Is Then dead? (abandon-ware?)

    Is Then dead? (abandon-ware?)

    Has Then been abandoned?  It doesn't appear @devxoul has responded to any issues or PRs, or made any code changes since Sept 2019.  And basically every comment he made before than was highly resistant to making any changes or accommodations for the devs who rely on Then.

    Is it time for someone else to take over the project?  Is there someone else who is already maintaining an updated fork who's willing to take up the mantle of maintaining the community, and who welcomes us all switching over to his/her fork?

    Side-note: I grew tired of some of the issues with Then a while back and wrote my own stab from scratch at solving this problem— I chose to go with a free function approach that's closer to the with keyword in Python, JavaScript, Visual Basic, Object Pascal, Delphi and using in C#, and which seems to be more idiomatic Swift.  I also care about making sure my libraries work in every build toolchain and environment (SPM, CocoaPods, Carthage, Xcode project embedding, etc.); can solve any reasonable user-requested problem (@discardableResult, arbitrary return value, @inlinable, etc.); and can be used freely by everyone (completely copyright-free public domain, no restrictions or attribution needed).  My recently-uploaded library is called With.

    opened by capnslipp 2
  • Remove xcodeproj & xcshareddata ignores

    Remove xcodeproj & xcshareddata ignores

    The .gitignore file currently is ignoring xcodepoj-related files, which currently does nothing for the Then project because of the decision to go full SPM and remove all xcodeproj stuff (#55).

    However, ignoring these files causes issues when Then's source is included in outer Git repo (via git-subtree or direct copying of project) such as when using Carthage or manual library management in conjunction with a generated xcodeproj (swift package generate-xcodeproj). Because Then's .gitignore is picked up by the enclosing repo, that prevents the generated xcodeproj or shared schemes from being able to be checked-in— which should arguably be under the discretion of the enclosing repo's build setup.  Removed the ignores for xcodeproj and xcshareddata to fix this, and removed the xcuserdata line too for good measure (again, if there's no xcodeproj in Then, there's no need to ignore it).

    opened by capnslipp 1
Releases(3.0.0)
Owner
Suyeol Jeon
A lazy developer 😴 I write many code to write less code.
Suyeol Jeon
🍯 Syntactic sugar for Moya

MoyaSugar Syntactic sugar for Moya. Why? Moya is an elegant network abstraction layer which abstracts API endpoints gracefully with enum. However, it

Suyeol Jeon 186 Jan 6, 2023
Swift's Sugar. Heavily inspired on Objc Sugar

Swift's Sugar. Heavily inspired on Objc Sugar

Rui Peres 154 Jun 29, 2022
📦 KeyPath dynamicMemberLookup based syntax sugar for Swift.

DuctTape ?? KeyPath dynamicMemberLookup based syntax sugar for Swift. let label: UILabel = UILabel().ductTape .numberOfLines(0) .textColor(.re

Taiki Suzuki 171 Nov 4, 2022
SharkUtils is a collection of Swift extensions, handy methods and syntactical sugar that we use within our iOS projects at Gymshark.

SharkUtils is a collection of Swift extensions, handy methods and syntactical sugar that we use within our iOS projects at Gymshark.

Gymshark 1 Jul 6, 2021
Sugar is a sweetener for your Cocoa implementations.

Sugar is a sweetener for your Cocoa implementations. Table of Contents iOS Application Screen Simulator Keyboard Observer iOS Extensions UIView

HyperRedink 1.1k Dec 29, 2022
Synatax sugar for Measurement of Foundation.

WrappedMeasurement 2022 © Weizhong Yang a.k.a zonble Syntax sugar for NSMeasurement of Foundation. NSMeasurement and NSUnit compose a great tool to le

Weizhong Yang a.k.a zonble 8 Jan 25, 2022
HumanMeasurementSwift - Synatax sugar for Measurement of Foundation

HumanMeasurement 2022 © Weizhong Yang a.k.a zonble Syntax sugar for NSMeasuremen

Weizhong Yang a.k.a zonble 8 Jan 25, 2022
Extensions giving Swift's Codable API type inference super powers 🦸‍♂️🦹‍♀️

Welcome to Codextended — a suite of extensions that aims to make Swift’s Codable API easier to use by giving it type inference-powered capabilities an

John Sundell 1.4k Jan 2, 2023
Super powerful remote config utility written in Swift (iOS, watchOS, tvOS, OSX)

Mission Control Super powerful remote config utility written in Swift (iOS, watchOS, tvOS, OSX) Brought to you by Have you ever wished you could chang

appculture 113 Sep 9, 2022
BCSwiftTor - Opinionated pure Swift controller for Tor, including full support for Swift 5.5 and Swift Concurrency

BCSwiftTor Opinionated pure Swift controller for Tor, including full support for

Blockchain Commons, LLC — A “not-for-profit” benefit corporation 4 Oct 6, 2022
Swift Markdown is a Swift package for parsing, building, editing, and analyzing Markdown documents.

Swift Markdown is a Swift package for parsing, building, editing, and analyzing Markdown documents.

Apple 2k Dec 28, 2022
Swift-DocC is a documentation compiler for Swift frameworks and packages aimed at making it easy to write and publish great developer documentation.

Swift-DocC is a documentation compiler for Swift frameworks and packages aimed at making it easy to write and publish great developer docum

Apple 833 Jan 3, 2023
Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. (Pure Swift, Supports Linux)

SwiftFoundation Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. Goals Provide a cross-platform in

null 620 Oct 11, 2022
Swift - ✏️Swift 공부 저장소✏️

Swift 스위프트의 기초 1. Swift의 기본 2. 변수와 상수 [3. 데이터 타입 기본] [4. 데이터 타입 고급] 5. 연산자 6. 흐름 제어 7. 함수 8. 옵셔널 객체지향 프로그래밍과 스위프트 9. 구조체와 클래스 10. 프로퍼티와 메서드 11. 인스턴스 생

Jiwon 0 Mar 9, 2022
Swift-ndi - Swift wrapper around NewTek's NDI SDK

swift-ndi Swift wrapper around NewTek's NDI SDK. Make sure you extracted latest

Alessio Nossa 12 Dec 29, 2022
__.swift is a port of Underscore.js to Swift.

__.swift Now, __.swift is version 0.2.0! With the chain of methods, __.swift became more flexible and extensible. Documentation: http://lotz84.github.

Tatsuya Hirose 86 Jun 29, 2022
SNTabBarDemo-Swift - Cool TabBar With Swift

SNTabBarDemo-Swift Cool TabBar How To Use // MARK: - setup private func setu

iAnchor 3 Sep 29, 2022
Swift-when - Expression switch support in Swift

Swift When - supporting switch expressions in Swift! What is it? Basically, it a

Gordan Glavaš 7 Nov 24, 2022
Swift-compute-runtime - Swift runtime for Fastly Compute@Edge

swift-compute-runtime Swift runtime for Fastly Compute@Edge Getting Started Crea

Andrew Barba 57 Dec 24, 2022