Swift Preserving Structure Default Initializer using Extensions is explained in the below video tutorial. Hope it helps.
Saturday, October 9, 2021
Swift defer statement
Swift defer statement is explained in the below video tutorial. Hope it helps.
Swift Stored Properties
Swift Stored properties are explained in the below video tutorial. Hope it helps.
Swift Lazy Stored Properties
Swift Lazy Stored properties are explained in the below video tutorial. Hope it helps.
Swift Higher Order Functions
Higher-order functions in swift are explained in the below video tutorial. Hope it helps.
Thursday, October 3, 2019
Custom cell class datasource in MVVM design pattern
We generally pass a model to cell to configure/render and the reason behind it is, instead of passing multiple parameters, we can have a model to be passed as parameter.
Let’s take a below cell for example which is having 4 labels and in MVVM design pattern, viewmodels build and gives model to cell in cellForRowAt in viewcontroller.
This seems/sounds familiar as this is what we have been doing.
But, there are flaws in this approach.
- What If I want to reuse the cell?
- In MVVM design pattern view(in this case cell) should not hold a model(Agree?)
I can not reuse the cell efficiently as this cell is tightly coupled with a model.
First in place, this poor cell is having 4 labels and technically needs 4 stings to display. As simple as that. Isn’t it?
Then why to pass a model and create a tight coupling.
Instead of passing a model, Cell can have a datasource implemented like below.
Now cell configuration happens based on the ProductCellDataSource protocol. That means any model that confirms to this protocol can be passed to cell configure method to render the cell.
In other words, cell is just asking to send me the data as per my protocol and it is saying I am not literally worried about the model you are sending as long as it confirms to my datasource protocol.
With this approach, cell will not have any tight coupling with models(MVVM basic rule) and it can be reused by passing any model which confirms to it’s datasource protocol.
Hope this post is useful. Feel free to comment incase of any queries.
Labels:
configure,
coupling,
custom,
datasource,
design pattern,
ios,
loose,
model,
MVVM,
protocol,
render,
reuse,
swift,
tight,
UITableViewCell,
ViewModel
Wednesday, September 26, 2018
Swift - Multiple levels of Optional Binding
If there is Optional, We tend to bind them using guard or if let multiple levels which should be based on what we need exactly.
class Person {
var name: String?
weak var spouse: Person?
init(name: String) {
self.name = name
}
}
let wife = Person(name: "Wife")
let husband = Person(name: "Husband")
wife.spouse = husband
husband.spouse = wife
I need to display spouse name in a label.
We don’t need two bindings like below.
if let spouse = husband.spouse,
let name = spouse.name {
let name = spouse.name {
lblSpouseName.text = name
}
Cause, We are not using binded spouse(let spouse = husband.spouse) object. We are using only minded spouse name(let name = spouse.name)
As here what we need is only spouse name, We can take help of optional chaining in optional binding.
if let name = husband.spouse?.name {
lblSpouseName.text = name
}
husband.spouse?.name is optional chaining and gives value only If husband’s spouse is not nil and spouse name is also not nil.
That’s how we need to use binding for the things we need in the scope of If let or guard let.
In the above case, Coalescing operator works like charm and best fit where we can give a default value as well.
lblSpouseName.text = husband.spouse?.name ?? "NA"
Hope this post is useful. Feel free to comment incase of any queries.
Swift - App is currently in Main Thread or not
At any point of time, we can check whether we are in main thread or not.
if Thread.current.isMainThread {
print("isMainThread")
}
This is useful for generic UI operations for async calls.
Suppose, we are need to display generic alerts for network errors and we wrote a common method for that,
func networkError() {
//stop loader
//display alert
}
Some developers forget to write UI calls on main thread in network calls.
let task = URLSession.shared.dataTask
(with: url) { ( data, responseData, error) in
(with: url) { ( data, responseData, error) in
if error != nil {
networkError()
}
}
So, We can check whether we are in main thread or not in networkError() method and do UI stuff like shown below.
func networkError() {
if Thread.current.isMainThread {
//stop loader
//display alert
} else {
DispatchQueue.main.async {
//stop loader
//display alert
}
}
}
Hope this post is useful. Feel free to comment incase of any queries.
Labels:
async,
current,
ios,
isMainThread,
main thread,
swift,
sync,
Thread
Friday, September 14, 2018
fileprivate to private
In Swift 3, If we need to access private stuff of a class in extension, we need to change the access specifier from private to fileprivate.
class User {
private var name: String
private var id: Int
init(name: String, id: Int) {
self.name = name
self.id = id
}
private var greeting: String {
get {
return "Hi \(name)"
}
set(v) {
name = v
}
}
}
extension User {
func greetUser() {
print(greeting)
}
}
Swift 3 gives build error for below as greeting is private.
extension User {
func greetUser() {
print(greeting)
}
}
It should be marked as fileprivate which makes it accessible to others which are inside a file which may not be we wanted most of the times.
Swift 4, makes it appropriate based on their name.
private is not at all accessible outside even with in the same file.
fileprivate is accessible only with in the file, Not accessible outside of a file.
If greeting is with in the same file where User class is there, It doesn’t matter If it’s fileprivate or private to access it in a User extension with in the same file. But, careful with fileprivate cause it is accessible with in the same file.
class User {
private var name: String
private var id: Int
init(name: String, id: Int) {
self.name = name
self.id = id
}
fileprivate var greeting: String {
get {
return "Hi \(name)"
}
set(v) {
name = v
}
}
}
extension User {
func greetUser() {
print(greeting)
}
}
If you are writing extension of User in another file, You can not access it If it’s fileprivate or private.
Extension outside of file,
extension User {
func greetUser() {
print(greeting)
}
}
fileprivate build error - 'greeting' is inaccessible due to 'fileprivate' protection level
private build error - 'greeting' is inaccessible due to 'private' protection level
That’s how Swift 4, make both the access specifiers clear based on their name.
Glad, It’s not confusing now like in Swift 3.
Swift 3, fileprivate - If you need access throughout the file even in extensions (private gives build error in extensions)
Swift 3, private - Not accessible outside the model scope even in the extension which is there in same file.
Swift 4, fileprivate - If you need access throughout the file.
Swift 4, private - Accessible in extensions If they are in the same file. Not accessible for all remaining cases.
Take Aways -
In Swift 4, We don’t need to change fileprivate access for a property/method to private to access that in the extension in the same file.
Hope this post is useful. Feel free to comment incase of any queries.
Wednesday, August 29, 2018
Swift Nil-Coalescing Operator for Optionals
Let’s see how to use Coalescing operator for optionals in swift.
var name: String?
label.text = name ?? ""
Here ?? is the Coalescing operator which checks whether optional is nil or not.
If Nil, takes default value, If not takes optional.
In short, below is what it does.
if name != nil {
//use name!
} else {
//use default value
}
Nil-Coalescing Operator is very useful for checking optional and giving default value in a single statement instead of going with optional binding.
if let nameVal = name {
label.text = nameVal
} else {
label.text = “”
}
We can not use ternary operator for optionals. Below gives a build error.
label.text = name ? name! : “”
Hope this post is useful. Feel free to comment incase of any queries.
Tuesday, August 28, 2018
Protocol Extensions for Default and Convenient API
In this tutorial, let’s see how protocol extensions can be used as default and convenient API.
I am taking a Movable protocol which is having a move method.
protocol Movable {
func move(at minimumSpeed: Float)
}
I am creating a class called Car which confirms to Movable protocol.
class Car: Movable {
}
This gives a build error.
We need to implement move method as Car is confirming to Movable.
Instead of this forced implementation, using protocol extensions, we can write default implementation.
extension Movable {
func move(at minimumSpeed: Float) {
print("Moving @ \(minimumSpeed) MPH")
}
}
let car = Car()
car.move(at: 40.0)
This is how we can leverage protocol extensions for default implementations.
Now, What If I don’t want to mention the speed every time. I need to go with minimum speed 40.0 as default speed.
This can also be done using the protocol extensions, by having default value for minimumSpeed.
extension Movable {
func move(at minimumSpeed: Float = 40.0)
{
{
print("Moving @ \(minimumSpeed) MPH")
}
}
let car = Car()
car.move()
Simple and useful. Isn’t it?
Hope this post is useful. Feel free to comment incase of any queries.
Labels:
API,
build,
confirming,
Convenient,
default,
error,
extensions,
implementation,
ios,
protocols,
swift
Subscribe to:
Posts (Atom)





