Question

Still on assignment 4 of cs193p. - http://www.stanford.edu/class/cs193p/cgi-bin/drupal/system/files/assignments/Assignment%204_2.pdf

I've fully (ish) implemented the displaying photos from a list of places.

I'm adding the second tab of the application (required tasks 10 & 11) , which is to generate and display a list of the 20 most recent photos viewed in chronological order.

My question relates to the MVC pattern and setting/accesing NSUserdefaults.

Basically, anytime a photo is viewed, a property list stored in NSUserdefaults needs to be updated.

When selecting the "recent photos" tab, those values need to be read and displayed, so that the user can select a recently viewed photo, and then view it by selecting it.

I think I can implement this quite easily from a writing lines of code and it will probably work point of view.

I've seen this question: CS193P UITabBarController MVC Help on Assignment 4 which is kind of related, but doesn't really address my more theoretical question about the nature of the pattern.

My question is more about the MVC pattern.

In the lecture, when he demonstrated this with favourite graphs, from the previous calculator assignment he used a delegate to communicate between the favourites list view controller and the graphviewController (see diagram on slide 64 of lecture 9). http://www.stanford.edu/class/cs193p/cgi-bin/drupal/system/files/lectures/Lecture%209_1.pdf

I'm trying to work out if I need to do something similar to avoid breaking the MVC pattern, or if I can just use NSUserdefaults in both the viewWillLoad of my imageViewController to add a photo to the favourites and and then in my setter in RecentImagesViewController. I know NSUserdefaults is designed for persistence, it just feels a bit like I"m using a global variable.

I realise this question is worded in a way which makes it difficult to follow if you aren't familiar with the cs193p course - sorry.

Thanks for any advice!!

Was it helpful?

Solution

Well, it probably feels like you're using a global variable because the user defaults themselves are a global concept. And they should be. You don't want different parts of the app operating on unsynchronized versions of user preferences.

But, if you use the term variable in the sense of an old C/C++ global static piece of data, then, no ... that's not what it is. NSUserDefaults was written by Apple to be a nice tidy class that encapsulates the user default data. The fact that you use [NSUserDefaults standardUserDefaults] to access something like a singleton instance (not sure if that's how Apple chose to implement it) still doesn't mean it's a true global variable.

I agree with Jacky Boy that keeping it simple is best, but your question is really asking whether doing it the way you are is a violation of the MVC pattern (and adhering slavishly to a pattern is not always going to make your code the best). That depends on what you consider the model to be. I could justify saying that Apple built NSUserDefaults to be a model layer encapsulation of the preferences data. So, there you have your model layer, and your controllers should be able to use it.

Or do you feel the need to write the entire model layer yourself, in which case your model layer would just have a wrapper for NSUserDefaults. That would seem like overkill for most situations.

Here is maybe one situation that could warrant it. If you have a lot of preference data that seems logically related, but some of it is not appropriate for NSUserDefaults. Perhaps it's a lot of binary data, stored in a hierarchy of objects, and you want to persist it with Core Data. But, it still seems logically related to what you're keeping in NSUserDefaults. Maybe then, you decide to write your own model layer, that encapsulates both the Core Data and NSUserDefaults data. Your view controllers could then use that directly.

But, generally, I think iOS is well designed to have whoever needs to just use the standardUserDefaults object directly.

OTHER TIPS

I don't think you have to transform something rather simple in something complex. You are storing the favorites using the NSUserDefaults and that's it. The place where you are using might not be the best (I am not saying the viewWillLoad is a bad place, I don't know your code), but I don't think you need a delegate to just update the NSUserDefaults. Botton line, don't forget the KISS principle. :)

If I understand the question correctly, it sounds like the setting/loading should be occurring from the appropriate view controller. Creating a delegate (which may or may not be a singleton) that you can call from each of the different tab's view controllers will help prevent you from duplicating code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top