caching model(DTO) classes for later use - ios

I am working on an application which uses foursquare and other server api-s for getting information from the internet. But I have to use some datas when the application is not connected to the internet, I need a method which easily saves these datas from the internet store them on the "disk" as a cache if the phone lost connectivity. Basically I want to store some of my model classes like:
VenueCategory contains a name, id, images(~10), weather reports for 7 days, venues.
A Venue contains images, rating, name, category, categoryImage, address, phone number and open hours schedule.
A water report contains date, max, min temperature, wind, ....
I am thinking on 3 methods but I don't know which is the best for my problem, maybe you can give me better ideas.
Database
Pro:
I get a nice representation from my datas.
Cons:
It is hard to modify if the application is live.
I don't need a new table for the venue category, a table is to much for 1 record inside it.
I have to do a lot of query, insertion, deletion, update, etc.
Serialization
It is easy if I can found a nice way I just say write the whole class to disk and read from disk.(I've never tried)
Plist: (just like the database)
My final question is that, what do you think which is the best and why? Do you have better idea?

The simplest way to approach this is (IMO), is to have your DTOs comply to NSCoding and serialize them using NSKeyedArchiver and deserialize them using NSKeyedUnarchiver.
You can use AutoCoding for that, which automatically implements the required methods in NSCoding with no effort at all.

Have you considered using CoreData? That was the first solution that came to my mind.
CoreData is (by default) based on SQLite and is in my opinion the defacto standard for persisting objects in iOS.

Related

Best Way to save data locally on the device in iOS app

I am working on my first iOS app which will be deployed for both iPhones and iPads. The app contains data that needs to be bundled with the app, which will be used when the device will be offline.
The offline version has atleast 35-40 records with each record containing images(which would be bundled in the app, only names will be saved), and a varchar field which would be atleast 1000 words and a boolean field.
I have found three possible solution for the same
Save all the fields using database (SQlite or Coredata), however
I am concerned about the table which will have 1000 words. But since
the varchar field might vary, I need to allocate max 2000 (or more,depending on the actual length of keywords)
limit (which will lead unnecessary allocation of memory resources)
Another Approach I would like to have is save the information in form of json locally and use it as and when required and save the boolean fields(only true locally in NSUserDefaults)
Use the JSON Approach as discussed above and create a database for managing the boolean fields.
I would like to seek the opinion of StackOverflow community on what would be ideal/optimized approach for this scenario. Also, I am open for any other approach as well.
Edit 1
Proposed provisional databased structure
Listing Table
id -> int (autoincrement)
name -> varchar(25)
imagename -> varchar(10)
desription -> varchar(2000)
favorite -> boolean
It sounds as though the text field (with the 1000-2000 words) is static text that is bundled with the app and can not be changed by the user of the app. If that's the case, then you can store that data in the app bundle with plist files, or JSON files and load it on demand (assuming you don't need to search though it).
Then, if each of those records has only a single boolean value that is changeable by the user, those could be stored in NSUserDefaults very easily (since you've stated you're only dealing with 35-40 records). You'd use the id to link the boolean to the data file.
You could use Core Data or Realm to store the data, but it may be overkill if you don't need a search feature and the user can't change the text. But if you do go with a database option, be aware that you can not store static data (the text), in a location that is backed up by iCloud, or Apple will reject your app. Regardless of whether you use iCloud in the app or not. So if you were to create a Core Data persistent store and save it to the users Documents folder, then load in all the static data, you will be rejected. You would want to save that data store in the users Cache folder so that iCloud doesn't back it up. The issue you'll hit after that though is that you want the user's choices that are your boolean values backed up. This means they need to be stored in a different place. Core Data does have a feature that lets you create Configurations where it will separate the user changeable data from the non-changeable data, but again, that's overkill for your case.
I'd recommend starting with Realm over 'Core Data` for such a small dataset. It's much easier to get up and running.
If you need to look into the fields, CoreData is th best approach, because you can easily access your data using NSPredicates, ( Like an SQL where statement` ).
But if you need to load everything at each launch, you can just store everything to a file ( plist, son ... ), because it is really more easy to managed, and to update ( If you update CoreData Model, the change may be complicated on the App update ).
So my short answer is :
If you need to teach into your data => Core Data
Else => File on local Storage
Do not use UserDefault to achieve that, this is not designed for it.
It is depends on you data base's complexity and operation.
See, first thing is whatever data base system you used, there is no performance difference.
Every database system has different complexity and operation limitations.
For example, It is very simpler to use NSUserDefaults to store and retrieve data.
But if you required to do relational operation between bulk data then it is better to use sqlite or core data. Relational database operations are easily performed by sqlite or coredata compare to others.
There is another option is property - list also available if you data is only type of key value pair.
Core data is totally based on sqlite. In root core data itself using sqlite.
Difference between core data and sqlite is : core data provides more flexibility to use it but it is comparatively hard or complex to learn. Where sqlite not provide flexibility compare to core data but it is less complex to learn and use. Flexibility means for example : you can see visual representation of core data. Can visually add entity or attributes etc.
So, select data base as your need and complexity of use or base on operations that you will required to perform. Your database is not much big and not complex and not required any relational operations or multiple tables then you can use user defaults or property list also.
Hope this will help :)
Pitching in with an option.
To make it easy for yourself later on, I would suggest using CoreData. This lets you easily manage the products for reading and writing. This also gives you a good persistent storage.
To the description issue; you could store the description for each product in its own file with a unique name that references the product you store in CoreData. In your CoreData entity you define a descriptionFile, which will hold the file path.
This approach makes it easier for CoreData when you fetch the objects, maybe you want a browse view where you don't need to display the description, therefore you don't need to load the description text into memory. When a product is selected, load the description file for that product and display the text within.
Happy Coding :)

