Swift Combine — ‘ASSIGN’ Subscriber

Nikunj joshi
5 min readJan 21, 2023

--

In the previous article, we have learnt about ‘Just’ publisher. This article will focus on ‘assign’ subscriber. If you are directly coming to this article, basic knowledge of subscriber, publisher and sink is expected. If you wish to revise feel free to revisit the learning series.

We have seen working of ‘sink’ subscriber with its callbacks. Sometimes we simply need to assign received event values to other properties or variables. In this case, we case use ‘assign’ subscriber instead of ‘sink’.

assign” subscriber has two variants: assign(to:on:) and assign(to:). Let’s see working of both and when to use which one.

assign’ enables us to assign received values to other KVO compliant properties or object.

assign(to:on:)

assign(to:on:)’ is used when you want to set a given property each time a publisher produces a value. Let’s check this using some code.

import Foundation
import Combine

/*
This is a Util function for logs.
Function will take a title of the topic and will execute the blocks
after printing.
*/

public func myLearningCode(of title: String,
execute: () -> Void) {
print("\n ***** Example of:", title, "***** \n")
execute()
}

myLearningCode(of: "assign(to:on:) subscriber") {

// 1
class Human {
var name: String = "" {
didSet {
// 5
print("Current name assigned is \(name) \n")
}
}
}

// 2
let object = Human()

// 3
let publisher = ["Alice", "Bob", "Nikunj"].publisher

// 4
_ = publisher
.assign(to: \.name, on: object)
}
  1. Simple class ‘Human’ with a property called ‘name’. We have used ‘didSet’ observer to print values when changed.
  2. Created an object for our class.
  3. Created a Publisher with string values from an array.
  4. Used ‘assign(to:on:)’ subscriber on our publisher of step #3. Make a note that we are passing object reference to subscriber. ‘\.name’ value gives access to the property. Notice the return value of ‘assign(to:on:)’ which is a cancellable subscription object.

5. Prints the value received from assign subscriber to name property of the object.

Take a pause and think about possible output. Let’s run and check the real output.

Note that, we are passing a created object to the subscription at step #4. That subscription will preserve strong reference cycle with the passed object until publisher of that subscription doesn’t send a completion event either with success or failure.

The assign(to:on:) function is particularly beneficial when developing applications using UIKit or AppKit, as it allows for direct assignment of values to objects of labels, text views, checkboxes, and other user interface elements.

assign(to:)

There is a variation of the assign that you can use to republish values emitted by a publisher through another property marked with the @Published property wrapper.

To try this add this new example to your playground.

import Foundation
import Combine

/*
This is a Util function for logs.
Function will take a title of the topic and will execute the blocks
after printing.
*/

public func myLearningCode(of title: String,
execute: () -> Void) {
print("\n ***** Example of:", title, "***** \n")
execute()
}

myLearningCode(of: "assign(to:) subscriber") {

// 1
class Human {
@Published var name: String = "Default"
}

// 2
let object = Human()

// 3
object.$name.sink { receivedValue in
print("Current name assigned is \(receivedValue) \n")
}

// 4
let namePublisher = ["Alice", "Bob", "Nikunj"].publisher

// 5
namePublisher.assign(to: &object.$name)
}
  1. Simple class ‘Human’ with a ‘@Publised’ property ‘name’ having a ‘Default’ value.
    When we mark any property ‘Published’ it will automatically get its own Publisher. All subscriber will get an event when value of this property gets changed.
  2. Created an object for out class Human.
  3. At this step, we are using Publisher of the Property ‘name’ with ‘sink’ subscriber to print its value when anyone assign anything to this property.
    ‘$’ sign we have used before property ‘name’ helps us to access default Publisher available for a ‘@Published’ propert

4. We have created a String publisher from an array so we can emit our string events.

5. ‘assign’ subscriber is used on our created ‘namePublisher’ to assign published value directly to a ‘@Published’ property.
if you notice, when we try to use ‘assign(to:)’, we are not getting any return value from it. Its lifecycle is handled internally and get destroyed automatically once published property on which it is assigned, gets deinitialized. Notice usage of ‘&’ which suggests pass by reference of the object value.

Let’s run and see the output.

Summary

  • assign” subscriber has two variants: assign(to:on:) and assign(to:)
  • Emitted value from any publisher can directly been assigned to properties.
  • assign(to:on:) will return a cancellable subscription object and also hold strong reference to the object passed for ‘on’ property.
  • @Published’ property will have its own Published attached with it by default.
  • assign(to:) doesn’t return any subscription object and manage its lifecycle internally with the assigned ‘@Published’ property’s life cycle.

We have seen ‘ASSIGN’ subscriber working, we will deep dive into default protocols of the Publisher, Subscriber and Subscription in the next article. Stay tuned with the combine learning series.

Feel free to follow me to stay updated with the upcoming articles.

Thank You. Cheers!

#Pre-Requisite
Intermediate level of the swift language / iOS is required for this Combine Article series.

#Credits

--

--