Giter Club home page Giter Club logo

swift-style-guide's People

Contributors

dennda avatar hirohisa avatar hiroyuki0115 avatar jarinosuke avatar joshaber avatar jspahrsummers avatar kevindeleon avatar mdiep avatar minsone avatar morizotter avatar rhysforyou avatar robb avatar robrix avatar sboddeus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swift-style-guide's Issues

Using lazy closures for thread safe property composition

I've been thrashing through this idiom recently so it's not explicitly a 'pure swift' thing but more of a good way to encapsulate logic within a particular component.

Say you have a text field and you want to perform a stack of modifications to it, you have two ways to do this

func myCoolFunc() {
    let textField = TextField(rect: CGRectZero)
    label.attributedPlaceholder = ...
    textField.attributedText = 
    textField.delegate = self (or some other class)
}

The problem being that what if myCoolFunc is called more than once, this is why you can use lazily evaluated closures on properties to guarantee they'll only be initialized once (and also they give you a convenient way to store item centric logic

lazy var myTextField : UITextField = {
    let textField = TextField(rect: CGRectZero)
    label.attributedPlaceholder = ...
    textField.attributedText = 
    textField.delegate = self (or some other class)
    return textField
}()

IIRC lazy attributes/properties are de facto thread-safe and lazy closures are only executed ONCE meaning you get a decoupling of your property elements from your actual imperative code (if you're exclusively laying out in code). Something I've been mulling over but something I think is a good addition to the guide. Happy to discuss with others.

Prefer immutability

This comes out of some discussion that maybe "Prefer let-bindings over var-bindings wherever possible" doesn't make sense as a guideline when the compiler already generates warnings for that as of Swift 2. After talking it over with @sboddeus we decided that it's still probably valuable as a guideline if it's rephrased as something along the lines of "prefer immutability over mutability wherever possible".

Using extensions for protocol/delegate conformance

This is another kind of idiomatic Swift trick that again allows you to decouple certain implementations from your existing structures or classes. The best example is you might have a common view controller that you decide to add a map view to, but you only want to add annotations. Rather than having your class conform to the protocol, have an extension on your class conform

So rather than

class MyCoolViewController : UIViewController, MKMapViewDelegate
{
//my cool class goes here
}

We do the following definition

//regular class
class MyCoolViewController : UIViewController
{
 //my wicked sick class goes here
}

extension MyCoolViewController : MKMapViewDelegate
{
  //delegate conformance goes here
}

What you end up getting from this is a) separation of concerns, but b) locality of concerns, it's also a great way to extend and adapt a particular class if you're getting to code smell lengths of fat view controllers and need to add functionality (or want to expand existing Obj-C view controllers but want to use swell as heck Swift for building upon your existing apps)

Method chaining

I often find myself chaining functions like map, filter, and reduce like so:

let totalSize = fileInfos
    .map { fileInfo in
        if (isSymlink(fileInfo) {
            return resolveSymlink(fileInfo)
        }
        return fileInfo
    }
    .flatMap { $0[NSFileSize] as? CUnsignedLongLong }
    .reduce(0, combine: +)

This is something I picked up from working on D3.js projects, and I find it aids readability when dealing with this style of function chaining.

In discussing this style of chaining methods in the Slack chat, @sboddeus brought up a good point that this seems to go against our recommendations for if/else statements. In that case, we advise that the else goes on the same line as the if statements closing brace like so:

if {
    // ...
} else {
    // ...
}

Following this precedent, our chaining would look like this:

let totalSize = fileInfos.map { fileInfo in
        if (isSymlink(fileInfo) {
            return resolveSymlink(fileInfo)
        }
        return fileInfo
    }.flatMap { 
        $0[NSFileSize] as? CUnsignedLongLong
    }.reduce(0, combine: +)

which doesn't look nearly as readable to me, but is worth considering for sakes of consistency.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.