Add items to .plist from and display in custom UITableViewCell - objective-c

I want to write data to multiple NSMUtableArray's from the user pressing IBAction's that then saves the time they pressed it, Location and os on, to a .plist. I then want to retrieve the data that was written in the plist and display it in a custom UITableViewCell that I have created. There are around 8 - 10 different labels in the cell. I have already made the plist file history.plist and there are a few things in there. I need the data to go in there. And to keep writing data there, such that after the data is gathered, it will then be displayed in the custom cell within the UITableView.
Should Item 0 be a dictionary or array?
So far I have the data being saved as NSUserDefaults

well if you want to use plists like that then keep item 0 as a dictionary... However, I strongly suggest that you use Core Data instead of plists to store your data.

Related

Make UITableViewController cells not disappear when navigating away

I'm making an app that uses a UITableViewController, and fills that table view with data from a webserver.
Inside my viewDidLoad I have a method that loads data from said webserver, stores it in an array as custom objects, and then loads that into cells. This is working fine.
Problem:
However, every time I navigate away from that UITableViewController, and then back, it loads everything again. This is very unnecessary, so what I did was store a boolean in the NSUserDefaults, which keeps track of whether or not this is the first time starting the app. If it is (you just logged in), load the data from the server. If not, don't.
However, as I noticed, the tableView resets every time I navigate away from (or back to) the Controller. Also, all the arrays I stored the custom objects in are now empty, so I can't load it back from the arrays either.
(Every time I navigate back to the TableViewController, it's empty)
I tried storing the arrays in the NSUserDefaults, and then just populate the tableView with that data every time, but it turns out I can't store custom objects in the NSUserDefaults.
What I want to achieve is this:
Whenever I navigate away from and back to said TableViewController (I use the SWRevealViewController), I don't want the tableView to empty out. I want all the cells to stay, that way there is no wait time between when the view is loaded and the tableview is filled.
If this is impossible, I want the second best. To store the array somewhere in the app, and then reload that data into the tableview as soon as the user navigates back to the TableViewController. This is slower than my preferred solution, but still quicker and less data-consuming than loading everything from my server.
Any help is appreciated!
Thanks.
You should create a separate object that manages fetching the data from the web service and then stores it locally. This object can be created in the app delegate or wherever appropriate and passed to the table view controller. The data object should provide an array that the view controller can then use to populate the table. You can even have that data object start pulling from the web service as soon as the app opens instead of waiting for the table view controller to be displayed.
I do not recommend keeping the view in memory just to save the very minimal amount of time it takes to load up a table view (using locally stored data). Unless you are talking about thousands and thousands of entries, you will not notice a lag time in the loading of the view. If you are talking about thousands and thousands of entries, I recommend you load a few hundred at a time into the table.
As far as storing the data, the simplest might be just writing the raw response of the web request to a file. A more elegant solution would probably include creating some objects to represent the data and using NSKeyedArchiver. Keeping data stored locally is a huge topic with countless options so I recommend doing some googling on your own to find the best solution for you. You might start at these places:
NSKeyedArchiver: http://www.raywenderlich.com/1914/nscoding-tutorial-for-ios-how-to-save-your-app-data
Other Options: https://developer.apple.com/technologies/ios/data-management.html
If you go with the NSKeyedArchiver option, you can generate a file path by doing the following:
+ (NSString *)dataFilePath
{
NSURL *directory = [[NSFileManager defaultManager]
URLForDirectory:NSLibraryDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:YES
error:nil
];
NSURL *fullURL = [cachesDirectory URLByAppendingPathComponent:#"a_file_name"];
return [fullURL relativePath];
}
You need to store all the data in cache at first time when user is calling data from server. And after that whenever user navigate and comeback to the page load data from cache.

How to read array from UITableView and pass to SQLite

I have some problem understanding how to read an array of x elements from an UITableView and pass it to the SQLite assigning a name to it.
Like a TODO List assigned to people's name.
I have created the database, I can save (null) fields except for the name of the list, but now I do not know how can I read all the fields and pass to my SQLite. Any hint?
In PHP, I usually use a foreach, but I am new to Obj-C and I a little bit blocked.
UPDATE:
The "+" button add a new row, instead the "Save" button has to save this list to an sqlite database.
But I am blocked on how to read and save all the fields.
A UITableView is a view and should not store your data. Usually you will have a ViewController that serves as the DataSource for the table view. This controller usually holds some array of sort that stores the data displayed in the table view.
What is the data source of your tableView ? each tableView object ( witch inherits from UITableView) should have a datasource who gives it the data to display in it's view.
You can use an SQLite wrapper so save/Load easily in/from an SQLite data base. FMDB

Modifying the results of a Core Data fetch request before displaying them

I've got an application which pulls back data from a database using Core Data, and displaying it in a custom cell in a UITableView, via an NSFetchedResultsController. I'd like to randomly insert a different type of custom cell every now and then (say, between every 10 and 20 cells), which will NOT get its data from that same database, and will be a different subclass of UITableViewCell.
I'm a little stumped on how I get in the middle of the NSFetchedResultsController and the UITableView Data Source methods. I have various options which allow the data that's pulled in to be sorted, filtered, etc., so I can't rely on using indexPath or anything like that.
What's the best approach to doing something like this? I know I can access fetchedObjects of the NSFetchedResultsController – is copying and modifying that the right way forward? Create, say, fetchedObjectWithInterstitialCells, and feed all of the Data Source and Delegate methods with the contents of that array?
Is there a better way / are there alternative ways to do it? I'll need to be able to retain the ability to sort / modify / filter the data from the database, while at all times keeping these interstitial cells at that same interval of randomly between every 10 and 20 cells.
I would consider one of the following three operations:
A: Insert objects into the database that are pulled along with the other data, but has properties to differentiate them enough to display the different subclass of the UITableViewCell. Probably the easiest way out, unless you have a very difficult datamodel.
B: If you can group your data from the data store into sections by using the sectionNameKeyPath-attribute on the NSFetchedResultsController, go for the NSFetchedResultsController + UITableViewDataSource-approach, and then return [[self.fetchedResultsController sections] count] + numberOfInterstitialCells; inside numberOfSectionsInTableView:.
In cellForRowAtIndexPath you would then need to override the section-info from the indexpath in order to switch between the right object from FetchedResultscontroller and your interstitial cells. This is probably a cumbersome and difficult way to do it, but if you are on iOS6 using parentContexts, the benefit from having implemented the NSFetchedResultsControllerDelegate is awesome
C: Fetch the objects with a normal fetchrequest and put them into a mutable array in which you insert your interstitial cells, before you load your view and feed your UITableViewDataSource with this array. As easy as option A, but you won't get the benefits of having the NSFetchedResults-Controller.

Objective-C: How to dynamically create GUI objects?

I`m really new in Objective-C and Mac OSX programming.
Can someone give me simple example for the next task:
I have array of strings (for example ('one','two','three','four')) in my app GUI each string should be represented by row, each row should has Label(with text of string) and CheckBox. Number of strings in array may be different. How i can dynamically create this GUI objects?
It is like in Transmission app, when you open torrent file and window opens with list of files and checkboxes
D you want to create a table? So what you are looking for is a UITableView object whose rows will be dynamically created after you set the 'data source'(in this case the data source can be your viewController that encapsulates that string array) from which it will get the data dynamically.
You'd better have a look at some documentation about UITableView and their programming
If this is not what you are looking for, you can accomplish your goal by creating many UIView dynamically, adding content to them (UILabels, etc) and position them one after the other on the main UIView as subview calculating their frame position and dimension

Managing data for UITableViews

I have two very simple, identical UITableViews in my app that are populated with thumbnail images named "thumb1.jpg", "thumb2.jpg", etc. These thumbnails have associated original images "1.jpg" and text files "1.txt" used for image processing. Everything is stored in the app's Documents folder.
I want to keep the numbered, ordered naming for these files since it makes displaying the thumbnails in the UITableViews very easy with cellForRowAtIndexPath. I'm currently using a NSMutableArray (index: 1 object:"thumb1.jpg", etc) to track all images in the app.
The issue is that users can add/delete images so maintaining the order is important. For handling adding/deleting I'm looking at using insertObjectAtIndex and removeObjectAtIndex on the NSMutableArray, which will maintain order but will require programmatically changing image and text file names when this happens. For example, if there are five images in the array "0.jpg","1.jpg","2.jpg","3.jpg","4.jpg" and the user deletes the second image ("1.jpg") the array will now have "2.jpg" at index 1 so filenames will have to be changed to "1.jpg", "1.txt", and "thumb1.jpg".
How does this approach sound? I'm new to Objective-C so if you have other functions you'd use, etc I'd be interested to hear your opinion.
Renaming the actual image files themselves doesn't sound like a good idea.
I would implement 2 NSMutableArrays, one to hold the title/description of the image and one to hold the filename (or, if you wanted, the actual UIImage instead). Then if you need to delete, for example the item at index 2, deleting the same object from each of the two arrays will then leave them in sync.
If you start wanting more and more things to be stored for each row, I suggest you implement your own class. You can then implement an array of multiple instances of that class, and each class would have properties such as image, text, thumbnail etc. In fact, because you've already named three separate properties (main image, text and thumbnail) I'm tempted to say you should implement a custom class straight away.
Let me know if this makes sense or if you'd like some code to further illustrate it.