Builder Pattern in iOS

Harry Yan
4 min readMar 18, 2023

--

Construction? Representation?

The builder pattern is a creational design pattern that helps in building complex objects by breaking them down into simpler components. In iOS, the Builder pattern is widely used to create and configure objects of various types. This pattern is especially useful when dealing with objects that have many properties that need to be set, or when the object creation process is complex and needs to be simplified.

The basic idea behind the Builder pattern is to separate the construction of an object from its representation. The construction process is broken down into smaller steps, with each step responsible for creating a part of the object. Once all the parts have been created, they are assembled to form the final object.

In iOS, the Builder pattern can be used to create objects of different types, including views, view controllers, network requests, and more. The pattern helps in making the code more readable, maintainable, and scalable. Here are some key benefits of using the Builder pattern in iOS:

  1. Simplifies the object creation process: The Builder pattern breaks down the object creation process into smaller, more manageable steps. This makes it easier to create complex objects and reduces the chances of errors.
  2. Improves code readability: By using the Builder pattern, the code becomes more readable and easier to understand. The use of descriptive method names and meaningful parameter names makes it clear what each step of the object creation process is doing.
  3. Enhances maintainability: As the code becomes more readable and organized, it becomes easier to maintain and update. If changes need to be made to the object creation process, they can be done in a centralized location, rather than being scattered throughout the codebase.

Now let’s take a look at how to implement the Builder pattern in iOS. Here is an example of how to use the Builder pattern to create a simple network request:

class NetworkRequestBuilder {
private var url: URL?
private var httpMethod: String?
private var httpBody: Data?
private var headers: [String: String] = [:]

func withURL(_ url: URL) -> NetworkRequestBuilder {
self.url = url
return self
}

func withHTTPMethod(_ method: String) -> NetworkRequestBuilder {
self.httpMethod = method
return self
}

func withHTTPBody(_ body: Data) -> NetworkRequestBuilder {
self.httpBody = body
return self
}

func withHeader(_ header: String, value: String) -> NetworkRequestBuilder {
self.headers[header] = value
return self
}

func build() -> URLRequest? {
guard let url = self.url else {
return nil
}

var request = URLRequest(url: url)

request.httpMethod = self.httpMethod
request.httpBody = self.httpBody

for (key, value) in self.headers {
request.setValue(value, forHTTPHeaderField: key)
}

return request
}
}

In this example, we have created a NetworkRequestBuilder class that has a few properties for constructing a network request. We have also defined several methods that allow us to set the properties. Once all the properties are set, we can call the build() method to create the final URLRequest object.

To use this NetworkRequestBuilder, we can do the following:

let request = NetworkRequestBuilder()
.withURL(URL(string: "https://example.com")!)
.withHTTPMethod("GET")
.withHeader("Authorization", value: "Bearer 123456")
.build()

In this example, we have created a URLRequest object with a few properties set using the NetworkRequestBuilder. By using the Builder pattern, we have simplified the process of creating a network request and made the code more readable and organized.

Another example of using the Builder pattern in iOS is with creating custom views. Let’s say we want to create a custom UILabel that has a certain font, text color, and alignment. Here's how we can use the Builder pattern to create this custom label:

class CustomLabelBuilder {
private var text: String?
private var font: UIFont?
private var textColor: UIColor?
private var alignment: NSTextAlignment?

func withText(_ text: String) -> CustomLabelBuilder {
self.text = text
return self
}

func withFont(_ font: UIFont) -> CustomLabelBuilder {
self.font = font
return self
}

func withTextColor(_ color: UIColor) -> CustomLabelBuilder {
self.textColor = color
return self
}

func withAlignment(_ alignment: NSTextAlignment) -> CustomLabelBuilder {
self.alignment = alignment
return self
}

func build() -> UILabel {
let label = UILabel()
label.text = self.text
label.font = self.font
label.textColor = self.textColor
label.textAlignment = self.alignment ?? .left
return label
}
}

In this example, we have created a CustomLabelBuilder class that has a few properties for constructing a custom label. We have also defined several methods that allow us to set the properties. Once all the properties are set, we can call the build() method to create the final UILabel object.

To use this CustomLabelBuilder, we can do the following:

let label = CustomLabelBuilder()
.withText("Hello, World!")
.withFont(UIFont.systemFont(ofSize: 20))
.withTextColor(.red)
.withAlignment(.center)
.build()

In this example, we have created a custom UILabel object with a few properties set using the CustomLabelBuilder. By using the Builder pattern, we have simplified the process of creating a custom label and made the code more readable and organized.

In conclusion, the Builder pattern is a powerful tool that can help simplify the process of creating complex objects in iOS. By separating the construction of an object from its representation, we can make our code more readable, maintainable, and scalable. The Builder pattern is widely used in iOS, and it’s worth considering using it in your own projects to simplify object creation and improve code quality.

--

--