UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Project 7, day 35, task 2

Forums > 100 Days of Swift

Hello everyone, I go through the lessons without using a storyboard, sometimes I have difficulties because the code is different from what the teacher does. I ran into a problem, my filter in textField does not work, although I found the answer to the problem here on the forum. Can anyone help me solve the problem? There are no errors, but the filter does not work.

SceneDelegate:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        guard let windowScene = (scene as? UIWindowScene) else { return }

        let myWindow = UIWindow(windowScene: windowScene)
        let navigationController = UINavigationController()
        let viewController = MainTabBarController()

        navigationController.viewControllers = [viewController]
        myWindow.rootViewController = navigationController

        self.window = myWindow

        myWindow.makeKeyAndVisible()
    }
}

MainViewController:

class MainViewController: UITableViewController {

    private let identifier = "identifier"

    var petitions = [Petition]()

    var filteredPetitions = [Petition]()

    override func viewDidLoad() {
        super.viewDidLoad()

        setupTableView()

        let urlString: String

        if navigationController?.tabBarItem.tag == 0 {
            urlString = "https://www.hackingwithswift.com/samples/petitions-1.json"
        } else {
            urlString = "https://www.hackingwithswift.com/samples/petitions-2.json"
        }

        if let url = URL(string: urlString) {
            if let data = try? Data(contentsOf: url) {
                parseJSON(json: data)
                filteredPetitions = petitions
                return
            }
        }
        showError()
    }

    func parseJSON(json: Data) {
        let decoder = JSONDecoder()

        if let jsonPetitions = try? decoder.decode(Petitions.self, from: json) {
            petitions = jsonPetitions.results
            tableView.reloadData()
        }
    }

    private func showError() {

        let ac = UIAlertController(title: "Loading error",
                                   message: "There was a problem loading the feed; please check you connection and try again",
                                   preferredStyle: .alert)

        ac.addAction(UIAlertAction(title: "OK",
                                   style: .default))

        present(ac, animated: true)
    }

    private func setupTableView() {

        tableView.register(UITableViewCell.self,
                           forCellReuseIdentifier: identifier)
    }
}

//MARK: TableView Delegate

extension MainViewController {

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return filteredPetitions.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: identifier,
                                                 for: indexPath)

        let petition = petitions[indexPath.row]
        cell.textLabel?.text = petition.title
        cell.detailTextLabel?.text = petition.body

        return cell
    }
}

MainTabBarController:


class MainTabBarController: UITabBarController {

    var mainVC = MainViewController()

    override func viewDidLoad() {
        super.viewDidLoad()

        setupTabBar()
        setupItems()
        setupNavItem()
    }

    private func setupNavItem() {

        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .search,
                                                            target: self,
                                                            action: #selector(filterTapped))
    }

    @objc func filterTapped() {

        let ac = UIAlertController(title: "Enter:",
                                   message: nil,
                                   preferredStyle: .alert)
        ac.addTextField()

        let submitAction = UIAlertAction(title: "Submit",
                                         style: .default) { [weak self, weak ac] action in
            guard let answer = ac?.textFields?[0].text else { return }
            self?.submit(answer)
        }
        ac.addAction(submitAction)
        present(ac, animated: true)
    }

    func submit(_ answer: String) {

        mainVC.filteredPetitions.removeAll(keepingCapacity: true)
        for x in mainVC.petitions {
            if x.title.contains(answer){
                mainVC.filteredPetitions.append(x)
                mainVC.tableView.reloadData()
            }
        }
    }

    private func setupTabBar() {
        tabBar.layer.borderWidth = 0.5
    }

    private func setupItems() {

        let mainViewController = MainViewController()
        let vc = MainViewController()

        setViewControllers([mainViewController, vc], animated: true)

        mainViewController.tabBarItem = UITabBarItem(tabBarSystemItem: .bookmarks, tag: 0)
        vc.tabBarItem = UITabBarItem(tabBarSystemItem: .topRated, tag: 1)

    }
}

PetitionModel:

struct Petitions: Codable {
    var results: [Petition]
}

struct Petition: Codable {

    var title: String
    var body: String
    var signatureCount: Int
}

3      

I'm not sure if this is your problem, but when you are typing in a filter, and checking to see that it matches the title of a petition, it doesn't look like you are checking for case sensitivity.

So, when you try to test the filter, are you making sure to type all the capital letters exactly as they appear in the petition title?

If that is your problem, you will probably need to just make sure that you use ".lowercased()" on both the petition title and the filter answer before comparing them in your code.

3      

@Fly0strich I tried to write in different ways and with a capital letter and with a small one and all large and all small, nothing works (

3      

Oh wait, maybe this is why yours isn't working.

So, you have this function that runs when a person types in a filter...

func submit(_ answer: String) {

        mainVC.filteredPetitions.removeAll(keepingCapacity: true)
        for x in mainVC.petitions {
            if x.title.contains(answer){
                mainVC.filteredPetitions.append(x)
                mainVC.tableView.reloadData()
            }
        }
}

It adds all the necessary petitions to the filteredPetitions array.

But then you have this function telling what should be shown in the cells of your tableview...

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: identifier,
                                                 for: indexPath)

        let petition = petitions[indexPath.row]
        cell.textLabel?.text = petition.title
        cell.detailTextLabel?.text = petition.body

        return cell
}

It is displaying its information based on the petitions array. So, even though you are creating a new array called filteredPetitions it isn't actually being used in your tableView.

3      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.