1.allSatisfy – checks if the collection satisfies the condition
Since Swift 4.2 we have the allSatisfy () method for collections (array, set, …). This function accepts a condition, and returns true if all of the items in that collection meet this condition.
For example, we have the following array to hold the test scores of a class:
1 2 |
<span class="token keyword">let</span> scores <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token number">5</span> <span class="token punctuation">,</span> <span class="token number">8</span> <span class="token punctuation">,</span> <span class="token number">7</span> <span class="token punctuation">,</span> <span class="token number">9</span> <span class="token punctuation">,</span> <span class="token number">10</span> <span class="token punctuation">]</span> |
Assuming 5 points are sufficient to pass the subject, we can check if all students in the class passed by:
1 2 |
<span class="token keyword">let</span> passed <span class="token operator">=</span> scores <span class="token punctuation">.</span> allSatisfy <span class="token punctuation">{</span> $ <span class="token number">0</span> <span class="token operator">>=</span> <span class="token number">5</span> <span class="token punctuation">}</span> <span class="token comment">// true</span> |
2. Public getter, private setter
Access control is a great feature of swift. Maybe you also use access controls like public and private for class properties to control code elsewhere to access these properties, and make the purpose of our code clearer. But did you know that we can use two types of access controls at the same time. See the following example:
We have a struct named Bank:
1 2 3 4 |
<span class="token keyword">struct</span> <span class="token builtin">Bank</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> address <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">}</span> |
Then we instantiate an instance of this struct:
1 2 |
<span class="token keyword">let</span> richBank <span class="token operator">=</span> <span class="token function">Bank</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> |
We do not use any access control with the property address , which means that code everywhere can read and change the address value of richBank . If we use private for address, the code elsewhere cannot change or read its value.
However, there will be times when you want code elsewhere to be able to read the address value, but only internally richBank can change the value of this property. Swift provides a very easy way to do this: public private (set) .
Using this syntax, a property can be read anywhere, but can only be changed internally. Specifically, in our example, anyone can read the richBank address, but only richBank itself can change its address.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span class="token keyword">struct</span> <span class="token builtin">Bank</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">private</span> <span class="token punctuation">(</span> <span class="token keyword">set</span> <span class="token punctuation">)</span> <span class="token keyword">var</span> address <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token keyword">public</span> <span class="token keyword">mutating</span> <span class="token keyword">func</span> <span class="token function">setAddress</span> <span class="token punctuation">(</span> newAddress <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> address <span class="token operator">=</span> newAddress <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> richBank <span class="token operator">=</span> <span class="token function">Bank</span> <span class="token punctuation">(</span> adress <span class="token punctuation">:</span> <span class="token string">"Rich Street"</span> <span class="token punctuation">)</span> <span class="token function">print</span> <span class="token punctuation">(</span> richBank <span class="token punctuation">.</span> address <span class="token punctuation">)</span> <span class="token comment">// Rich Street</span> richBank <span class="token punctuation">.</span> address <span class="token operator">=</span> <span class="token string">"Poor Street"</span> <span class="token comment">// Error</span> richBank <span class="token punctuation">.</span> <span class="token function">setAddress</span> <span class="token punctuation">(</span> <span class="token string">"Poor Street"</span> <span class="token punctuation">)</span> <span class="token comment">// OK</span> |
3. Static vs class properties
Class properties in Swift can be created using one of two keywords: static and class .
Both make the property a common property in every instance of the class, but the static keyword is final , ie a property created with a static keyword cannot override the subclass.
For example, we could create a Building class that has a class property that holds the address, and a static property that holds the names of the people who own this Building:
1 2 3 4 5 6 7 8 9 10 |
<span class="token keyword">class</span> <span class="token class-name">Building</span> <span class="token punctuation">{</span> <span class="token keyword">class</span> <span class="token class-name">var</span> address <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"Awesome Street"</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> <span class="token keyword">var</span> owners <span class="token punctuation">:</span> <span class="token punctuation">[</span> <span class="token builtin">String</span> <span class="token punctuation">]</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span> <span class="token string">"Good leader"</span> <span class="token punctuation">,</span> <span class="token string">"Evil boss"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Because address is a class property, it can be changed by the subsclass of the Building. In contrast, owners are a static property that cannot be changed in subclasses.
1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="token keyword">class</span> <span class="token class-name">Villa</span> <span class="token punctuation">:</span> <span class="token builtin">Building</span> <span class="token punctuation">{</span> <span class="token comment">// Có thể override được class var</span> <span class="token keyword">override</span> <span class="token keyword">class</span> <span class="token class-name">var</span> address <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> “ <span class="token builtin">Not</span> <span class="token operator">-</span> that <span class="token operator">-</span> awesome <span class="token builtin">Street</span> <span class="token punctuation">}</span> <span class="token comment">// Nhưng không được phép override static var</span> <span class="token keyword">override</span> <span class="token keyword">static</span> <span class="token keyword">var</span> owners <span class="token punctuation">:</span> <span class="token punctuation">[</span> <span class="token builtin">String</span> <span class="token punctuation">]</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">[</span> “ <span class="token builtin">Grandma</span> ” <span class="token punctuation">,</span> “ <span class="token builtin">Grandpa</span> ” <span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token comment">// Error</span> <span class="token punctuation">}</span> |
4. == vs. ===
In Swift there is a protocol named Equatable . When a type applies this protocol, we can use operator “==” to check if the 2 values of that type are the same. For example:
1 2 3 4 |
<span class="token number">1</span> <span class="token operator">==</span> <span class="token number">1</span> <span class="token comment">// true</span> “kayak” <span class="token operator">==</span> <span class="token function">String</span> <span class="token punctuation">(</span> “kayak” <span class="token punctuation">.</span> <span class="token function">reversed</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token comment">// true</span> <span class="token punctuation">[</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">4</span> <span class="token punctuation">,</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> <span class="token builtin">map</span> <span class="token punctuation">{</span> $ <span class="token number">0</span> <span class="token operator">*</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token comment">// true</span> |
When you create a new type, you just need to apply the Equatable protocol to use ==. However, if you use a class and want to compare two instances of the class against each other, you have one more option.
Because a class instance is just a reference to that class’s address in memory, you can use operator === to check if two instances of the same class point to the same address.
1 2 3 4 5 6 7 8 9 10 11 12 |
<span class="token keyword">class</span> <span class="token class-name">Lightsaber</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> color <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token operator">!</span> <span class="token keyword">init</span> <span class="token punctuation">(</span> color <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> color <span class="token operator">=</span> color <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">let</span> firstSaber <span class="token operator">=</span> <span class="token function">Lightsaber</span> <span class="token punctuation">(</span> color <span class="token punctuation">:</span> “ <span class="token builtin">Blue</span> ” <span class="token punctuation">)</span> <span class="token keyword">let</span> secondSaber <span class="token operator">=</span> firstSaber <span class="token function">print</span> <span class="token punctuation">(</span> firstSaber <span class="token operator">===</span> secondSaber <span class="token punctuation">)</span> <span class="token comment">// true</span> |
You can see that the above class does not need to apply the Equatable protocol but is still able to compare the instances. === is also known as the identity operator.
5. Create default value for protocol property using extension
We all know we can create a default implementation for a method of the protocol using an extension . However, we can also use the extension to assign default values to protocol properties .
For example, we could create a protocol called Fadeable that will obscure the view for a few seconds:
1 2 3 4 5 |
<span class="token keyword">protocol</span> <span class="token builtin">Fadeable</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> fadeSpeed <span class="token punctuation">:</span> <span class="token builtin">TimeInterval</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">fadeOut</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Instead of having each type apply this protocol add values for the fadeSpeed and implement the fadeOut () method, we can set default values for both in the extension:
1 2 3 4 5 6 7 8 9 10 11 |
<span class="token keyword">extension</span> <span class="token builtin">Fadeable</span> <span class="token keyword">where</span> <span class="token keyword">Self</span> <span class="token punctuation">:</span> <span class="token builtin">UIView</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> fadeSpeed <span class="token punctuation">:</span> <span class="token builtin">TimeInterval</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token number">1.0</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">fadeOut</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token builtin">UIView</span> <span class="token punctuation">.</span> <span class="token function">animate</span> <span class="token punctuation">(</span> withDuration <span class="token punctuation">:</span> fadeSpeed <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span> <span class="token punctuation">.</span> apha <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Then, we can let our subclass apply this protocol without having to rewrite the defaults listed above:
1 2 |
<span class="token keyword">class</span> <span class="token class-name">MyViewClass</span> <span class="token punctuation">:</span> <span class="token builtin">UIView</span> <span class="token punctuation">,</span> <span class="token builtin">Fadeable</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> |
Above are 5 quick and useful tips in Swift. Hope my articles can help you code more effectively.