iOS Application: Portable Data Storage of many Key/Values

What is a good way to store many key/value pair entries in a mobile (iOS) application, such that they can be easily exported/imported?
I have considered a single large JSON file - would this be too slow/large with 200,000+ entries?
I have also considered CoreData - but could the data be moved easily via, for example, email?
Think of an address book. Contacts can be easily imported/exported, what data storage model would be comparable?
Thank you.
EDIT: Examples
Notes - be able to select and view short notes in a table. Each note is < 100 characters.
Saved bookmarks - each bookmark is stored in a table.
I have considered a single large JSON file - would this be too
slow/large with 200,000+ entries?
I don't know. I can make a guess. The guess would be yes, it's both too large and too slow. However, you can always test it to find out.
I have also considered CoreData - but could the data be moved easily
via, for example, email?
That depends on how you want to share the data. You call email easy?
Core Data is a framework. You can use any type of backend you want (you can even write your own). The most common is probably SQLite.
If you use Core Data, you can keep the data files in a separate subdirectory and copy them just like any other file.
However, if you want to share data via an online service, you may want the ability to import/export JSON files.
If you are talking about synchronization, then that's a different beast entirely.
Basically, there is no single right answer. You have to assess your requirements, and then determine which solution meets your needs.
On the surface, it seems like using Core Data would be a good fit, but it depends on how you want to use the data in your application. Only you know that answer.

Fastest and light way(Sqlite or core data or plist or csv or flat file)

I have a simple problem to solve but want to know which is better pattern to use and understand the reason for the choice.
Problem :
I want to create a utility which developers can use to check whether the feature should be enabled/disabled depending on the server package version.
eg : server package versions like 10.234, 11.1 etc and client versions 9.3,10.2 etc
Validation on client to see min version on server package for feature to be enabled/disabled.
example data would be like "search lookup feature >= 10.234". And sometimes complex situation need to even check client version whether the feature should be supported.
edit:
Note: Application is very huge and memory is full for most of the time. (thousands of records of organisation data.) So memory is bottle neck.
Just it even flashed to mind to used macro as to do all comparisons and returning value.
I think Plist would be heavy as all the objects would be in NSDictionary and even to access one object, I'll be holding all data.
I want to reduce memory overhead and comparisons too.
For Light data, Use NSUserDefaults or PList. SQLite and Core Data is overkilled.
Updated Answer for Updated Question:-
For server package versions/your app version or other light weight data, you can always use NSUserDefaults or PList.
For records of organisation data, you might want to consider Core Data.
Yes, you can use 2 different types of persistent storage inside your app.
If your data is never going to change, or grow you better use NSUserDefaults, plist or csv file. If you think that user should have the ability to change or add new entries to this data file you better go ahead with CoreData
Plists, csv, and flat files have low overhead for small to medimum amounts of data (and for data where you use all or nearly all) of it.
Systems that only use some of the data on any given run AND have large amounts of data AND have the data structured so SELECT can use an index can be faster (lots and lots faster) with a database (SQLite, or CoreData with the SQL Persistant store).
As a gut feel I expect your problem could be handled well by SQL, but only if you are talking about 1000s of configurations not 10s or even 100s...but you would be better served by benchmarks then my guesses. Go code :-)

