├── CONTRIBUTING.md ├── LICENSE └── README.md /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | This guide is primarily intended to be _descriptive_, detailing the usage 2 | that Swift developers at GitHub have arrived at in cases of disagreement. 3 | Consider whether a proposed addition would make more sense in a fork used 4 | by your projects/organization instead. 5 | 6 | If you want to suggest a change or addition that will help accomplish 7 | [the goals](README.md) of this style guide, please open a pull request that: 8 | 9 | 1. Explains the guideline 10 | 1. Demonstrates the guideline with more-or-less valid example code 11 | 1. Justifies the guideline by explaining the rationale behind it 12 | 13 | Just note that all suggestions are open to discussion and debate! :smile: 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This repository is no longer active. 2 | 3 | ---- 4 | 5 | A guide to our Swift style and conventions. 6 | 7 | This is an attempt to encourage patterns that accomplish the following goals (in 8 | rough priority order): 9 | 10 | 1. Increased rigor, and decreased likelihood of programmer error 11 | 1. Increased clarity of intent 12 | 1. Reduced verbosity 13 | 1. Fewer debates about aesthetics 14 | 15 | If you have suggestions, please see our [contribution guidelines](CONTRIBUTING.md), 16 | then open a pull request. :zap: 17 | 18 | ---- 19 | 20 | #### Whitespace 21 | 22 | * Tabs, not spaces. 23 | * End files with a newline. 24 | * Make liberal use of vertical whitespace to divide code into logical chunks. 25 | * Don’t leave trailing whitespace. 26 | * Not even leading indentation on blank lines. 27 | 28 | #### Prefer `let`-bindings over `var`-bindings wherever possible 29 | 30 | Use `let foo = …` over `var foo = …` wherever possible (and when in doubt). Only use `var` if you absolutely have to (i.e. you *know* that the value might change, e.g. when using the `weak` storage modifier). 31 | 32 | _Rationale:_ The intent and meaning of both keywords are clear, but *let-by-default* results in safer and clearer code. 33 | 34 | A `let`-binding guarantees and *clearly signals to the programmer* that its value will never change. Subsequent code can thus make stronger assumptions about its usage. 35 | 36 | It becomes easier to reason about code. Had you used `var` while still making the assumption that the value never changed, you would have to manually check that. 37 | 38 | Accordingly, whenever you see a `var` identifier being used, assume that it will change and ask yourself why. 39 | 40 | #### Return and break early 41 | 42 | When you have to meet certain criteria to continue execution, try to exit early. So, instead of this: 43 | 44 | ```swift 45 | if n.isNumber { 46 | // Use n here 47 | } else { 48 | return 49 | } 50 | ``` 51 | 52 | use this: 53 | ```swift 54 | guard n.isNumber else { 55 | return 56 | } 57 | // Use n here 58 | ``` 59 | 60 | You can also do it with `if` statement, but using `guard` is preferred, because `guard` statement without `return`, `break` or `continue` produces a compile-time error, so exit is guaranteed. 61 | 62 | #### Avoid Using Force-Unwrapping of Optionals 63 | 64 | If you have an identifier `foo` of type `FooType?` or `FooType!`, don't force-unwrap it to get to the underlying value (`foo!`) if possible. 65 | 66 | Instead, prefer this: 67 | 68 | ```swift 69 | if let foo = foo { 70 | // Use unwrapped `foo` value in here 71 | } else { 72 | // If appropriate, handle the case where the optional is nil 73 | } 74 | ``` 75 | 76 | Alternatively, you might want to use Swift's Optional Chaining in some of these cases, such as: 77 | 78 | ```swift 79 | // Call the function if `foo` is not nil. If `foo` is nil, ignore we ever tried to make the call 80 | foo?.callSomethingIfFooIsNotNil() 81 | ``` 82 | 83 | _Rationale:_ Explicit `if let`-binding of optionals results in safer code. Force unwrapping is more prone to lead to runtime crashes. 84 | 85 | #### Avoid Using Implicitly Unwrapped Optionals 86 | 87 | Where possible, use `let foo: FooType?` instead of `let foo: FooType!` if `foo` may be nil (Note that in general, `?` can be used instead of `!`). 88 | 89 | _Rationale:_ Explicit optionals result in safer code. Implicitly unwrapped optionals have the potential of crashing at runtime. 90 | 91 | #### Prefer implicit getters on read-only properties and subscripts 92 | 93 | When possible, omit the `get` keyword on read-only computed properties and 94 | read-only subscripts. 95 | 96 | So, write these: 97 | 98 | ```swift 99 | var myGreatProperty: Int { 100 | return 4 101 | } 102 | 103 | subscript(index: Int) -> T { 104 | return objects[index] 105 | } 106 | ``` 107 | 108 | … not these: 109 | 110 | ```swift 111 | var myGreatProperty: Int { 112 | get { 113 | return 4 114 | } 115 | } 116 | 117 | subscript(index: Int) -> T { 118 | get { 119 | return objects[index] 120 | } 121 | } 122 | ``` 123 | 124 | _Rationale:_ The intent and meaning of the first version are clear, and results in less code. 125 | 126 | #### Always specify access control explicitly for top-level definitions 127 | 128 | Top-level functions, types, and variables should always have explicit access control specifiers: 129 | 130 | ```swift 131 | public var whoopsGlobalState: Int 132 | internal struct TheFez {} 133 | private func doTheThings(things: [Thing]) {} 134 | ``` 135 | 136 | However, definitions within those can leave access control implicit, where appropriate: 137 | 138 | ```swift 139 | internal struct TheFez { 140 | var owner: Person = Joshaber() 141 | } 142 | ``` 143 | 144 | _Rationale:_ It's rarely appropriate for top-level definitions to be specifically `internal`, and being explicit ensures that careful thought goes into that decision. Within a definition, reusing the same access control specifier is just duplicative, and the default is usually reasonable. 145 | 146 | #### When specifying a type, always associate the colon with the identifier 147 | 148 | When specifying the type of an identifier, always put the colon immediately 149 | after the identifier, followed by a space and then the type name. 150 | 151 | ```swift 152 | class SmallBatchSustainableFairtrade: Coffee { ... } 153 | 154 | let timeToCoffee: NSTimeInterval = 2 155 | 156 | func makeCoffee(type: CoffeeType) -> Coffee { ... } 157 | ``` 158 | 159 | _Rationale:_ The type specifier is saying something about the _identifier_ so 160 | it should be positioned with it. 161 | 162 | Also, when specifying the type of a dictionary, always put the colon immediately 163 | after the key type, followed by a space and then the value type. 164 | 165 | ```swift 166 | let capitals: [Country: City] = [sweden: stockholm] 167 | ``` 168 | 169 | #### Only explicitly refer to `self` when required 170 | 171 | When accessing properties or methods on `self`, leave the reference to `self` implicit by default: 172 | 173 | ```swift 174 | private class History { 175 | var events: [Event] 176 | 177 | func rewrite() { 178 | events = [] 179 | } 180 | } 181 | ``` 182 | 183 | Only include the explicit keyword when required by the language—for example, in a closure, or when parameter names conflict: 184 | 185 | ```swift 186 | extension History { 187 | init(events: [Event]) { 188 | self.events = events 189 | } 190 | 191 | var whenVictorious: () -> () { 192 | return { 193 | self.rewrite() 194 | } 195 | } 196 | } 197 | ``` 198 | 199 | _Rationale:_ This makes the capturing semantics of `self` stand out more in closures, and avoids verbosity elsewhere. 200 | 201 | #### Prefer structs over classes 202 | 203 | Unless you require functionality that can only be provided by a class (like identity or deinitializers), implement a struct instead. 204 | 205 | Note that inheritance is (by itself) usually _not_ a good reason to use classes, because polymorphism can be provided by protocols, and implementation reuse can be provided through composition. 206 | 207 | For example, this class hierarchy: 208 | 209 | ```swift 210 | class Vehicle { 211 | let numberOfWheels: Int 212 | 213 | init(numberOfWheels: Int) { 214 | self.numberOfWheels = numberOfWheels 215 | } 216 | 217 | func maximumTotalTirePressure(pressurePerWheel: Float) -> Float { 218 | return pressurePerWheel * Float(numberOfWheels) 219 | } 220 | } 221 | 222 | class Bicycle: Vehicle { 223 | init() { 224 | super.init(numberOfWheels: 2) 225 | } 226 | } 227 | 228 | class Car: Vehicle { 229 | init() { 230 | super.init(numberOfWheels: 4) 231 | } 232 | } 233 | ``` 234 | 235 | could be refactored into these definitions: 236 | 237 | ```swift 238 | protocol Vehicle { 239 | var numberOfWheels: Int { get } 240 | } 241 | 242 | func maximumTotalTirePressure(vehicle: Vehicle, pressurePerWheel: Float) -> Float { 243 | return pressurePerWheel * Float(vehicle.numberOfWheels) 244 | } 245 | 246 | struct Bicycle: Vehicle { 247 | let numberOfWheels = 2 248 | } 249 | 250 | struct Car: Vehicle { 251 | let numberOfWheels = 4 252 | } 253 | ``` 254 | 255 | _Rationale:_ Value types are simpler, easier to reason about, and behave as expected with the `let` keyword. 256 | 257 | #### Make classes `final` by default 258 | 259 | Classes should start as `final`, and only be changed to allow subclassing if a valid need for inheritance has been identified. Even in that case, as many definitions as possible _within_ the class should be `final` as well, following the same rules. 260 | 261 | _Rationale:_ Composition is usually preferable to inheritance, and opting _in_ to inheritance hopefully means that more thought will be put into the decision. 262 | 263 | 264 | #### Omit type parameters where possible 265 | 266 | Methods of parameterized types can omit type parameters on the receiving type when they’re identical to the receiver’s. For example: 267 | 268 | ```swift 269 | struct Composite { 270 | … 271 | func compose(other: Composite) -> Composite { 272 | return Composite(self, other) 273 | } 274 | } 275 | ``` 276 | 277 | could be rendered as: 278 | 279 | ```swift 280 | struct Composite { 281 | … 282 | func compose(other: Composite) -> Composite { 283 | return Composite(self, other) 284 | } 285 | } 286 | ``` 287 | 288 | _Rationale:_ Omitting redundant type parameters clarifies the intent, and makes it obvious by contrast when the returned type takes different type parameters. 289 | 290 | #### Use whitespace around operator definitions 291 | 292 | Use whitespace around operators when defining them. Instead of: 293 | 294 | ```swift 295 | func <|(lhs: Int, rhs: Int) -> Int 296 | func <|<(lhs: A, rhs: A) -> A 297 | ``` 298 | 299 | write: 300 | 301 | ```swift 302 | func <| (lhs: Int, rhs: Int) -> Int 303 | func <|< (lhs: A, rhs: A) -> A 304 | ``` 305 | 306 | _Rationale:_ Operators consist of punctuation characters, which can make them difficult to read when immediately followed by the punctuation for a type or value parameter list. Adding whitespace separates the two more clearly. 307 | 308 | #### Translations 309 | 310 | * [中文版](https://github.com/Artwalk/swift-style-guide/blob/master/README_CN.md) 311 | * [日本語版](https://github.com/jarinosuke/swift-style-guide/blob/master/README_JP.md) 312 | * [한국어판](https://github.com/minsOne/swift-style-guide/blob/master/README_KR.md) 313 | * [Versión en Español](https://github.com/antoniosejas/swift-style-guide/blob/spanish/README-ES.md) 314 | * [Versão em Português do Brasil](https://github.com/fernandocastor/swift-style-guide/blob/master/README-PTBR.md) 315 | * [فارسی](https://github.com/mohpor/swift-style-guide/blob/Persian/README-FA.md) 316 | --------------------------------------------------------------------------------