TAP top app download banner
theAsianparent Singapore Logo
theAsianparent Singapore Logo
Product Guide
Sign in
  • Together Against RSV
  • SG60
  • Pregnancy
    • Due date calculator
    • I'm pregnant
    • Trying To Conceive
    • Labour
    • After birth
    • Baby loss
  • Parenting
    • Parent's Guide
    • Relationship & Sex
  • Child
    • Newborn
    • Baby
    • Toddler
    • Pre-Schooler
    • Kid
    • Pre-Teen & Teen
  • Feeding & Nutrition
    • Diseases-Injuries
    • Breastfeeding & Formula
    • Meal Planner
    • Health
    • Allergies & Conditions
    • Vaccinations
  • Education
    • Pre-School
    • Primary School
    • Secondary School
    • Primary School Directory
  • Lifestyle
    • Money
    • Travel & Leisure
    • Fashion
    • Home
    • Fitness
    • Contests & promotions
  • Events
  • Holiday Hub
  • Aptamil
    • Immunity
    • Intelligence
  • TAP Recommends
  • Shopping
  • Press Releases
  • Project Sidekicks
  • Community
  • Advertise With Us
  • Contact Us
  • VIP

Some coding goes here

5 min read
Some coding goes here

Hello my brilliant readers, Leo here.Today we'll explore one of the oldest reactive techniques that you can easily implement in pure Swift. But why would you do that if you have Combine or RxSwift. Well, maybe you don't want to add all the complexity of Combine or RxSwift to your code base but still want to have a reactive code. Reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. This is has a special fit for mobile developers because all that we do is to wait the user to do something and react to that.Let's code!ProblemYou want that your properties of your objects could have custom closure-based reactions.The technique we'll go through today is called Boxing. But what is it? Let's examine the code above:COPYCOPYCOPYstruct User {

let name: String

let age: Int

}

class UserController {

var users: [User] = [] // 1

func getUsersFromNetwork() { // 2

// get from network stuff

users = [User(name: "Leo", age: 30),User(name: "Ana", age: 26)]

}

}

Imagine that you have this very common structure of Controller. You have a func (2) that get users from network and add to a local variable the result of it. Generally the UserController would use some Closure based completion, that we can inject in the method what we want to do after it completes processing, something like this:COPYCOPYCOPY func getUsersFromNetwork(completion: @escaping (Result<[User],Error>)->()) { // 2

// mock a completion handler

let users = [User(name: "Leo", age: 30),User(name: "Ana", age: 26)]

self.users = users

completion(.success(users))

}

And use it like this:COPYCOPYCOPYclass UserViewController {

let userController = UserController()

init() {

userController.getUsersFromNetwork {

Partner Stories
Appreciation Beyond Teachers’ Day for Early Childhood and Early Intervention Educators
Appreciation Beyond Teachers’ Day for Early Childhood and Early Intervention Educators
Discover the Hidden Gem: Whistle Woods Schoolhouse Open House
Discover the Hidden Gem: Whistle Woods Schoolhouse Open House
Unlocking Financial Independence for the Next Generation
Unlocking Financial Independence for the Next Generation
21CC and PSLE - “Neither can live while the other survives!”
21CC and PSLE - “Neither can live while the other survives!”

switch $0 {

case .success(let users):

print(users)

case .failure(_):

print("yeap was an error")

}

}

}

}

let userVC = UserViewController()

Getting the printed result in the init method:And yes, this works just fine. The problem here is that our func is reactive based on his response we aren't getting reactively the users from the controller. You could have more methods calling API's and all of them must implement the completion handler, this is not a very comfortable API to work with, so we can use boxing to react each time the user is set, this way we only deal with ONE closure for all network calls of UserController.The BoxTo do the box struct it's pretty straightforward. We just need a struct that wraps the value and also could receive a closure that is executed each time the value changes. First we start adding the properties:COPYCOPYCOPYstruct UsersBox {

typealias Action = ([User]) -> Void

private var value: [User] { // 1

didSet {

action?(value)

}

}

private var action : Action? // 2

init(value: [User]) {

self.value = value

}

}

This is interesting because the design of this struct on 1 and 2 marks has conformity with the open-close principle that says "the software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification". We making the properties private in Swift tells the compiler that no one could modify this behavior, what is intended.And now we will add the functions that handle with the bind of the closure and with new values.COPYCOPYCOPYstruct UsersBox {

private var value: [User] {

didSet {

action?(value)

}

}

typealias Action = ([User]) -> Void

private var action : Action?

init(value: [User] = []) {

self.value = value

}

mutating func set(value: [User]) { // 1

self.value = value

}

mutating func bind(action: @escaping Action) { // 2

self.action = action

action(value)

}

}

