Skip to content

Commit c93ee5a

Browse files
committed
add my swift style ideas
1 parent 0c2c83b commit c93ee5a

File tree

1 file changed

+195
-0
lines changed

1 file changed

+195
-0
lines changed

swift.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,198 @@
22

33
*Swift*
44

5+
# Swift Style Guide
6+
7+
* capitalize constants, and prefer putting them in the top level of a class if they are private. If they are public, put the constant as a static property, so we get nice namespaces.
8+
```swift
9+
private let PrivateValue = "secret"
10+
11+
class MyClass {
12+
static let PublicValue = "something"
13+
14+
func doSomething() {
15+
print(MaxTime)
16+
}
17+
}
18+
```
19+
20+
* always use “self” for properties. Don’t use it for methods.
21+
```swift
22+
class MyClass {
23+
var aProp: Int
24+
25+
func doSomething() {
26+
// WRONG
27+
aProp = 4
28+
29+
// RIGHT
30+
self.aProp = 4
31+
32+
// WRONG
33+
self.otherMethod()
34+
35+
// RIGHT
36+
otherMethod()
37+
}
38+
}
39+
```
40+
41+
* Try to initialize properties in the init() method whenever possible, rather than using implicitly unwrapped optionals. (Notable exception is UIViewController.)
42+
```swift
43+
// WRONG
44+
class MyClass: NSObject {
45+
var someValue: Int!
46+
init() {
47+
super.init()
48+
someValue = 5
49+
}
50+
}
51+
52+
// RIGHT
53+
class MyClass: NSObject {
54+
var someValue: Int
55+
init() {
56+
someValue = 0
57+
super.init()
58+
}
59+
}
60+
```
61+
62+
* Use functions instead of computed properties if they get to be complicated. Also avoid didSet and willSet for the same reason.
63+
```swift
64+
// WRONG
65+
// this is less readable
66+
class MyClass {
67+
var someValue: Int {
68+
get {
69+
// return something computed
70+
}
71+
set(newValue) {
72+
// set a bunch of other values
73+
}
74+
}
75+
}
76+
77+
// RIGHT
78+
// easier to read more clear that there are side effects of setting
79+
class MyClass {
80+
func someValue() {
81+
}
82+
83+
func setSomeValue() {
84+
}
85+
}
86+
```
87+
* Separate long function names on each argument and put the open curly on the next line so the body is indented correctly.
88+
```swift
89+
class MyClass {
90+
// WRONG
91+
func doSomething(arg: Int, anotherArg: Int, yetAnotherArg: Int, andOneMoreArgForGoodMeasure: String) {
92+
// This is just too long and will probably auto-wrap in a weird way
93+
}
94+
95+
// WRONG
96+
func doSomething(arg: Int,
97+
anotherArg: Int,
98+
yetAnotherArg: Int,
99+
andOneMoreArgForGoodMeasure: String) {
100+
// XCode will indent the body an extra level in
101+
}
102+
103+
func doSomething(
104+
arg: Int,
105+
anotherArg: Int,
106+
yetAnotherArg: Int,
107+
andOneMoreArgForGoodMeasure: String)
108+
{
109+
// Will cause correct level of indentation
110+
}
111+
}
112+
```
113+
114+
* Avoid large callback blocks - instead organize them into methods. This makes weak-self in blocks much simpler.
115+
```swift
116+
// WRONG
117+
class MyClass {
118+
func doRequest(completion: () -> Void) {
119+
API.request() { response in
120+
// lots of processing and whatever
121+
completion()
122+
}
123+
}
124+
}
125+
126+
// RIGHT
127+
class MyClass {
128+
func doRequest(completion: () -> Void) {
129+
API.request() { response in
130+
self.processResponse(response)
131+
completion()
132+
}
133+
}
134+
135+
func processResponse(response) {
136+
// do actual processing here
137+
}
138+
}
139+
```
140+
141+
* Guard
142+
* Only add to top of functions. Goal of guard is to reduce branch complexity and in some ways adding guard statements in the middle of a chunk of code increases complexity
143+
144+
* How do we deal with multiple let clauses in an if clause?
145+
```swift
146+
// This feels weird, but is how autoindent works right now in XCode
147+
if
148+
let val1 = val1,
149+
let val2 = val2
150+
where !val2.isEmpty {
151+
print(val2)
152+
}
153+
154+
// Putting the first let on the same line as the if makes the body indent an extra level
155+
// This also looks kind of gross
156+
if let val1 = val1,
157+
let val2 = val2
158+
where !val2.isEmpty {
159+
print(val2)
160+
}
161+
```
162+
* Don’t include return type Void in blocks even though that’s what autocomplete does
163+
```swift
164+
// WRONG
165+
someAsyncThing() { argument -> Void in ... }
166+
167+
// RIGHT
168+
someAsyncThing() { argument in ... }
169+
```
170+
171+
* prefer immutable values whenever possible. use map and flatmap instead of appending to a new array. mutable variables increase complexity, so try to keep them in as small a scope as possible if you have to use them.
172+
```swift
173+
// WRONG
174+
var results = []
175+
for element in input {
176+
let result = transform(element)
177+
results.append(result)
178+
}
179+
180+
// RIGHT
181+
let results = input.map(transform)
182+
183+
// WRONG
184+
func doSomething() {
185+
var someHash = getHashFromSomewhere()
186+
someHash["someNewKey"] = someComputation()
187+
doSomethingWithHash(someHash)
188+
}
189+
190+
// RIGHT
191+
func doSomething() {
192+
let someHash = getHashFromSomewhere()
193+
let modifiedHash = modifyHash(someHash)
194+
doSomethingWithHash(modifiedHash)
195+
}
196+
```
197+
* Avoid using optionals unless there’s a good semantic meaning.
198+
199+

0 commit comments

Comments
 (0)