Strange behavior with .append()

Hello everyone,

I'm new to SwiftUI, and to coding in general, and I'm currently trying to build an app using SwiftUI.

I have a problem that I was not able to solve, even after a careful review of my code, and with the help of GPT-4.

So, the goal of my app is to remind the user of interacting with the persons that they're closed to. Therefore, my app mainly uses two structs, called Relation (representing a person), and Interaction (representing one interaction with a person).

I've built a sheet called "NewInteractionSheet", whose goal is to add a new Interaction to one of the relations' array of interactions.

This sheet works perfectly well when it comes to adding an interaction. However, for some reason, it only works once. Why does it do that? That's what I'm trying to figure out.

Here's a part of the code of "NewInteractionSheet.swift":

import PhotosUI
import CoreLocation
import MapKit

struct NewInteractionSheet: View {
    @Binding var isPresentingNewInteractionView: Bool
    @Binding var relations: [Relation]
    
    @State private var newInteraction = Interaction.emptyInteraction
    @State private var relation: Relation = Relation.emptyRelation
    @State private var isPresentingLocationPicker: Bool = false
        
    var body: some View {
        NavigationView {
            Form {
                
                Section("You interacted with...") {
                    RelationPicker(relations: $relations, relation: $relation)
                }
                
                Section("Interaction details") {
                    InteractionDatePicker(dateToSet: $newInteraction.date)
                    
                    TypePicker(typeToSet: $newInteraction.type)
                    
                    DurationPicker(shouldShow: newInteraction.type.hasDuration,
                                   hoursToSet: $newInteraction.durationHours,
                                   minutesToSet: $newInteraction.durationMinutes)
                    
                    SummaryTextField(summaryToSet: $newInteraction.summary)
                    
                    LocationPicker(shouldShow: newInteraction.type.hasLocation,
                                   coordinatesToSet: $newInteraction.location.coordinates,
                                   locationNameToSet: $newInteraction.location.name,
                                   isPresentingLocationPicker: $isPresentingLocationPicker)
                    
                    InteractionPhotosPicker(images: $newInteraction.pictures)
                }
            }
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Dismiss") {
                        isPresentingNewInteractionView = false
                    }
                }
                ToolbarItem(placement: .confirmationAction) {
                    Button("Add") {
                        if let index = relations.firstIndex(where: { $0.id == relation.id }) {
                            print("\nBefore appending to relations")
                            print(relations[index])
                            print(newInteraction)
                            relations[index].interactions.append(newInteraction)
                            print("\nAfter having appended to relations")
                            print(relations[index])
                            print(newInteraction)
                        }
                        isPresentingNewInteractionView = false
                        
                        //AJOUTER LA PLANIFICATION D'UNE NOTIFICATION
                    }
                }
            }
            .navigationTitle("New interaction")
        }
    }
}

As you can see in the code, I've included three "print" instructions to help me debug this. And when I'm trying to add two interactions, here's what's printing in the console:

Before appending to relations
Relation(id: EA18AAD4-E576-49A9-90BF-CC58C5000ECE, firstName: "Johanna", lastName: "Duby", photo: nil, interactions: [], contactFrequency: 1814400.0, birthday: Optional(2023-06-15 14:34:40 +0000), notes: "", theme: Relations.Theme.blue, reminders: nil)

Interaction(id: 106CD832-1949-4800-AC75-E21B8890E580, date: 2023-06-15 14:34:43 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])


After having appended to relations
Relation(id: EA18AAD4-E576-49A9-90BF-CC58C5000ECE, firstName: "Johanna", lastName: "Duby", photo: nil, interactions: [Relations.Interaction(id: 106CD832-1949-4800-AC75-E21B8890E580, date: 2023-06-15 14:34:43 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])], contactFrequency: 1814400.0, birthday: Optional(2023-06-15 14:34:40 +0000), notes: "", theme: Relations.Theme.blue, reminders: nil)

Interaction(id: 106CD832-1949-4800-AC75-E21B8890E580, date: 2023-06-15 14:34:43 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])




Before appending to relations
Relation(id: 8D3D2012-D8A2-4092-B1A9-D476F7E05B9A, firstName: "Nastassja", lastName: "Ferrari", photo: nil, interactions: [], contactFrequency: 1209600.0, birthday: nil, notes: "", theme: Relations.Theme.green, reminders: nil)

Interaction(id: 5C4EE2E1-7D2D-4E32-BC00-FCA781EC8C20, date: 2023-06-15 14:34:49 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])


After having appended to relations
Relation(id: 8D3D2012-D8A2-4092-B1A9-D476F7E05B9A, firstName: "Nastassja", lastName: "Ferrari", photo: nil, interactions: [], contactFrequency: 1209600.0, birthday: nil, notes: "", theme: Relations.Theme.green, reminders: nil)

Interaction(id: 5C4EE2E1-7D2D-4E32-BC00-FCA781EC8C20, date: 2023-06-15 14:34:49 +0000, type: Relations.InteractionType.audioCall, durationHours: 0, durationMinutes: 0, summary: "", location: Relations.Location(name: "", coordinates: nil), pictures: [])

You don't need to read this in detail, but just see that:

  • the first time, the interaction is correctly appended to the relations array of the interaction
  • the second time though, for some reason, it's not appended.

I'd be really grateful for any guidance that could shed some light on this perplexing issue! I'm willing to share more code if necessary, such as the parent view from which this sheet is called for example. Any insight would be extremely valuable. Thank you so much for your time and help!

PS: The iPhone I'm using to run this is an iPhone 13 mini, running iOS 16.5

Welcome to the forum.

Question is clear and you have added the prints, which is very helpful.

Not easy to tell though.

A question about isPresentingNewInteractionView.

When do you set it true ? Where is it used ?

Oui, cela aiderait d'avoir le code complet pour tester. Par exemple, poste une adresse de contact et nous échangerons par mail.

What happens if you tap twice on Add to add relation to the same person (for instance Johanna) ? Is appending occuring ?

How is Relation defined ? An ObservableObject class with @Published var ?

Once again, having more code to be able to reproduce would be helpful.

Strange behavior with .append()
 
 
Q