All Projects β†’ CaptureContext β†’ swift-declarative-configuration

CaptureContext / swift-declarative-configuration

Licence: MIT license
Declarative configuration for your objects

Programming Languages

swift
15916 projects
shell
77523 projects
Makefile
30231 projects

Projects that are alternatives of or similar to swift-declarative-configuration

BottomSheet
A BottomSheet component made with UIKit. Completely written in Swift 🧑
Stars: ✭ 62 (+34.78%)
Mutual labels:  uikit, spm
SwiftUIKit
πŸ“± UIKit code that is fun to write
Stars: ✭ 71 (+54.35%)
Mutual labels:  uikit, spm
trace-cocoa-sdk
Catch bugs before they reach production β€” get detailed crash reports and monitor how your app is performing across the entire install base.
Stars: ✭ 15 (-67.39%)
Mutual labels:  uikit, spm
column-text-view-ui
πŸ“„ Column Text View is an adaptive UI component that renders text in columns, horizontally [iOS 12, UIKit, TextKit, SwiftUI].
Stars: ✭ 11 (-76.09%)
Mutual labels:  uikit, spm
Jsonnet
Jsonnet - The data templating language
Stars: ✭ 5,257 (+11328.26%)
Mutual labels:  functional, configuration
njsx
A customizable and declarative interface for creating React and React Native components without JSX syntax.
Stars: ✭ 29 (-36.96%)
Mutual labels:  builder, functional
awesome-ios
A collaborative list of awesome for iOS developers. Include quick preview.
Stars: ✭ 1,329 (+2789.13%)
Mutual labels:  uikit, spm
ObservableComputations
Cross-platform .NET library for computations whose arguments and results are objects that implement INotifyPropertyChanged and INotifyCollectionChanged (ObservableCollection) interfaces.
Stars: ✭ 94 (+104.35%)
Mutual labels:  functional, declarative
FTAPIKit
Declarative and generic REST API framework using Codable.
Stars: ✭ 18 (-60.87%)
Mutual labels:  functional, declarative
ngx-env
Easily inject environment variables into your Angular applications
Stars: ✭ 73 (+58.7%)
Mutual labels:  builder, configuration
Pypika
PyPika is a python SQL query builder that exposes the full richness of the SQL language using a syntax that reflects the resulting query. PyPika excels at all sorts of SQL queries but is especially useful for data analysis.
Stars: ✭ 1,111 (+2315.22%)
Mutual labels:  builder, functional
sitri
Sitri - powerful settings & configs for python
Stars: ✭ 20 (-56.52%)
Mutual labels:  configuration
sugar
Declarative HTTP client for Golang
Stars: ✭ 25 (-45.65%)
Mutual labels:  declarative
react-nonav
Experimental React Native declarative navigation
Stars: ✭ 58 (+26.09%)
Mutual labels:  declarative
vuo
A realtime visual programming language for interactive media.
Stars: ✭ 103 (+123.91%)
Mutual labels:  declarative
pythonic
Python like utility functions for JavaScript: range, enumerate, zip and items.
Stars: ✭ 28 (-39.13%)
Mutual labels:  functional
CircularProgressView
Circular and animated progress bar for iOS
Stars: ✭ 25 (-45.65%)
Mutual labels:  spm
kotlin-coroutines-jdbc
A library for interacting with blocking JDBC drivers using Kotlin Coroutines.
Stars: ✭ 40 (-13.04%)
Mutual labels:  functional
Fae
A functional module for Deno inspired from Ramda.
Stars: ✭ 44 (-4.35%)
Mutual labels:  functional
lambda-zero
A minimalist pure lazy functional programming language
Stars: ✭ 65 (+41.3%)
Mutual labels:  functional

Swift Declarative Configuration

Test SwiftPM 5.6 Platforms @capture_context

Swift Declarative Configuration (SDC, for short) is a tiny library, that enables you to configure your objects in a declarative, consistent and understandable way, with ergonomics in mind. It can be used to configure any objects on any platform, including server-side-swift.

Products

  • FunctionalModification

    Provides modification functions for copying and modifying immutable stuff. It is useful for self-configuring objects like builder, when modifying methods should return modified self.

  • FunctionalKeyPath

    Functional KeyPath wrapper.

  • FunctionalConfigurator

    Functional configurator for anything, enables you to specify modification of an object and to apply the modification later.

    Also contains self-implementing protocols (ConfigInitializable, CustomConfigurable) to enable you add custom configuration support for your types (NSObject already conforms to it for you).

  • FunctionalBuilder

    Functional builder for anything, enables you to modify object instances in a declarative way. Also contains BuilderProvider protocol with a computed builder property and implements that protocol on NSObject type.

  • FunctionalClosures

    Functional closures allow you to setup functional handlers & datasources, the API may seem a bit strange at the first look, so feel free to ask or discuss anything here.

  • DeclarativeConfiguration

    Wraps and exports all the products.

Basic Usage

See tests for more

No SDC

