Bird
Raised Fist0
iOS Swiftmobile~20 mins

Predicates and sorting in iOS Swift - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Filtered Sorted List
This screen shows a list of fruits. Users can filter the list by typing a search term. The list is always sorted alphabetically.
Target UI
-------------------------
| Filtered Sorted List   |
-------------------------
| Search: [___________] |
|                       |
| - Apple                |
| - Banana               |
| - Cherry               |
| - Date                 |
| - Grape                |
| - Kiwi                 |
|                       |
-------------------------
Display a list of fruit names.
Add a search bar at the top to filter fruits by name using a predicate.
Sort the filtered fruits alphabetically.
Update the list in real-time as the user types.
Starter Code
iOS Swift
import SwiftUI

struct FruitListView: View {
    @State private var searchText = ""
    let fruits = ["Banana", "Apple", "Cherry", "Date", "Grape", "Kiwi"]

    var body: some View {
        NavigationView {
            VStack {
                TextField("Search", text: $searchText)
                    .padding()
                    .textFieldStyle(RoundedBorderTextFieldStyle())

                List {
                    // TODO: Show filtered and sorted fruits here
                }
            }
            .navigationTitle("Filtered Sorted List")
        }
    }
}

struct FruitListView_Previews: PreviewProvider {
    static var previews: some View {
        FruitListView()
    }
}
Task 1
Task 2
Task 3
Solution
iOS Swift
import SwiftUI

struct FruitListView: View {
    @State private var searchText = ""
    let fruits = ["Banana", "Apple", "Cherry", "Date", "Grape", "Kiwi"]

    var filteredFruits: [String] {
        fruits.filter { fruit in
            searchText.isEmpty || fruit.localizedCaseInsensitiveContains(searchText)
        }
        .sorted()
    }

    var body: some View {
        NavigationView {
            VStack {
                TextField("Search", text: $searchText)
                    .padding()
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .accessibilityLabel("Search fruits")

                List(filteredFruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .listStyle(PlainListStyle())
            }
            .navigationTitle("Filtered Sorted List")
        }
    }
}

struct FruitListView_Previews: PreviewProvider {
    static var previews: some View {
        FruitListView()
    }
}

We created a computed property filteredFruits that filters the fruits array using the search text. It uses localizedCaseInsensitiveContains to check if the fruit name includes the search text, ignoring case. If the search text is empty, it shows all fruits. Then it sorts the filtered list alphabetically with sorted().

The List displays the filtered and sorted fruits. The TextField updates searchText as the user types, so the list updates in real-time.

We also added an accessibility label to the search field for better usability.

Final Result
Completed Screen
-------------------------
| Filtered Sorted List   |
-------------------------
| Search: [App_______]  |
|                       |
| - Apple                |
|                       |
-------------------------
User types 'App' in the search bar.
List updates to show only 'Apple' because it matches the search.
If user clears the search, all fruits appear sorted alphabetically.
Stretch Goal
Add a clear button inside the search bar to quickly erase the search text.
💡 Hint
Use the .overlay modifier on TextField with a Button that sets searchText to an empty string.

Practice

(1/5)
1. What does an NSPredicate do in Swift when working with arrays?
easy
A. Removes duplicates from the array
B. Sorts the array in ascending or descending order
C. Adds new items to the array
D. Filters the array to include only items matching a condition

Solution

  1. Step 1: Understand the role of NSPredicate

    An NSPredicate is used to specify conditions to filter collections like arrays.
  2. Step 2: Differentiate filtering from sorting

    Filtering means selecting items that meet a condition, while sorting changes order.
  3. Final Answer:

    Filters the array to include only items matching a condition -> Option D
  4. Quick Check:

    Predicate = Filter [OK]
Hint: Predicate means filter, not sort or add [OK]
Common Mistakes:
  • Confusing predicate with sorting
  • Thinking predicate adds or removes items
  • Assuming predicate changes order
2. Which of the following is the correct syntax to create an NSPredicate filtering for names equal to "John"?
easy
A. NSPredicate(format: "name == 'John'")
B. NSPredicate(format: "name = 'John'")
C. NSPredicate(format: "name equals 'John'")
D. NSPredicate(format: "name === 'John'")

Solution

  1. Step 1: Recall NSPredicate format syntax

