best option for caching data in ios - ios

I am trying to find the best option for caching multiple string values with the ios system.
The two I have found so far are NSCache and NSDictionary however from what I have read NSCache will dump data if you start to have trouble with your memory and well quite frankly I dont fully understand NSDictionary.
So I am wondering what if any other options there are out there that will suite what I am trying to achive.. for instance maybe using core data / local sqlite etc? basically the plan is to get information from a online database, store some of the more important information on the phone that is only ever updated when the version number (and int) on the database has changed, the I will flush my cache and update it with the new information.

If I understand you correctly, it seems as though every time you have a new version on your server, you want to download the new data, and store some of it to the device.
If that's the case, you can write all the data to a file, and save it on the phone, and then reload the data that you need from that file later. I personally like using NSCoding for this, as it let's you store data easily to a file, and then read it back later when you need it. You don't even need to read all of the data at once, just what you need at what time, which can help with memory issues. You can also make your own custom objects NSCoding compliant, and it becomes even easier to store data!
I would suggest trying NSCoding out. There are also tons of tutorials out there to help you figure it out.
Also, NSDictionaries are super easy to use. You give it an object and a key to store it with, and when you want the object back, simply give the NSDictionary the key, and you'll get the object back.
Hope that Helps!

Related

Need some knowledge on Core Data - NSManagedObject usages

