Introduction

Observe design pattern Wiki
I use the Observer design pattern when I need to inform the user about changes made to an object in the background thread.

Observable variable class definition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Observable<T> {
init(value: T) {
self.value = value
}
var value: T {
didSet {
DispatchQueue.main.async {
self.valueChanged?(self.value)
}
}
}

private var valueChanged: ((T) -> Void)?
func addObserver(_ onChange: ((T) -> Void)?) {
valueChanged = onChange
}

func removeObserver() {
valueChanged = nil
}
}

Create observable variable

1
var hasInternet = Observable<Bool>(value: true)

Set observable variable value

1
hasInternet.value = false

Observe the variable for value change

1
2
3
4
5
6
7
hasInternet.addObserver( {value in
if !value{
//handle observable variable value changed to false
}else{
//handle observable variable value changed to true
}
})

Sample

For example, I want to monitor the internet connection. If internet is disconnected, pop up a notification message.

1
2
3
4
5
6
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

...

self.monitorNetworkConnection()
}
1
2
3
4
class CommonModel{
...
static var hasInternet = Observable<Bool>(value: true)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import Network

let internetMonitor = NWPathMonitor()
func monitorNetworkConnection(){
internetMonitor.pathUpdateHandler = { pathUpdateHandler in
if pathUpdateHandler.status == .satisfied {
print("Internet connection is on.")

if !CommonModel.hasInternet.value{
CommonModel.hasInternet.value = true
}

} else {
print("There's no internet connection.")

if CommonModel.hasInternet.value{
CommonModel.hasInternet.value = false
}
}
}
internetMonitor.start(queue: DispatchQueue.global())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class TestViewController: UIViewController {

override func viewWillAppear(_ animated: Bool) {

if !CommonModel.hasInternet.value{
//Pop-up no internet message here
}

CommonModel.hasInternet.addObserver( {value in
if !value{
//Pop-up no internet message here
}
})
}

override func viewWillDisappear(_ animated: Bool) {
...
CommonModel.hasInternet.removeObserver()
}
}