4
\$\begingroup\$

I'm one month into self-learning Swift, and I would like some advice to improve my coding skills.

I have listed 2 situations that I think I need to improve. I'd like some feedback focusing on my use of static variables for changing data between ViewControllers and subviews.


1.0 Image 1 shows the app flow (Left = HomeController), middle = MenuController, Right = FavouritesController)

Image 1 Image 1

In HomeController there is a UIView subview. From this subview the current quote (HomeController.homeControllerCurrentQuote) displayed can be saved to favourites array. This is a static array defined in FavouritesController.

The functions below are called from the subview within HomeController. I made HomeController.homeControllerCurrentQuote static because the subview needs access to it. Likewise for FavouritesController.favourites.

In FavouritesController the data contained in FavouritesController.favourites array is used to populate a tableVIew.

// FavouritesController.favourites is static variable!
// HomeController.homeControllerCurrentQuote is static variable! updated as user scrolls

func handleFavourite() {
    let favourites = FavouritesController.favourites
    if favourites.contains(HomeController.homeControllerCurrentQuote) { 
    removeFromFavourites()
    } else { FavouritesController.favourites.append(HomeController.homeControllerCurrentQuote)
        UserDefaults.standard.set(try? PropertyListEncoder().encode(FavouritesController.favourites), forKey:"myKey")
    }
}

func removeFromFavourites() {
    var tempArray: [Quote] = [.init(category: "", quote: "", author: "")]
    tempArray = FavouritesController.favourites
    let searchString = HomeController.homeControllerCurrentQuote.quote
    var filteredArray = [Quote]()
    filteredArray = tempArray.filter( { !$0.quote.contains(searchString) } )
    UserDefaults.standard.set(try? PropertyListEncoder().encode(filteredArray), forKey:"myKey")
}

// update static variable on HomeController
internal override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
....
    HomeController.homeControllerCurrentQuote = Quote(category: cell.categoryLabel.text ?? "", quote: cell.quoteLabel.text ?? "", author: author)
....
}

Should I change how this is done? I don't like the use of static variables but as it's my first app I was more focused on getting it done rather than how it was done. Is it a good case for using a delegate and protocol to communicate between the views (I've never used this before)? If so how would I start to think about implementing it or, as it works, is what I've done satisfactory?


2.0 When the app launches on HomeController required data is generated and is stored in a static variable.

                          //  [category : [quote  : author]]
static var xQuotesByCategory: [String   : [String : String]] = [:]

I make this data static because when I instantiate HomeController again from another controller, I don't want to have to refetch the data. I want to retrieve it once. Then when a new instance of HomeController is called I can make this check which should return false. Is this an appropriate use of a static variable?

if HomeController.xQuotesByCategory.values.isEmpty {
    ... fetchJson()
}

Following on from this, as HomeController.xQuotesByCategory is static, on CategoriesController I can call

var categories = Array(HomeController.xQuotesByCategory.keys)

This gets only the outer keys (categories) which I use to create the collectionView cells with the text and images shown in image 2. Again, same question, is this appropriate use of a static variable? Is there better way to ensure data is loaded only once and then pass the keys to CategoriesController in a different way when it's required?

image 2


If you'd like to try running the app, there is a test version available on TestFlight. Let me know and I can add you in TestFlight!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.