The 1 and 2 marks are functions that helps us with the box. 1 mark just set new values and the mark 2 is where we get the reactive behavior of it. So now, every time the list os users changes, we can react to that, independently of what function triggered that change. That's great, isn't it?Now we came back to the UserController and use the UsersBox instead of the the plain array of users:COPYCOPYCOPYclass UserController {

var users = UsersBox()

func getTwoUsersFromNetwork() { // 2

// get from network stuff

let users = [User(name: "Leo", age: 30),User(name: "Ana", age: 26)]

self.users.set(value: users)

}

func getOneUserFromNetwork() { // 2

// get from network stuff

let users = [User(name: "Leo", age: 30)]

self.users.set(value: users)

}

func getThreeUsersFromNetwork() { // 2

// get from network stuff

let users = [User(name: "Leo", age: 30),User(name: "Leo", age: 30),User(name: "Leo", age: 30)]

self.users.set(value: users)

}

func configureUsersBox(completion: @escaping ([User]) -> Void) {

users.bind(action: completion)

}

}

Here I add other mock methods just to test and prove that they all are responding to changes reactively. Int the UserViewController we can now just do one bind, and all the network calls will be reactively fulfilled:COPYCOPYCOPYclass UserViewController {

let userController = UserController()

init() {

userController.configureUsersBox {

print("Users: ($0)")

}

userController.getTwoUsersFromNetwork()

userController.getOneUserFromNetwork()

userController.getThreeUsersFromNetwork()

print("update table/collections views whatever you want")

}

}

And we get the result of calling UserViewController:COPYCOPYCOPYlet userVC = UserViewController()

Generic BoxOne interesting thing that you can do is to turn the UserBox into ah Generic Box like this:COPYCOPYCOPYstruct Box<T> {

private var value: [T] {

didSet {

action?(value)

}

}

typealias Action = ([T]) -> Void

private var action : Action?

init(value: [T] = []) {

self.value = value

}

mutating func set(value: [T]) {

self.value = value

}

mutating func bind(action: @escaping Action) {

self.action = action

}

}

And modifying user controller to use the generic type:COPYCOPYCOPY var users = Box<User>()

Got a parenting concern? Read articles or ask away and get instant answers on our app. Download theAsianparent Community on iOS or Android now!

img
Written by

irai anbu

  • Home
  • /
  • Education
  • /
  • Some coding goes here
Share:
  • Amber Preschool: A New Era of Early Education Begins in Singapore’s East Coast

    Amber Preschool: A New Era of Early Education Begins in Singapore’s East Coast

  • When School Refusal Isn’t Laziness — It’s Anxiety in Disguise

    When School Refusal Isn’t Laziness — It’s Anxiety in Disguise

  • Here's a Clinical Psychologist's Take on Why Kids are Losing their Attention Span

    Here's a Clinical Psychologist's Take on Why Kids are Losing their Attention Span

  • Amber Preschool: A New Era of Early Education Begins in Singapore’s East Coast

    Amber Preschool: A New Era of Early Education Begins in Singapore’s East Coast

  • When School Refusal Isn’t Laziness — It’s Anxiety in Disguise

    When School Refusal Isn’t Laziness — It’s Anxiety in Disguise

  • Here's a Clinical Psychologist's Take on Why Kids are Losing their Attention Span

    Here's a Clinical Psychologist's Take on Why Kids are Losing their Attention Span

Get advice on your pregnancy and growing baby. Sign up for our newsletter
  • Pregnancy
  • Family Occasions
  • Lifestyle
  • Normal Delivery
  • Ages & Stages
  • Trying To Conceive
  • News
  • TAP Community
  • Advertise With Us
  • Contact Us
  • Become a Contributor


  • Singapore flag Singapore
  • Thailand flag Thailand
  • Indonesia flag Indonesia
  • Philippines flag Philippines
  • Malaysia flag Malaysia
  • Vietnam flag Vietnam
© Copyright theAsianparent 2025. All rights reserved
About Us|Privacy Policy|Terms of Use |Sitemap HTML
  • Tools
  • Articles
  • Feed
  • Poll

We use cookies to ensure you get the best experience. Learn MoreOk, Got it

We use cookies to ensure you get the best experience. Learn MoreOk, Got it