Should I use SQLite to add this feature? - objective-c

I need your advise on this, I'm currently developing a kinda family application.(Everything relates to the family)
I would like to add something similar to a family tree or the family members. (Using Table view) and each member/element on the list will have its own "view" containing a 50 words biography about him and his photo.
Since, I'm still new to iOS development and I still haven't worked with SQLite yet. Do you guys think SQLite is the best for this job? How about the photos. Is there a way to put a thumbnail photo for each member?

SQLite does this well, though Core Data is generally considered the preferred iOS technology. There are a few situations where I might advise using SQLite over Core Data, but you haven't outlined any app requirements that would make me lean that direction.
If you do your own SQLite, though, I'd suggest you use something like FMDB, so you spare yourself the hassles of writing SQLite code.
And, as I mentioned in the comment of another answer to this question, regarding images in Core Data or SQLite, you face a significant performance hit for that. If you're dealing with small images (e.g. thumbnails), it's fine, but if you're dealing with a lot of large images, you really might want to consider storing them in some directory structure under the Documents folder (and then store relative path names in your database). It not architecturally elegant to take the images out of the database and use the Documents folder, but for performance reasons you might want to do precisely that.

No. I would use CoreData for this. CoreData gives you the graphical modelling tools to build an object model and handles all the tedious housekeeping required to persist your object graph to disk.
The photos you would store as conventional files on disk and be modelled by a CoreData object that maintains a reference (URI or file path) to the photo.

I would use CoreData for this, it boils down to an SQLite database, but Apple have added their own wrapper round the SQLite database, making it really simple to use.
There are a number sample apps on the Developer Site as well as numerous Tuts available just by searching the phrase "CoreData example" in google, the link here is ro Raywenderlich which is a good place to start. I think once you go through this blog you'll be using CoreData more and more when you need to store things like this.
With regards to the thumbnail storage I would store those on the device and save the path to the file in the Database.

Yes you can use SQLite for this; in fact it's ideal for holding a family tree given its relational nature.
The photo data can be serialised into a byte stream (NSData *) and stored in a column as a blob.

A database has the huge pro, that you can keep everything stored at one place.
You could (not that I recommend) also use a folder-structure to specify the data like /images/, /words/, /people/ and use the same name for everyone throughout the folders (tim.jpg, tim.txt, tim.dat )
Or use a small database to store everything in different tables all with relation to your "family(_members)" table.
You can also store images in a database, mostly as a blob (or base64 encoded or or or... yuck)
I don't know how well iOS stuff handles those database types of SQLite but you should be better of using a database for that.

You have a number of options here.
If you are storing all of the info within the application itself (ie. the details aren't being fetched from the web somewhere), SQLite (as a CoreData backend) would probably be a good idea. Read up on using CoreData so that you don't end up reinventing the wheel, and so that your implementation provides a smooth scrolling experience that iPhone users expect.
The photos, however, need a different means of storage/retrieval.
A common technique is to implement a 2-level cache system. What this would entail is storing the pictures in individual files, but keeping some of them in-memory after they are retrieved for speed. You could then have a class that looks something like the following:
#interface ThumbnailManager : NSObject
{
id<ImageCache> _imageCache; // You make this.
}
- (UIImage *)imageForFamilyMemberWithName:(NSString *)name;
#end
That's similar to something I would do in your position.
Good luck!

Related

Saving Data - Core Data vs plist file

I'm writing an iOS applications that saves Music albums(just an exercise I'm doing for the fun of it) .
For every Album there's a singer, song names, time, and a picture
The final result will be a lot of objects with a lot of details including a picture attached to every object. Should I even consider doing something like that with plist? (can pictures be stored in a plist?)
What's the best way to save and access that data?
I'm new to iOS and from the training videos I've seen Core Data is not recommend for the beginner user. Is that really the case?
If I'm going with plist, should I create one plist for every genre for example rap.plist , rock.plist etc' or just a big data.plist?
Thanks
I would go for core data. If you choose the right template when you create your new project in xcode then reduce the once-off overhead work significantly.
With that simple structure I would say that the templates provides nearly everything you need. Just define your model and layout and off you go.
There is just the images where I would spend a bit more time in thinking it over. I personally never put the image data into core data itself. I rather stored them as file and within my core data model I just stored the path and filename to access it. As file name I simply used a timestamp. You could use some auto-increment or other unique id technique but a time stamp would do as well. It will not be visible to the user anyway.
I think the best way you can do this, since you are new to IOS is by using sqlite. Save all the information you want in your local database and display it on the screen.
You can use plist if you have data structure that is small.
Note that property lists should be used for data that consists primarily
of strings and numbers. They are very inefficient when used with large blocks
of binary data. A property list is probably the easiest to maintain, but it will be loaded into memory all at once. This could eat up a lot of the device's memory.
With Sqlite you will easily be able delete , edit, insert your data into the database.
Core data also uses sqlite for data storage only it helps you to manage your data objects, their relationships and dependencies with minimal code.
And since your are new getting started with core data would not be such a good idea i think.. so i would suggest start off with normal sqlite. Save the data in one of your folders of your app and store their path in the database.
You dont have to write different plists.. You can use the same one if you are using.
EDIT : here is a link that will help you with learning sqlite
http://www.iosdevelopment.be/sqlite-tutorial/
you need some more code to set up the core data stack (the store coordinator, the store, the object model, and a context)
it is a tad more complicated but that shouldnt scare you off.
Reading a plist is indeed dead easy but while good for smaller data (like the info.plist) it doesnt scale and soon you need a fullblown DB
As you edited your original question an decided to go with plist now.
In that case I would go for one plist per ablum and one overall plist for the list of albums.
You could, of course, use more plists for categories etc.
However, if you are thinking of data structures like categories you are far better off with core data. Especially when it comes to searching.
No one seems to be mentioning SQLLite, I would go that way and for reasons that I explain here ( https://stackoverflow.com/a/12619813/1104563 ). Hope this helps!
coredata is a apple provided persistant tool, while plist is XML file. The reason why core data is not recommended for beginner, I think, is core data is more difficult than plist from programming perspective. For your application, obviously core data is more suitable. But alternatively, you may also use archive file, that's between core data and plist.

What are the downsides of plain text files as configuration files with only a few values in iOS?

Why use plists and xml files? If I only want to store a few values, is it okay to use plain text files or does this go against Objective-C best practices?
-------EDIT-------
I'm not sure if this should go in a separate post or not, so I'll just put it here...
If I'm making an app where a user can design a cupcake and save it with their preferences (color, flavor, size), which method should I use. I imagine my users aren't going to make hundreds of designs, but some will inevitably make a large number.
I'd say it's fine, but considering how easy they make it to read plist files, my question would be why bother?
The main reason that plists are commonly used is because the native APIs can handle these easily. You can load a NSArray/NSDictionary directly from a plist with one command.
SQL databases are used when you are going to have many occurrences of similar data. For example, if you need to record contacts for a social app, you would use a database that could contain the id, name, age, gender, phone number, email, etc.
Other than these, there are custom binary formats, but these are specialized for whatever project is being worked on. Depending on what you need to accomplish, a text file could work for you, but there may be better answers. There is nothing wrong with using text files, but these are not commonly used as you would have to write your own methods to parse them. Really, I would need to know more about what type of data you will be storing before I could tell you which option would be best.
An edit to answer your edit:
For this, the best thing to do would be to use a SQL database, as every cupcake is going to have various properties, such as name, type of cake mix used, type of frosting, color of frosting, sprinkles yes/no, etc. This is perfect for a SQL database, because dbs have named colums (ie "name", "mixType", etc), and each row in the table will have different values for each of these columns.
This could also be implemented with a plist, but it wouldn't be as efficient, and it would use more disk space (although not much if youre just using it for cupcakes). I assume that you have a Cupcake class, so you could just implement a load function like this:
+(id)cupcakeWithContentsOfFile:(NSString*)file {
if((self = [super init])) {
NSDictionary* plist = [NSDictionary dictionaryWithContentsOfFile:file];
self.flavor = [plist objectForKey:#"flavor"];
// Etc.
}
return self;
}
This is an interesting question. I actually have an app out there that DOES indeed use simple text files for data that the app uses. Because the original code came from a windows / mac program, and I wanted to keep the data files consistent, Windows doesnt provide pfile type operation. I wrote all of the code on windows to read in the files, and since it was all ANSI-C it transported to MacOS X quite nicely.
When it came to porting it over to the iPhone and iPad, it still was just as easy to port the code then to re-write not only the data files into PList format, but also the PList reading code.
For All apps that I have begun from scratch that arent windows bound also, I have used PLists though.
This is actually an issue that I go back and forth on. PList and / or XML reading and processing is certainly NOT going to be as high of performance as a well designed text file format as both are bloated due to all of the excess tags that may or may not be necessary. If you are trying to develope a single data file that has many types of data, than this could be the simpler approach, but if you are looking for less datasize, and maybe faster execution, then formatting your own file may be much better. I know this isnt a definitive answer.
So in the end, it isnt a "best practices" sort of thing, but really a preference type of thing.

Provide example for why it is not advisable to store images in CoreData?

this question has been asked many times, I have read many users telling that it is not advisable to store images in a DB, in particular within CoreData. By they all seems to omit the reason why they would do so. Even Apple documentation state this, and everybody points to that direction, and every discussion end like this "well you can, but storing the path is better".
Apart from opinions, I would like to have a concrete example of why it is not a good solution.
I explain better, I have a strong background in building Web Application. A concrete example I would give from my point of view could be: do not store images in a DB, but rather the path to them, because you can have them served them by the web server, which can apply all of its caching issues.
But in a desktop environment, especially in iOS application, what are the downside of having stored in Core Data using sqllite, providing that:
There's a separate entity holding the images, it is not an attribute
of main entity
Also seems to be a limit of 100kb for images. Why ? What does happen with a 110,120...200kb ecc ?
thanks
There's nothing special about what Core Data normally does here. It's just using an SQLite database. You can put large blobs of data into it, but it just doesn't scale all that well. You can read more about it here: Internal Versus External BLOBs in SQLite.
That said, Core Data has support for external blobs which in Core Data terminology is called stored in external record (iOS 5.0 and later). Again, there's nothing magic about it, it's just storing the large pieces of data in the file system separately from the SQLite db itself. The benefit is that Core Data updates all this for you.
When you're in Xcode, there'll be a checkbox called Allows External Storage that you can check for Binary Data properties.
The filesystem, and the API:s surrounding it is (just like a webserver) optimized to serve files, of any size, and to apply caching where appropriate.
CoreData is optimized for handling an object graph with tiny pieces of data, like integers and short strings.
Also, there are a number of other issues that tend to creep up on you, like periodically vacuuming the SQLite database CoreData uses, or it won't be able to shrink, just grow.
Leonardo,
With Lion/iOS 5, Core Data started handling file system storage of large BLOBs for you.
The choice is really determined by how many images you are going to have open. If you have many, then you should keep them in the DB. Why? Because you only have a modest number of file descriptors, one of which is used for each open image stored in the file system.
That said, there is still a reason to manage the files yourself. If your BLOBs are really big, say 2+ MB, you will want to map them into memory and not just read them in. (When the memory warnings come, this lets the OS automatically purge them from your resident memory. This is a very good thing.) Even so, you still have the limited number of file descriptors problem.
Andrew

Objective-C best choice for saving data

I'm currently looking for the best way to save data in my iPhone application; data that will persist between opening and closing of the application. I've looked into archiving using a NSKeyedArchiver and I have been successful in making it work. However, I've noticed that if I try to save multiple objects, they keep getting overwritten every time I save. (Essentially, the user will be able to create a list of things he/she wants, save the list, create a few more lists, save them all, then be able to go back and select any of those lists to load at a future date.)
I've heard about SQLite, Core Data, or using .plists to store multiple arrays of data that will persist over time. Could someone point me in the best direction to save my data? Thanks!
Core Data is very powerful and easy to use once you get over the initial learning curve. here's a good tutorial to get you started - clicky
As an easy and powerful alternative to CoreData, look into ActiveRecord for Objective-C. https://github.com/aptiva/activerecord
I'd go with NSKeyedArchiver. Sounds like the problem is you're not organizing your graph properly.
You technically have a list of lists, but you're only saving the inner-nested list.
You should be added the list to a "super" list, and then archiving the super-list.
CoreData / SQL seems a bit much from what you described.
Also you can try this framework. It's very simple and easy to use.
It's based on ActiveRecord pattern and allow to use migrations, relationships, validations, and more.
It use sqlite3 only, without CoreData, but you don't need to use raw sql or create tables manually.
Just describe your iActiveRecord and enjoy.
You want to check out this tutorial by Ray Wenderlich on Getting started with CoreData. Its short and goes over the basics of CoreData.
Essentially you only want to look at plists if you have a small amount of data to store. A simple list of settings or preferences. Anything larger than that and it breaks down specifically around performance. There is a great video on iTunesU where the developers at LinkedIn describe their performance metrics between plists and CoreData.
Archiving works, but is going to be a lot of work to store and retrieve your data, as well as put the performance challenge on your back. So I wouldn't go there. I would use CoreData. Its extremely simple to get started with and if you understand the objects in this stack overflow question then you know everything you need to get going.

Objective C Data Caching on iOS

I am pulling data from an API and then building out my data objects with it. I want to cache this data for the future. I have been storing the string from the api in NSUserDefaults and then re-parsing it each time the app loads. This works, but it really seems like the wrong way to go about it.
How can I do this?
Have you noticed the NSCache?
An NSCache object is a mutable collection that stores key-value pairs, similar to an NSDictionary object. The NSCache class provides a programmatic interface to adding and removing objects and setting eviction policies based on the total cost and number of objects in the cache...
Personally I'm quite fond of the EGOCache classes, I use them quite a lot in my projects:
https://github.com/enormego/EGOCache
The classes are easy to use, I used to have my own classes with a similar design, but these are just more well-rounded, so I decided to stick with them (don't wanna reinvent the wheel).
There are many different solutions to this problem and there is no "right" way to do it. A few popular options are:
Core Data - Apple's framework for persistence. Very performant, but more difficult.
SQLite - Fast and flexible, but bare bones.
Plists - Basically writing a file to disk, you have to read and write manually.
NSUserDefaults - The lightest weight "key-value" option.
I would encourage you to read up on all four and see which one works best for you.
I vote Core Data
What type of data? If its text/string bases SQLLite would probably be the best.
I'd store the computed/parsed data in either a Core Data store, or in NSData flat files in your application's Documents directory. You're correct that storing that in NSUserDefaults and then re parsing feels a little overkill.