Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.

Commit 6dc14c1

Browse files
author
Kerr Marin Miller
committed
Update based on comments from PR
1 parent 7f2dffc commit 6dc14c1

File tree

1 file changed

+58
-70
lines changed

1 file changed

+58
-70
lines changed

swift/README.md

Lines changed: 58 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ Our overarching goals are conciseness, readability, and simplicity.
1515
* [Prose](#prose)
1616
* [Selectors](#selectors)
1717
* [Generics](#generics)
18-
* [Class Prefixes](#class-prefixes)
1918
* [Language](#language)
2019
* [Code Organization](#code-organization)
2120
* [Protocol Conformance](#protocol-conformance)
@@ -43,6 +42,7 @@ Our overarching goals are conciseness, readability, and simplicity.
4342
* [Extending Lifetime](#extending-lifetime)
4443
* [Access Control](#access-control)
4544
* [Control Flow](#control-flow)
45+
* [Error Handling](#error-handling)
4646
* [Golden Path](#golden-path)
4747
* [Failing Guards](#failing-guards)
4848
* [Semicolons](#semicolons)
@@ -60,10 +60,6 @@ Consider warnings to be errors. This rule informs many stylistic decisions such
6060

6161
## Naming
6262

63-
Clarity at the point of use is your most important goal. Entities such as methods and properties are declared only once but used repeatedly. Design APIs to make those uses clear and concise. When evaluating a design, reading a declaration is seldom sufficient; always examine a use case to make sure it looks clear in context.
64-
65-
Clarity is more important than brevity. Although Swift code can be compact, it is a non-goal to enable the smallest possible code with the fewest characters. Brevity in Swift code, where it occurs, is a side-effect of the strong type system and features that naturally reduce boilerplate.
66-
6763
Use descriptive names with camel case for classes, methods, variables, etc. Type names (classes, structures, enumerations and protocols) should be capitalized, while method names and variables should start with a lower case letter.
6864

6965
**Preferred:**
@@ -92,15 +88,15 @@ Abbreviations and acronyms should generally be avoided. Following the [API Desig
9288

9389
**Preferred**
9490
```swift
95-
let utf8String: String
96-
let urlString: URLString
91+
let utf8Text: String
92+
let targetURL: URL
9793
let userID: UserID
9894
```
9995

10096
**Not Preferred**
10197
```swift
102-
let UTF8String: String
103-
let uRLString: UrlString
98+
let UTF8Text: String
99+
let uRLText: UrlString
104100
let userId: UserId
105101
```
106102

@@ -157,16 +153,6 @@ When referring to functions in comments include the required parameter names fro
157153
158154
This is the same as the `#selector` syntax. When in doubt, look at how Xcode lists the method in the jump bar – our style here matches that.
159155

160-
### Class Prefixes
161-
162-
Swift types are automatically namespaced by the module that contains them and you should not add a class prefix such as MOB. If two names from different modules collide you can disambiguate by prefixing the type name with the module name. However, only specify the module name when there is possibility for confusion which should be rare.
163-
164-
```swift
165-
import SomeModule
166-
167-
let myClass = MyModule.UsefulClass()
168-
```
169-
170156
### Selectors
171157

172158
Selectors are Obj-C methods that act as handlers for many Cocoa and Cocoa Touch APIs. Prior to Swift 2.2, they were specified using type unsafe strings. This now causes a compiler warning. The "Fix it" button replaces these strings with the **fully qualified** type safe selector. Often, however, you can use context to shorten the expression. This is the preferred style.
@@ -254,6 +240,13 @@ For UIKit view controllers, consider grouping lifecycle, custom accessors, and I
254240

255241
Unused (dead) code, including Xcode template code and placeholder comments should be removed. Aspirational methods whose implementation simply calls the super class should also be removed.
256242

243+
**Preferred:**
244+
```swift
245+
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
246+
return Database.contacts.count
247+
}
248+
```
249+
257250
**Not Preferred:**
258251
```swift
259252
override func didReceiveMemoryWarning() {
@@ -273,13 +266,6 @@ override func tableView(tableView: UITableView, numberOfRowsInSection section: I
273266

274267
```
275268

276-
**Preferred:**
277-
```swift
278-
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
279-
return Database.contacts.count
280-
}
281-
```
282-
283269
### Minimal Imports
284270

285271
Keep imports minimal. For example, don't import `UIKit` when importing `Foundation` will suffice.
@@ -360,7 +346,8 @@ Here's an example of a well-styled class definition:
360346

361347
```swift
362348
class Circle: Shape {
363-
var x: Int, y: Int
349+
var x: Int
350+
var y: Int
364351
var radius: Double
365352
var diameter: Double {
366353
get {
@@ -406,7 +393,7 @@ The example above demonstrates the following style guidelines:
406393

407394
For conciseness, avoid using `self` since Swift does not require it to access an object's properties or invoke its methods.
408395

409-
Use `self` when required to differentiate between property names and arguments in initializers, and when referencing properties in closure expressions (as required by the compiler):
396+
Use `self` when required to differentiate between property names and arguments in initializers, and when referencing properties or methods in closure expressions (as required by the compiler):
410397

411398
```swift
412399
class BoardLocation {
@@ -576,14 +563,14 @@ Always use Swift's native types when available. Swift offers bridging to Objecti
576563

577564
**Preferred:**
578565
```swift
579-
let width = 120.0 // Double
580-
let widthString = (width as NSNumber).stringValue // String
566+
let width = 120.0 // Double
567+
let labelText = (width as NSNumber).stringValue // String
581568
```
582569

583570
**Not Preferred:**
584571
```swift
585-
let width: NSNumber = 120.0 // NSNumber
586-
let widthString: NSString = width.stringValue // NSString
572+
let width: NSNumber = 120.0 // NSNumber
573+
let labelText: NSString = width.stringValue // NSString
587574
```
588575

589576
### Constants
@@ -602,7 +589,6 @@ enum Math {
602589
}
603590

604591
radius * Math.pi * 2 // circumference
605-
606592
```
607593
**Note:** The advantage of using a case-less enumeration is that it can't accidentally be instantiated and works as a pure namespace.
608594

@@ -624,55 +610,55 @@ class Component {
624610

625611
### Static Methods and Variable Type Properties
626612

627-
Static methods and type properties work similarly to global functions and global variables and should be used sparingly. They are useful when functionality is scoped to a particular type or when Objective-C interoperability is required.
613+
Static methods and type properties work similarly to free functions and global variables and should be used sparingly. They are useful when functionality is scoped to a particular type or when Objective-C interoperability is required.
628614

629615
### Optionals
630616

631617
Declare variables and function return types as optional with `?` where a nil value is acceptable.
632618

633-
Use implicitly unwrapped types declared with `!` only for instance variables that you know will be initialized later before use, such as subviews that will be set up in `viewDidLoad`. Other cases you shoudl use `!` are:
619+
Use implicitly unwrapped types declared with `!` only for instance variables that you know will be initialized later before use, such as subviews that will be set up in `viewDidLoad`. Other cases you should use `!` are:
634620

635621
- You just assigned to an object where you know initialization can not fail:
636622

637-
```swift
638-
let numberSeven = Int("7")! //Don't do this.
639-
```
623+
```swift
624+
let numberSeven = Int("7")! //Don't do this.
625+
```
640626

641-
In this case, wrap this into a static function and write a test for it:
627+
In this case, wrap this into a static function and write a test for it:
642628

643-
```swift
644-
extension Int {
645-
static func seven() -> Int {
646-
return Int("7")!
647-
}
648-
}
649-
```
629+
```swift
630+
extension Int {
631+
static func seven() -> Int {
632+
return Int("7")!
633+
}
634+
}
635+
```
650636

651-
```swift
652-
import XCTest
637+
```swift
638+
import XCTest
653639

654-
class IntegerTests: XCTestCase {
655-
func testSeven() {
656-
XCTAssertEqual(7, Int.seven())
657-
}
658-
}
659-
```
640+
class IntegerTests: XCTestCase {
641+
func testSeven() {
642+
XCTAssertEqual(7, Int.seven())
643+
}
644+
}
645+
```
660646

661-
Although the test might seem redundant, because `seven()` returns a non-optional, this ensures that even if in the future someone changes the implementation of `seven()`, it won't get past CI if the explicit unwrapping would fail.
647+
Although the test might seem redundant, because `seven()` returns a non-optional, this ensures that even if in the future someone changes the implementation of `seven()`, it won't get past CI if the explicit unwrapping would fail.
662648

663649
- You are creating an object during initialization but need to pass `self` to that object's initializer:
664650

665-
```swift
666-
class Component: ParentComponent {
667-
var controller: CustomViewController! // We want to use it as a non-optional but have to initialize after super.init()
651+
```swift
652+
class Component: ParentComponent {
653+
var controller: CustomViewController! // We want to use it as a non-optional but have to initialize after super.init()
668654

669-
override init() {
670-
// controller = CustomViewController(component: self) <-- compiler error
671-
super.init()
672-
controller = CustomViewController(component: self)
673-
}
674-
}
675-
```
655+
override init() {
656+
// controller = CustomViewController(component: self) <-- compiler error
657+
super.init()
658+
controller = CustomViewController(component: self)
659+
}
660+
}
661+
```
676662

677663
When accessing an optional value, use optional chaining if the value is only accessed once or if there are many optionals in the chain:
678664

@@ -771,12 +757,12 @@ let maximumWidth: CGFloat = 106.5
771757
```swift
772758
let message: String = "Click the button"
773759
let currentBounds: CGRect = computeViewBounds()
774-
let names = [String]()
760+
let names: [String] = ["Mic", "Sam", "Christine"]
775761
```
776762

777763
#### Type Annotation for Empty Arrays and Dictionaries
778764

779-
For empty arrays and dictionaries, use type annotation. (For an array or dictionary assigned to a large, multi-line literal, use type annotation.)
765+
For empty arrays and dictionaries, use type annotation. (For an array or dictionary assigned to a large, multi-line literal, use type annotation to make it clear what type(s) the array/dictionary contains)
780766

781767
**Preferred:**
782768
```swift
@@ -873,7 +859,9 @@ resource.request().onComplete { [weak self] response in
873859

874860
## Access Control
875861

876-
Full access control annotation in tutorials can distract from the main topic and is not required. Using `private` appropriately, however, adds clarity and promotes encapsulation. Use `private` as the leading property specifier. The only things that should come before access control are the `static` specifier or attributes such as `@IBAction` and `@IBOutlet`.
862+
Using `private` appropriately adds clarity and promotes encapsulation. Use `private` as the leading property specifier. The only things that should come before access control are the `static` specifier or attributes such as `@IBAction` and `@IBOutlet`.
863+
864+
An exception to this is RPC methods within Astro, which should be marked as `internal`.
877865

878866
**Preferred:**
879867
```swift
@@ -929,6 +917,8 @@ while i < attendeeList.count {
929917
}
930918
```
931919

920+
## Error Handling
921+
932922
As of Swift 2.0 exceptions have been introduced into the language and the APIs that formerly used `someMethod(..., error: *NSError)` make use of them. We have decided to stick with our existing pattern for returning errors.
933923

934924
We typically use an enumeration type:
@@ -1024,8 +1014,6 @@ Swift does not require a semicolon after each statement in your code. They are o
10241014

10251015
Do not write multiple statements on a single line separated with semicolons.
10261016

1027-
The only exception to this rule is the `for-conditional-increment` construct, which requires semicolons. However, alternative `for-in` constructs should be used where possible.
1028-
10291017
**Preferred:**
10301018
```swift
10311019
let swift = "not a scripting language"

0 commit comments

Comments
 (0)