Search code examples
arraysswiftinitialization

cannot use instance member 'country' within property initializer; property initializers run before 'self' is available


Attempting to add search function, while doing this I receive the following error message "cannot use instance member 'country' within property initializer; property initializers run before 'self' is available." I am not sure why this is occurring, if I move the variable "country" to viewdidload I receive many errors not just this one, (should I move it to viewwillappear?) any help will be greatly appreciated. Below is all of the code from the view controller causing the issue.

class PresetGenreViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var collectionView: UICollectionView!


    var country = [countries]()
    let searchController = UISearchController(searchResultsController: nil)
    var passValue:String = ""
    var filteredCountries = [country]()

    override func viewDidLoad() {
        super.viewDidLoad()

        country = [countries(name: "Afghanistan"), countries(name: "Africa"), countries(name: "Alabama"),countries(name: "Alaska"),countries(name: "Albania"),countries(name: "Algeria"),countries(name: "Andorra"),countries(name: "Angola"),countries(name: "Antigua and Barbuda"),countries(name: "Arabic"),countries(name: "Argentina"),countries(name: "Armenia"),countries(name: "Aruba"),countries(name: "Australia"),countries(name: "Austria"),countries(name: "Azerbaijan"),countries(name: "Bahamas"),countries(name: "Bangladesh"),countries(name: "Barbados"),countries(name: "Belarus"),countries(name: "Belgium"),countries(name: "Belize"),countries(name: "Benin"),countries(name: "Bermuda"),countries(name: "Bolivia"),countries(name: "Bosnia and Herzegovina"),countries(name: "Brazil"),countries(name: "Brunei"),countries(name: "Bulgaria"),countries(name: "Burkina Faso"),countries(name: "Burundi"),countries(name: "Cambodia"),countries(name: "Cameroon"),countries(name: "Canada"),countries(name: "Cayman Island"),countries(name: "Chile"),countries(name: "China"),countries(name: "Colombia"),countries(name: "Congo"),countries(name: "Costa Rica"),countries(name: "Croatia"),countries(name: "Cuba"),countries(name: "Curacao"),countries(name: "Cyprus"),countries(name: "Czech Republic"),countries(name: "Denmark"),countries(name: "Dominica"),countries(name: "Dominican Republic"),countries(name: "Ecuador"),countries(name: "Egypt"),countries(name: "El Salvador"),countries(name: "English"),countries(name: "Estonia"),countries(name: "Ethiopia"),countries(name: "Faroe Islands"),countries(name: "Fiji"),countries(name: "Finland"),countries(name: "France"),countries(name: "Gambia"),countries(name: "Georgia"),countries(name: "Germany"),countries(name: "Ghana"),countries(name: "Greece"),countries(name: "Greenland"),countries(name: "Grenada"),countries(name: "Guadeloupe"),countries(name: "Guatemala"),countries(name: "Guinea"),countries(name: "Guyana"),countries(name: "Haiti"),countries(name: "Honduras"),countries(name: "Hong Kong"),countries(name: "Hungary"),countries(name: "Iceland"),countries(name: "India"),countries(name: "Indonesia"),countries(name: "Iran"),countries(name: "Iraq"),countries(name: "Ireland"),countries(name: "Israel"),countries(name: "Italy"),countries(name: "Ivory Coast"),countries(name: "Jamaica"),countries(name: "Japan"),countries(name: "Jordan"),countries(name: "Kazakhstan"),countries(name: "Kenya"),countries(name: "Korea"),countries(name: "Kosovo"),countries(name: "Kuwait"),countries(name: "Kyrgyzstan"),countries(name: "Latvia"),countries(name: "Lebanon"),countries(name: "Liberia"),countries(name: "Lithuania"),countries(name: "Luxembourg"),countries(name: "Macedonia"),countries(name: "Madagascar"),countries(name: "Malaysia"),countries(name: "Maldives"),countries(name: "Mali"),countries(name: "Malta"),countries(name: "Martinique"),countries(name: "Mauritius"),countries(name: "Mexico"),countries(name: "Moldova"),countries(name: "Monaco"),countries(name: "Mongolia"),countries(name: "Montenegro"),countries(name: "Morocco"),countries(name: "Namibia"),countries(name: "Nepal"),countries(name: "Netherlands"),countries(name: "Netherlands Antilles"),countries(name: "New Zealand"),countries(name: "Nicaragua"),countries(name: "Nigeria"),countries(name: "Norway"),countries(name: "Oman"),countries(name: "Pakistan"),countries(name: "Palestine"),countries(name: "Panama"),countries(name: "Paraguay"),countries(name: "Persian"),countries(name: "Peru"),countries(name: "Philippines"),countries(name: "Poland"),countries(name: "Portugal"),countries(name: "Puerto Rico"),countries(name: "Qatar"),countries(name: "Romania"),countries(name: "Russia"),countries(name: "Rwanda"),countries(name: "Saint Kitts and Nevis"),countries(name: "Saint Lucia"),countries(name: "Saint Vincent"),countries(name: "Saudi Arabia"),countries(name: "Senegal"),countries(name: "Serbia"),countries(name: "Singapore"),countries(name: "Slovakia"),countries(name: "Slovenia"),countries(name: "Somalia"),countries(name: "South Africa"),countries(name: "South Korea"),countries(name: "Spain"),countries(name: "Sri Lanka"),countries(name: "Sudan"),countries(name: "Suriname"),countries(name: "Sweden"),countries(name: "Switzerland"),countries(name: "Syria"),countries(name: "Taiwan"),countries(name: "Tajikistan"),countries(name: "Tamil"),countries(name: "Tanzania"),countries(name: "Thailand"),countries(name: "Trinidad and Tobago"),countries(name: "Tunisia"),countries(name: "Turkey"),countries(name: "Uganda"),countries(name: "UK"),countries(name: "Ukraine"),countries(name: "United Arab Emirates"),countries(name: "Uruguay"),countries(name: "USA"),countries(name: "Uzbekistan"),countries(name: "Venezuela"),countries(name: "Vietnam"),countries(name: "Virgin Islands"),countries(name: "Zambia"),countries(name: "Zimbabwe")]

        // Setup the Search Controller
        searchController.searchResultsUpdater = self
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.placeholder = "Search Countries"
        navigationItem.searchController = searchController
        definesPresentationContext = true
    }
    func searchBarIsEmpty() -> Bool {
        // Returns true if the text is empty or nil
        return searchController.searchBar.text?.isEmpty ?? true
    }
    func filterContentForSearchText(_ searchText: String, scope: String = "All"){
        filteredCountries = country.filter({ (Country: countries) -> Bool in
            return Country.name.lowercased().contains(searchText.lowercased())
        })

        collectionView.reloadData()
    }
    func isFiltering() -> Bool {
        return searchController.isActive && !searchBarIsEmpty()
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if (isFiltering()){
            return filteredCountries.count
        } else {
            return country.count
        }
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell
        let Country: countries
        if (isFiltering()){
            Country = filteredCountries[indexPath.row]
        } else {
            Country = country[indexPath.row]
        }
        cell.label.text = Country.name

        return cell
    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        collectionView.allowsSelection = true
        let currentCell = collectionView.cellForItem(at: indexPath) as! CollectionViewCell
        currentCell.label.text = passValue

    }

    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
        if (segue.identifier == "discover"){
        let viewcontroller = segue.destination as! PresetViewController
        viewcontroller.passedValue = passValue
    }
}

extension PresetGenreViewController: UISearchResultsUpdating {
    // MARK: - UISearchResultsUpdating Delegate
    func updateSearchResults(for searchController: UISearchController) {
       filterContentForSearchText(searchController.searchBar.text!)
    }
}

Solution

  • Both your initializations are wrong. Both country and filteredCountries seem to be arrays of type Country which would be declared like this.

    var filteredCountries = [Country]()
    

    I think you are confused with what type of an array is. You seem to be setting the type thinking that it is supposed to denote where the content of the array comes from. But it's not like that. The type just says what kind of data is contained in a particular variable. So even if your filteredCountries gets it's content from countries. The type of countries is Country which means the type of fitleredCountries should also be Country.


    Important Note: Names of classes, structs, etc should be upperCamelCase as mentioned in the Swift API guidelines.