iphone: Caching an NSMutableArray? - iphone

I'm currently writing a Twitter client for iPhone and need a way to cache the public timeline. The data fetched is stored as 'Status' objects in an NSMutableArray.
The NSMutableArray stores 20 objects at a time.
What is the best way to do this?

You will probably want to use Core Data. You'll need to create an entity for each tweet, and then store that in your database. There is quite a lot of documentation and sample code on Core Data out there; start at Apple's Samples page.

If you don't want to play with one of the frameworks already mentioned (SQLitePersistentObjects and CoreData), you could implement your own using the NSCoding protocol on your status objects. The array should already implement NSCoding for archiving/unarchiving.

If you want to start quickly try SQLitePersistentObjects.

If you never plan to go over 20 objects you could (slightly) violate some rules from the gods of apple, and use NSUserDefaults - likely the easiest one to implement, but as the name implies, made for things like user settings, so don't use for big piles of info.
Disclaimer: If you know how to use the others, use them, this one is kinda the lazy way if you don't want to learn something better but more difficult.

Related

What are some advantages of using Core Data? (as opposed to plist)

I am relatively new to iOS and programming, and I made an app before, but it used a plist for storage, which I saved to the documents folder. Now, I am thinking about switching over to Core Data, but it looks a little complicated, and I'm not sure if it will work for what I want. I am going to have a bunch of data which I need to graph, so I'm not sure if Core Data is best for this, as it seems that I cannot create an array type in the .xcdatamodeld file. What are some other advantages of Core Data? Is it faster? Easier to use (once you set it up)?
Update: For anyone wondering, I finished the app, and it was totally worth it to learn how to use Core Data, and it was a lot less complicated that I originally thought. Doing it with plists would have been hell. The way they go about doing it seemed a little cryptic at first but if you just start using it you will get it. The relationships are really what is awesome about it.
A few advantages off the top of my head:
Much better memory management. With a plist you must load the entire thing into memory; with Core Data only the objects you're currently using need to be loaded. Also, once objects are loaded, they're normally placeholder "fault" objects whose property data doesn't load until you need it.
Related to the above, when you have changes, you can save only the changed objects, not the entire data set.
You can read/write your model objects directly instead of converting them to/from something like an NSDictionary.
Built-in sorting of objects when you fetch them from the data store.
Rich system of predicates for searching your data set for objects of interest.
Relationships between entities are handled directly, as properties on the related objects. With a plist you would need to do something like store an object ID for a relationship, and then look up the related object.
Optional automatic validation of property values.
Data models don't use arrays, but "to-many" relationships are modeled as sets.
It's a matter of what you're saving. For simple strings, arrays, dictionaries, it's fine to use a plist. For something more complicated (data, images, non-object information) or something with to-many relationships (think relationship between song to album, or photo to photographer), then something like a more robust solution might work better like SQLite.
CoreData is an objective-c-based wrapper around SQLite. If you think you might want to something more complicated, CoreData might be the way to go.
If you need a quick tutorial, I'd check out: http://www.raywenderlich.com/934/core-data-tutorial-getting-started
This got me going and allowed me to learn the basics the workings of CoreData.
Good luck!

How to create a persistant iphone cache

So I have been doing lots of reading and found out NSCache is not persistent which is a slight problem for what I need to do. I have heard that I will need to use Core data instead... but I don't have any experience with core data so am wondering if its the only solution for persistent data.
The app will allow the user to search through a catalog, by typing in a search parameter in the code and select a distributor for their search parameter. What I want to do when the app loads is download the list of distributors and save them to a "cache" the will be persistent (till when the header I will make at some point changes and demands the app to update the cache), so that if the user turns the app of or the phone next time then open it the manufacture.
Now that I'm getting abit deeper into my app I'm getting abit lost in things for instance how would setting up a cache work with regards to NSURLConnection.
Any suggestions or code examples would be greatly appreciated..
This previous answer of mine might help you decide.
To sum it up:
If your data is small, static and low-complexity, use a collection class and write it to disk using the built-in class methods
If the data is static, low-complexity but large, SQL may be a good solution especially if you already know it.
If the data is dynamic and complex regardless of size, then Core Data is your best choice.
Viewed purely from the technical perspective, Core Data is always the best choice for iOS/MacOS API apps. Core Data is not just a persistence API, it is an API for creating the model layer of the Model-View-Controller design paradigm that the Apple API uses. It not only persist the data, but models it, validates its and provides an easy interface to the rest of the API.
If your going to be writing iOS apps, you need to eventually learn Core Data. However, it does have a learning curve and you should pick the method right now that will let you ship a usable app.
You can also check out sqlite. Here's another question that discusses getting started with sqlite on the phone: Where's the best SQLite 3 tutorial for iPhone-SDK?
The advantage to sqlite is that it is fairly easy to pick up. The downside is that you have to write queries for everything, and that can be a pain. It doesn't save objects, just data, numbers or text.

Iphone, for regularly updated data is NSUserDefaults still the easiest option?