Just a quick question regarding loading data into the app through Core Data - I have already implemented Core Data and app is pretty much running just as it was before I started using it.
In short, when app launches I am fetching all the Entities into a Manager script that stores each object into different arrays and when the app uses the objects the Manager script will pass these arrays to other scripts.
My question is, does this seem like a bad method while using Core Data? Should I just be fetching the Entities when the scripts want them or its fine 'pre-fetching' from the start? This data is limited (to a point) and doesn't change during runtime.
Also, since I have all the entities in different arrays in the Manager script, I am sorting/filtering these arrays by predicates when a script needs something done. (which means I am never using a Core Data fetch with predicate since all the data is already available in the Manager's arrays)
App is already done, was just trying to make performance improvements and by adding Core Data, there is a huge boost. This is kind of my last question (at the moment) and I'm not really sure on the answer since I have never used Core Data before.
Thank you
It is fine.
There are three main drawbacks to prefetching:
You can take up too much memory and crash.
If an entity is deleted and you keep a pointer to it, the app will crash when you try to use that managedObject
Loading might take a very long time if there is a lot of data.
You said "This data is limited (to a point) and doesn't change during runtime" so it appears that none of these issue apply to you.
That being said I am not sure that you are really getting any benefit from core data in this setup. Core data in general scales very well, but your setup will not. You could just as easily store all your information in a file and load it all into memory when the app starts. I trust that you getting other benefits from core data that are not stated in your question.

NSUserDefaults or a backend?

I have to ship a simple app with a very tight deadline so I have no time to learn anything othen than what I know (meaning learning Core Data for example). Would it fine to use NSUserDefaults to store data for my app? It's almost like a check list app where users have list of items with some data accompanying each item.
Other than that I would be using a service like Parse which I can handle thanks to having built my last app with it.
Would Apple reject an app if you use NSUserDefaults for something other than settings/preferences?
Thanks!
From Apple's documentation:
The NSUserDefaults class provides a programmatic interface for interacting with the defaults system. The defaults system allows an application to customize its behavior to match a user’s preferences. For example, you can allow users to determine what units of measurement your application displays or how often documents are automatically saved. Applications record such preferences by assigning values to a set of parameters in a user’s defaults database. The parameters are referred to as defaults since they’re commonly used to determine an application’s default state at startup or the way it acts by default.
[...]
Values returned from NSUserDefaults are immutable, even if you set a mutable object as the value. For example, if you set a mutable string as the value for "MyStringDefault", the string you later retrieve using stringForKey: will be immutable.
In other words, this is not the place to store mutable application data.
If the checklist data is going to be modified by end users (i.e. adding new items, or editing the text of the items on the checklist) it really would be worthwhile to learn how to use Core Data. Over the years it really has become very easy to learn and use.
You can find a great series of Core Data tutorials at http://code.tutsplus.com/series/core-data-from-scratch--cms-653
If you're looking for something that's been updated for iOS 8 and Swift (although they're mainly syntax changes for the new language), you can check out http://www.raywenderlich.com/85578/first-core-data-app-using-swift.
Apple wouldn't reject even if you unnecessarily burden NSUserDefault. But users of your App will definitely uninstall it or OS will kill it if app crashes or hangs their iPhone.
NSUserDefault : is a fast way to access the data. it stores in (key,value) pair and lives as long as your app is installed in phone. Usually session based small amount of data is supposed to be stored in it. Not ur entire database.
Database (CoreData or Sqlite) : Behind the seen Coredata is also a sqlite with objects talking to each other(Think in terms of model instead of tables if using Coredata).
I simple suggest you use Coredata if your data by any chance is big or expected to get big. CoreData wont take much time.
Yes, you can store data in NSUserDefaults, which will be the quick and dirty method to store data locally.
You could use Core Data, though I prefer to just use FMDB and write my own SQLite statements. You could also use NSFileManager and just read and write everything to a JSON file. Parse will probably be overkill if all you are doing is storing a list of check list objects.
Go for NSUserDefault fro now !
When the App is submitted fro approval, look at SQlLite. this will be useful for the next projects.
Parse... sure but make sure it's not overkilling especially if you have limited amount of data
Good Luck !

iOS app with remote server - I don't need data to persist on app, should I still use CoreData?

Design question:
My app talks to a server. Json data being sent/received.
Data on server is always changing, and I want users to see most current data, not stored/cached data. So I require a user to be logged in order to use the app, and care not to persist data in the app.
Should I still use CoreData and map it to Json's.?
Or can I just create custom model classes and map Json's to it's properties, and have nsarray properties, which point to its child objects, etc. ?
Which is better?
Thanks
If you dont want to persist data, I personally think core data would be overkill for this application
Core Data is really for local persistance. If the data was not changing so often and you didnt want them to have to get an updated data everytime the user visited the page, then you would load the JSON and store it locally using CoreData.
Use plain old objective-c objects for now. It's not hard to switch to Core Data in future, but once you've done so it gets a lot harder to change your schema.
That depends on what your needs are.
If you need the app to work offline, you need to store your information somehow in the client.
In order to save on network usage, you could store locally, then query the server to see if it had an updated answer -- you could do this by sending a time stamp to the server and return a 304 Not Modified if the entity hasn't changed.
Generally, it depends on how much time you have to put into the app and what your specific requirements are, but as a general rule I would optimise for as low bandwidth usage as possible, as that not only reduces potential data costs, but also means the answers will be more quickly available to your users (when online and they have not changed) and also available offline.
If you do not wish to store data locally at all,

Optimal way of syncing Core Data with server-side data?

I have what I would presume is a very common situation, but as I'm new to iOS programming, I'm not sure of the optimal way to code it.
Synopsis:
I have data on a server which can be retrieved by the iPhone app via a REST service. On the server side, the data is objects with a foreign key (an integer id number).
I'm storing the data retrieved via REST in Core Data. The managed objects have an "objId" attribute so that I can uniquely identify the managed objects in the rest of my code.
My app must always reflect the server data.
On subsequent requests made to the server:
some objects may not be returned, they have been deleted on the server - in which case I need to delete the corresponding objects from Core Data - so that I'm reflecting the state of the server correctly.
some objects have attributes which have changed, therefore the corresponding managed objects need updating with the new data.
my solution - and question to you
To get things going in my app, I made the easiest solution of deleting all objects in Core Data, then adding all new objects in, created with the latest server side data.
I don't think this is the best way to approach it :) As I progress on with my app, I now want to link up my tableview with NSFetchedResultsController, and have realised that my approach of deleting everything and re-adding is not going to work any more.
What is the tried and trusted way of syncing Core Data with server side data?
Do I need to make a fetch request for each object id I get back from the server, and then update the object with the new data?
And then go through all of the objects in core data and see which ones have not been updated, and delete those?
Is that the best way to do it? It just seems a little expensive to do a fetch for each object in Core Data, that's all.
Pseudo code is fine for any answers :)
thanks in advance!
Well, consider your download. First, you should be doing this in a background thread (if not, there are lots of SO posts that talk about how to do that).
I would suggest that you implement what makes sense first, and then, after you can get valid performance data from running Instruments, consider performance optimization. Of course, use some common sense on "easy" performance stuff (your design can take care of the big ones easily enough).
Anyway, get your data from the online resource, and then, for each object fetched, use the "unique object id" to fetch the object from core data. You know there is only one object with that ID, so you can set fetchLimit to 1 on your fetch request. You can also configure your "object id" attribute to be an INDEX in the database. This way, you get the fastest search from the underlying database, and it knows to stop looking once it finds your one object. This should be pretty snappy.
Now you have your object. Change any attributes necessary. Save, rinse, and repeat.
Furthermore, for several reasons, you may want to know when objects were last updated. I'd suggest adding a timestamp to each object that gets changed with the current time every time an object is changed. This will also help in deleting objects. Since your online database does not tell you which objects are deleted, you must have some way to know that an item is "old and no longer needed."
An easy way to do this is to remember the time you started your update. After processing all objects from the download, you now have a way to find all the objects that were deleted from the online database. Basically, any object with a "last update" timestamp before the time you began the update should be removed (since they were not added or modified in the last update). You can also index the database on this field, which will make finding those objects faster - unless your database is huge, I'd wait to see what Instruments has to say about this one though.

Convert iOS app from NSCoding to Core Data

My app currently uses NSCoding to store persistent data, but I would like to make the switch to Core Data to take advantage of its integration with iCloud. The problem is that the app is currently live on the App Store, and I'm afraid that, once I make the change, the data on my current users' local stores will be lost.
In theory, I should be able to do the following:
Test for existence of NSCoding data
Convert data to Core Data format
Use Core Data for all future "saves"
... but I haven't found any documentation on making the conversion.
Any ideas? Or am I totally off somewhere?
Thanks
CoreData does some nice automated migration, but that's from different CoreData stores. In your case, you will have to write your own conversion code.
Leave the "old" classes around, and unarchive the "old" store if it is there. Then, just loop through the objects in the store, and create their CoreData equivalents. Save the CoreData, close it, then reload it as a check to make sure everything is identical. Then, delete the old storage file.
The only down side is that you have to keep old code around (at least enough to unarchive the old object formats).

Resources