class ImageViewController: UIViewController {
  let imageView: UIImageView = {
    let imageView = UIImageView()
    imageView.contentMode = .scaleAspectFit
    imageView.backgroundColor = .black
    imageView.layer.masksToBounds = true
    imageView.layer.cornerRadius = 10
    return imageView
  }()
    
  override func loadView() {
    self.view = imageView
  }
}

FunctionalConfigurator

Note: This way is recommended, but remember, that custom types MUST implement initializer with no parameters even if the superclass already has it or you will get a crash otherwise.

import FunctionalConfigurator

class ImageViewController: UIViewController {
  let imageView = UIImageView { $0 
    .contentMode(.scaleAspectFit)
    .backgroundColor(.black)
    .layer.scope { $0
      .masksToBounds(true)
      .cornerRadius(10)
    }
  }
    
  override func loadView() {
    self.view = imageView
  }
}

FunctionalBuilder

Note: This way is recommended too, and it is more safe, because it modifies existing objects.

import FunctionalBuilder

class ImageViewController: UIViewController {
  let imageView = UIImageView().builder
    .contentMode(.scaleAspectFit)
    .backgroundColor(.black)
    .layer.masksToBounds(true)
    .layer.cornerRadius(10)
    .build()
    
  override func loadView() {
    self.view = imageView
  }
}

FunctionalClosures

No SDC

Declaration

public class TapGestureRecognizer: UITapGestureRecognizer {
  var onTapGesture: ((TapGestureRecognizer) -> Void)?
    
  init() {
    super.init(target: nil, action: nil)
    commonInit()
  }
    
  override public init(target: Any?, action: Selector?) {
    super.init(target: target, action: action)
    commonInit()
  }
    
  private func commonInit() {
    self.addTarget(self, action: #selector(handleTap))
  }
    
  @objc private func handleTap(_ recognizer: TapGestureRecognizer) {
    onTapGesture?(recognizer)
  }
}

Usage

let tapRecognizer = TapGestureRecognizer()

// handler setup
tapRecognizer.onTapGesture = { recognizer in
	// ...
}

// call from the outside
tapRecognizer.onTapGesture?(tapRecognizer)

With SDC

Declaration

public class TapGestureRecognizer: UITapGestureRecognizer {
  @Handler<TapGestureRecognizer>
  var onTapGesture
    
  init() {
    super.init(target: nil, action: nil)
    commonInit()
  }
    
  override public init(target: Any?, action: Selector?) {
    super.init(target: target, action: action)
    commonInit()
  }
    
  private func commonInit() {
    self.addTarget(self, action: #selector(handleTap))
  }
    
  @objc private func handleTap(_ recognizer: TapGestureRecognizer) {
    _onTapGesture(recognizer)
  }
}

Usage

let tapRecognizer = TapGestureRecognizer()

// handler setup now called as function
tapRecognizer.onTapGesture { recognizer in
	// ...
}

// call from the outside now uses propertyWrapper projectedValue API, which is not as straitforward
// and it is nice, because:
// - handlers usually should not be called from the outside
// - you do not lose the ability to call it, but an API tells you that it's kinda private
tapRecognizer.$onTapGesture?(tapRecognizer)

Also you can create such an instance with Configurator:

let tapRecognizer = TapGestureRecognizer { $0 
  .$onTapGesture { recognizer in 
    // ...
  }
}

More

Builder

Customize any object by passing initial value to a builder

let object = Builder(Object())
  .property.subproperty(value)
  .build() // Returns modified object

For classes you can avoid returning a value by calling apply method, instead of build

let _class = _Class()
Builder(_class)
  .property.subproperty(value)
  .apply() // Returns Void

In both Builders and Configurators you can use scoping

let object = Object { $0
  .property.subproperty(value)
}

Conform your own types to BuilderProvider protocol to access builder property.

import CoreLocation
import DeclarativeConfiguration

extension CLLocationCoordinate2D: BuilderProvider {}
// Now you can access `location.builder.latitude(0).build()`

Configurator

Note: Your NSObject classes must implement init() to use Configurators. It's a little trade-off for the convenience it brings to your codebase, see tests for an example.

DataSource

OptionalDataSource and DataSource types are very similar to the Handler, but if Handler<Input> is kinda OptionalDataSource<Input, Void>, the second one may have different types of an output. Usage is similar, different types are provided just for better semantics.

Installation

Basic

You can add DeclarativeConfiguration to an Xcode project by adding it as a package dependency.

  1. From the File menu, select Swift Packages β€Ί Add Package Dependency…
  2. Enter "https://github.com/makeupstudio/swift-declarative-configuration" into the package repository URL text field
  3. Choose products you need to link them to your project.

Recommended

If you use SwiftPM for your project structure, add DeclarativeConfiguration to your package file.

.package(
  url: "[email protected]:capturecontext/swift-declarative-configuration.git", 
  .upToNextMinor(from: "0.3.0")
)

or via HTTPS

.package(
  url: "https://github.com:capturecontext/swift-declarative-configuration.git", 
  .exact("0.3.0")
)

Do not forget about target dependencies:

.product(
    name: "DeclarativeConfiguration", 
    package: "swift-declarative-configuration"
)

License

This library is released under the MIT license. See LICENSE for details.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].