Chat App - Module 2: Lesson 12 - ContactsListView

I’m new to this community and coding with Chris. I was working through the Chat App on module 2 lesson 12. At the end of the lesson, Chris puts in the onChange function with the following lines on row 50. I’m running it on iOS 17.0 in the simulator. Thanks for any help offered.

I’m getting this error below and I need some help modifying this to make this work.

‘onChange(of:perform:)’ was deprecated in iOS 17.0: Use onChange with a two or zero parameter action closure instead.

import SwiftUI

struct ContactsListView: View {
@EnvironmentObject var contactsViewModel: ContactsViewModel

@State var filterText = ""

var body: some View {
    
    
    VStack {
        // Heading
        HStack {
            Text("Contacts")
                .font(Font.pageTitle)
            
            Spacer()
            
            Button {
                // TODO: Settings
            } label: {
                Image(systemName: "gearshape.fill")
                    .resizable()
                    .frame(width: 20, height: 20)
                    .tint(Color("icons-secondary"))
            }
            
        }
        .padding(.top, 20)
        
        // Search bar
        ZStack {
            Rectangle()
                .foregroundColor(Color.white)
                .cornerRadius(20)
            
            TextField("Search contact or number", text: $filterText)
                .font(Font.tabBar)
                .foregroundColor(Color("text-textfield"))
                .padding()
        }
        .frame(height: 46)
        .onChange(of: filterText) { _ in
        
            // filter the results
            contactsViewModel.filterContacts(filterBy:
                                                filterText.lowercased()
                .trimmingCharacters(in:
                        .whitespacesAndNewlines))
        }
        
        if contactsViewModel.filteredUsers.count > 0 {
        
            // List
            List(contactsViewModel.filteredUsers) { user in
                
                // display rows
                ContactRow(user: user)
                    .listRowBackground(Color.clear)
                    .listRowSeparator(.hidden)
            }
            .listStyle(.plain)
            .padding(.top, 12)
        }
        else {
            
            Spacer()
            
            Image("no-contacts-yet")
            
            Text("Hmm... Zero contacts?")
                .font(Font.titleText)
                .padding(.top, 32)
            
            Text("Try saving some contacts on your phone!")
                .font(Font.bodyParagraph)
                .padding(.top, 8)
            
            
            Spacer()
            
        }
        
    }
    .padding(.horizontal)
    .onAppear {
        contactsViewModel.getLocalContacts()
    }
}

}

struct ContactsListView_Previews: PreviewProvider {
static var previews: some View {
ContactsListView()
}
}

In iOS 17 the .onChange modifier now passes two parameters into the closure so in the case of your code you aren’t referencing any passed in values but just using a change on the target to run some specific code.

The standard function signature looks like this:

.onChange(of: EquatableValue, { oldValue, newValue in
    // Your code goes here
})

In your case since you are not referencing either of the passed in values, you can replace them with an underscore so all you need to do is this:

.onChange(of: filterText) { _, _ in
        
            // filter the results
            contactsViewModel.filterContacts(filterBy:
                                                filterText.lowercased()
                .trimmingCharacters(in:
                        .whitespacesAndNewlines))
        }
1 Like