I have been designing my app to store local user data which is changed / sorted and referenced regularly to be stored as global variables held by the app delegate and referenced through:
appDelegate = [[UIApplication sharedApplication]delegate]
Which seems to work though is most likely not best practice, is there any downsides to just holding the same data in NSUserDefaults, SQL Lite seems a bit heavy for my needs considering the data itself is a couple of small arrays of custom objects and is refreshed on start up and throughout the app.
Is there a general best practice for local storage, or does it really depend?
I recommend using Core Data. Although the first experience may be a little confusing, the investment will be worth it.
What you're doing is fine. A better practice would probably be to have a singleton class that contains all the related data. Then anywhere you need the day you just call [[globalData instance] arrayOfData] and have it. That way you abstract the data from your app delegate into a centralized place.
NSUserDefaults is used to store information between app launches. Use it to store settings or things that you read each time the app launches or use it to save the state of the app so a user can relaunch and be in the same place after they exited. There isn't really any noticeable performance issues unless the data you are storing is rather large.
for my needs considering the data
itself is a couple of small arrays of
custom objects and is refreshed on
start up and throughout the app.
As your current requirements are limited to small arrays and custom objects, NSUserDefaults could be used.
But while using NSUserDefault we should take care of these two facts.
1.) For custom object you will need to use Encoding Protocols for directly saving them using NSUserDeraults.
2.) NSUserDefaults some times shows strange behavior if we don't synchronize it properly. you can use its `[NSUserDefaults synchronize].
Core Data should be used when you are working many with interrelated custom objects. Because its concept of object relationship mapping and direct object management is quite good.{at lower layer it uses SQLite}.
SQLite on the other hand is relatively easy to implement and has C api for interaction with system. Here you will need to break down custom object into attributes and run queries.

Store Data on Objective-C

I would simply like to create a file that stays around after the program quits. I would like it to contain objects that I have initiated, is that possible? Or does it just have to have text in it? How can I access that file later? Also, is this done the same way on the Mac and the iPhone?
Take a look at Core Data or SQLite. Apple has some sample code for them, not sure about SQLite because they prefer you tou use core data.
I will direct you to this question. Adding core data to my iPhone app
Or use NSUserDefaults: Best way to save data on the iPhone
Yes! It's possible.
Derive your objects that you want to persist from NSCoding. On those objects, implement the initWithCoder and encodeWithCoder functions on those objects. In these functions, write all of your primitive types to the coder (or read them) using the functions here http://developer.apple.com/library/ios/#documentation/cocoa/reference/foundation/Classes/NSCoder_Class/Reference/NSCoder.html
When you want to save your file, use an NSKeyedArchiver and pass in the object you want to archive along w/ the file name.
[NSKeyedArchiver archiveRootObject:root toFile:string];
More examples here https://stackoverflow.com/questions/2805026/iphone-problem-in-saving-file-using-nscoding
I have used SQLitePersistentObjects in the past to give my Objective-C class objects an ORM-esque feel and behaviour. The objects itself translate into corresponding tables in the database, which in this case is a simple SQLite database file.
Archives and Serializations Programming Guide might be interesting as well.

ORM on iPhone. More simple than CoreData

The question is rather simple. I know that there is SQLite. There is Core Data also. But I need something in between. More object-oriented than SQLite API and simplier than Core Data.
Main points are:
I need access to stored entities only by id. No queries required.
I need to store items of a single type, it means that I can use only one table if I choose SQLite.
I want automatic object-relational conversion. Or object-storage if the storage is not relational.
I can use object archiving, but I have to implement things (NSArchiver).
But I want to write some kind of class and get persistence automatically. As it can be done with Hibernate/ActiveRecord/Core Data/etc.
Thanks.
Everything you've said you want here is completely compatible with Core Data. Apple's giving you a solution that meets your stated needs exactly, so why are you trying to avoid it?
Beyond BNRPersistence, which Alex points out, I don't think you're going to find anything that maintains object relationships, yet is simpler than Core Data on the Cocoa platforms. An object wrapper around SQLite like FMDB still requires you to manage relationships in your own code.
Maintaining relationships between objects is a non-trivial task, which is why you see so few of these frameworks out there. Core Data gets it right for many people, so there isn't that much motivation among developers to build an alternative to Apple's solution. BNRPersistence was created out of Aaron Hillegass' long-time frustration with certain aspects of Core Data, but many people (like me) are perfectly happy with the way Core Data does what it does.
You might also want to look at Core Resource, a newer framework that provides some wrappers around Core Data to make common tasks easier.
You might consider a non-Objective-C approach to serializing objects, just as XML or JSON, where you don't have to write serialization code, if you don't want to, because the framework does it for you. For example, put your objects into a key-value attribute pairing with NSDictionary (via a wrapper class or whatever) that points to another record's id key, and then encode the mess with json-framework's JSONRepresentation call. You'd probably need to do your own relationship integrity tests, but voila, instant relational database.
Take a look at BNRPersistence.