    NSPredicate uses format strings with == for equality comparison.
  2. Step 2: Identify correct equality operator

    == is the correct operator; = or === are invalid in NSPredicate format.
  3. Final Answer:

    NSPredicate(format: "name == 'John'") -> Option A
  4. Quick Check:

    Use == for equality in NSPredicate [OK]
Hint: Use double equals (==) for equality in predicates [OK]
Common Mistakes:
  • Using single equals (=) instead of double (==)
  • Using === which is not valid in NSPredicate
  • Writing 'equals' as a word instead of operator
3. Given this Swift code snippet, what will be the output?
let names = ["Anna", "John", "Bob", "Alice"]
let predicate = NSPredicate(format: "SELF BEGINSWITH[c] 'A'")
let filtered = (names as NSArray).filtered(using: predicate) as! [String]
let sorted = filtered.sorted(by: { $0 > $1 })
print(sorted)
medium
A. ["Alice", "Anna"]
B. ["Anna", "Alice"]
C. ["Anna"]
D. ["Alice"]

Solution

  1. Step 1: Filter names starting with 'A' ignoring case

    The predicate selects names beginning with 'A' or 'a': "Anna" and "Alice".
  2. Step 2: Sort filtered names descending

    Sorting with $0 > $1 means descending order alphabetically: "Alice" comes before "Anna".
  3. Final Answer:

    ["Alice", "Anna"] -> Option A
  4. Quick Check:

    Filter by 'A', then descending sort = ["Alice", "Anna"] [OK]
Hint: Filter first, then sort; descending means bigger first [OK]
Common Mistakes:
  • Sorting ascending instead of descending
  • Ignoring case sensitivity in predicate
  • Confusing filter and sort order
4. Identify the error in this Swift code using NSPredicate and sorting:
let numbers = [5, 3, 8, 1]
let predicate = NSPredicate(format: "SELF > 4")
let filtered = numbers.filter { predicate.evaluate(with: $0) }
let sorted = filtered.sorted(by: { $0 < $1 })
print(sorted)
medium
A. NSPredicate format string is incorrect
B. No error; code works as expected
C. Filtering with predicate.evaluate(with:) is correct
D. Cannot use NSPredicate with Int values

Solution

  1. Step 1: Check NSPredicate format

    The format "SELF > 4" is valid for filtering numbers greater than 4.
  2. Step 2: Verify filtering and sorting logic

    Using predicate.evaluate(with:) inside filter is valid; sorting ascending is correct.
  3. Final Answer:

    No error; code works as expected -> Option B
  4. Quick Check:

    Predicate with Int and filter works fine [OK]
Hint: Evaluate predicate inside filter is valid for Int arrays [OK]
Common Mistakes:
  • Thinking NSPredicate can't filter Ints
  • Assuming format string is wrong
  • Expecting error in sorting syntax
5. You have an array of dictionaries representing people:
let people = [
  ["name": "John", "age": 30],
  ["name": "Alice", "age": 25],
  ["name": "Bob", "age": 30],
  ["name": "Carol", "age": 25]
]
How do you filter for people aged 25 and sort them by name ascending using NSPredicate and Swift sorting?
hard
A. Use NSPredicate(format: "age = 25") and sort with sorted(by: { $0["name"]! > $1["name"]! })
B. Use NSPredicate(format: "age >= 25") and sort with sorted(by: { $0["age"]! < $1["age"]! })
C. Use NSPredicate(format: "age == 25") and sort with sorted(by: { $0["name"]! < $1["name"]! })
D. Use NSPredicate(format: "age == '25'") and sort with sorted(by: { $0["name"]! < $1["name"]! })

Solution

  1. Step 1: Write correct NSPredicate for age 25

    Use "age == 25" to filter exactly age 25; single equals is invalid.
  2. Step 2: Sort filtered array by name ascending

    Sort by comparing names with < operator for ascending order.
  3. Final Answer:

    Use NSPredicate(format: "age == 25") and sort with sorted(by: { $0["name"]! < $1["name"]! }) -> Option C
  4. Quick Check:

    Filter age == 25, sort by name ascending [OK]
Hint: Use == for equality and < for ascending sort [OK]
Common Mistakes:
  • Using single = instead of ==
  • Comparing age as string '25' instead of number
  • Sorting by age instead of name
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard