Clone Struct Models for SwiftUI with No Anxiety
Tags: swift, swiftui, swiftimmutable
Published: 2024-02-19 20:05:25

---
title: Clone Struct Models for SwiftUI with No Anxiety
published: true
description: Clone struct models for SwiftUI effortlessly using the Immutability pattern.
tags: #swift #SwiftUI #SwiftImmutable
cover_image: https://rdevpublic.ams3.cdn.digitaloceanspaces.com/public/dev.to/devto-swift-immutable_modi.png
# Use a ratio of 100:42 for best results.
# published_at: 2024-02-19 07:52 +0000
---


I've been working with SwiftUI for some time, and the task of copying struct models has always been a source of anxiety for me. To illustrate, let's consider this example:

```swift 
struct Person {
    let name: String
    var active: Bool
    var score: Int
}

var persons = [
    Person(name: "Alice", active: false, score: 0),
    Person(name: "Bob", active: false, score: 0),
    Person(name: "Charlie", active: false, score: 0)
]

// Using map to change the active status to true and increase the score value by one for all persons
persons = persons.map { person in
    var modifiedPerson = person
    modifiedPerson.active = true
    modifiedPerson.score += 1
    return modifiedPerson
}
```


Now, what if I have conditional logic for scoring and activating? Then, I would make this change:
 
```swift 
persons = persons.map { person in
    if allowedNames.contains(person.name) {
        var modifiedPerson = person    
        modifiedPerson.active = true
        modifiedPerson.score += 1
        return modifiedPerson
    }
    return person   
}

```

However, I believe there's a better way that aligns more closely with the immutability pattern that SwiftUI aims to achieve. This can be done using the [swift-immutable](https://github.com/rayeddev/swift-immutable)
Swift macro package, which allows cloning a model and partially modifying its members.

Let's see how it works.

First, we add the package.
Then, we add the Clone macro to our struct.


```swift
import SwiftImmutable

@Clone
struct Person {
    let name: String
    var active: Bool
    var score: Int
}
```

The macro will add a clone function to the struct, allowing us to use it like this:

```swift 
// Using map to change the active status to true and increase the score value by one for all persons
persons = persons.map { 
        $0.clone(active: true, score: $0.score + 1) 
}
```

Or using sugar syntax:
```swift 
// Using map to change the active status to true and increase the score value by one for all persons
persons = persons.map { 
       $0.clone(toggle: .active, inc: .score(1)) 
}
```

What if there is a condition?

```swift
// Using map to change the active status to true and increase the score value by one for all persons
persons = persons.map { 
       !allowedNames.contains($0.name) 
       ? $0 
      : $0.clone(toggle: .active, inc: .score(1)) 
}
```


## Numeric, String, and Bool Modifiers
```swift
// Increment score
person = person.clone(inc: .score(1))

// Toggle active status
person = person.clone(toggle: .active)

// Add prefix to name
person = person.clone(prefix: .name("Mr. "))

// Append suffix to name
person = person.clone(suffix: .name(" Legend"))
```

I hope you find this helpful for your work. Thank you.