choice the database. iOS

I am making meeting app and I need to store users data. I am not need to use sql for now because it hard to setting it, so I need place to store data, I not want store users in RAM, so where can I do it? It not necessary to cache images for now, by if I can add it in this place in future it will be great.
Here is what I believe you are asking:
I am developing a meeting app and I need to store some user data.
I dont want to use sql for because its complex to do, so I need
a place to store my data. I not want use up unnecessary RAM,
so where can I store the data? I currently dont have any need
for cacheing images but perhaps in the future.
Not using CoreData/SQL because its hard to understand is not really a good reason. It was the native built in way of data access within iOS and it is the recommended way.
This is a very broad question since we dont know what your data looks like and if there are relationships between them, how large your dataset is, etc.
If its a small enough data list maybe you can look into using a PLIST. It will be a list of values with a key to each one. If its really small you can use NSUserDefaults If its static data, perhaps storing them in a NSArray or NSDictionary

iOS Map Kit Locations read from database

I have been tasked with creating an iPhone application for a client.
I have some coding experience but only in C# so it doesn't really help here but other than that I am a complete novice on iPhone coding.
What I am trying to accomplish is to get some form of store locator on a map.
I have successfully added the map, get the user location with it zooming into the user. I have added 2 annotations (Which I believe the the best way to go about showing locations on the map).
I have 2 queries that I need help with, What is the best way to go about listing the stores in some form of database. XML, PList, .sql etc... (this would also need to be read from the web as it would need to be easily edited as new stores would be added a lot). Is it possible to loop through the database and dynamically add the stores onto the map within a location of the user?
I am not asking anyone to write any code for me, I am just asking for some help as I have googled the hell out of this and cant seem to find anything that helps.
Any help would be much appreciated,
Thanks
In terms of your potential formats for saving these locations, you options include:
XML/JSON are good formats for exchanging data with a remote server, but less ideal for a local database (though they theoretically could be used for that purpose). JSON is marginally easier to deal with (using NSJSONSerialization), but XML can be relatively easily parsed, too (using, for example, NSXMLParser). If you're doing network operations, I also heartily recommend looking at AFNetworking, which offers some nice advantages over the standard NSURLConnection. This, of course, presumes that you have written a web service on your server to deliver the necessary JSON or XML feed.
Plist is a fine, simple format if you want to save a short, local list of locations on iOS devices. Saving data to a plist is as simple as calling writeToFile method for your NSDictionary or NSArray and reading data is done via [NSDictionary dictionaryWithContentsOfFile:filename] or [NSArray arrayWithContentsOfFile:filename].
Core Data is a good, iOS-specific format for larger databases. It's probably the preferred iOS mechanism for dealing with persistent objects, but is an order of magnitude more complicated than plists.
SQLite is also a good database format if you're thinking about a structure that lends itself towards larger database, but also which lends itself towards eventual rollout to multiple platforms (e.g. both Android and iOS). If you decide to go SQLite route, consider an Objective-C wrapper (such as FMDB), which will simplify your life greatly.
Implicit in all of the above discussion is that, yes, you certainly can write code that iterates through your database and/or model data structures, extracting the necessary location information, and dynamically add annotations to your map. The Location Awareness Programming Guide should help introduce you to some of the MapKit related features.
"Is it possible to loop through the database and dynamically add the stores onto the map within a location of the user?"
Yes. Just as you have created those first two annotations, you now need to create more annotations in a loop. The only additional info you might need is that once you have added an annotation to the map it will stay there until you remove it. So you don't need to maintain your own list of annotations unless you want to do something else with it. Just fire and forget. So now your question comes down to how to loop through data from your chosen data source in Objective-C and not MapKit specific.
I know this is old but if anyone else comes across this like I did, you can use tmysqlkit by tanmay bakshi to read and write directly to a mysql database on a server.
Best,
Sam

Resources