Where/how/when ought I initialize my second parser?
What is the best configuration of views/viewControllers for what I describe?
Here's the deal:
I have a tableViewController. I have it populated with data from a parsing class that initiates in the appDelegate method, applicationDidFinishLaunching... This class runs through an XML file I created.
Each item populating the tableViewController are associated with a URL, which will be parsed as a row is selected inside the tableViewController's didSelectRowAtIndexPath method (is this the right thing to do?).
The results of the second parsing are to populate the detail view with titles of the items from the selected url of the second parsing. I would not be writing this question if it were that simple. I need to be able to pick an item populating the detailview and drill to another detailview showing the details of that item.
Im using nibs
This is not a discussion question:
Where/how/when ought I initialize my second parser?
What is the best configuration of views/viewControllers for what I describe?
Is there anything glaring I must know?
There are two options
1.)parse data as soon as tableviewcell is selected then once finished load detail view with results. (con can slow interface down)
2.) load detail view and then parse data and populate details as data becomes available (con loads details view with no data and makes user wait)
So both options make the user wait but only one slows the interface down...
I think option 2 is the choice everyone will recommend.
Related
I'm using a cocoa pod called ACTabScrollView. In the demo code, it has a View Controller for the UI part which scrolls from side to side and has different tabs, and a view controller that has a table view (a "content view controller"). Each tab displays different information on each table view, but the information is sourced from a single array and is divided via an assigned enum. If this is confusing, there is a gif on the ACTabScrollView readme. In my "content view controller," I can hard code an array and it works flawlessly. The class for this content view controller has a variable declaration that I've never seen before as I'm new to iOS programming.
var category: TeamCategory? {
didSet {
for team in Team.teamArray {
if (team.category == category || category == .all) {
teamArray.append(team)
}
}
}
}
A project sample with this snippet is located here.
In the above snippet, Team is a model of teams, and the class has a hard coded array of teams (which are structs).
Obviously, I don't want to hard code the array of Teams in the app because I want to be able to update the array and have it update in real time. I'm using Firebase and I've tried loading the array in the App Delegate, in the UI view controller, and in the content view controller, but the tableView does not populate. I've confirmed that the data is arriving.
When/Where should I load the data from Firebase? The content view controller needs the array loaded before the view controller is loaded. Any tips for this would be much appreciated.
When you should load the data from Firebase is a design decision. You said that the content view controller needs to have the array loaded before the view controller is loaded, so you should request that data from Firebase at some point in your app flow where you can be guaranteed that the request will have come back with data before your TableView is attempting to load that data.
You may be running into a race condition where you are requesting the data, and then going to the content view controller before the request finished.
In general you don't want to have to rely on a guarantee that a request will finish in time, so I recommend doing what #rmaddy suggested, where you load the data before hand, and then have some sort of completion handler / notification / delegate call that will call reloadData on your tableView once the array from which you are pulling your data is updated.
The project sample you are referring to does not handle an asynchronous case, as you are handling. The didSet in the property declaration is just a closure that gets executed when you set a value for that property. In the case of the project sample, the news category is set at the time of the view controller instantiation, and then the didSet executes once and attaches the appropriate news array for the tableView to access. Again, in your case, as long as you are updating your array that contains your tableview's source of data after the data returns from Firebase, calling reloadData on your tableView should achieve the result you are looking for. If it doesn't, then that means you aren't properly updating that teamArray.
I have a section in my app where I would like to display static content that is divided in short chapters (mostly text and some figures), for example a manual. The questions is: what's the best way to do this?
I was thinking of a static TableViewController containing my chapters, which on click lead to a ViewController containing the actual content. However, having a segue for each of the TableView cells to my ViewController seems wrong. Also, what is the best way to embed the static content in my ViewController? The content consists (depending on the selected chapter) of text and figures, taken from a PDF.
You are describing a totally standard vanilla boring everyday 5-cent master-detail interface.
The thing that's wrong with your drawing is the use of multiple segues. You only need one segue — one that looks at which row was tapped and loads the data corresponding to that row into the view controller that is then instantiated and pushed onto the navigation controller.
If you create a new iPhone app from the Master-Detail template in Xcode, you'll see a standard setup for doing this sort of thing.
As to the question of static vs. dynamic, personally I'd recommend a normal code-based table data source for this. Your data may be static, but most table data is, ultimately; that doesn't mean you'd want to use a static table. The key is simply to store your data in a format that can be loaded at launch time and parsed quickly into a data structure that is precisely adapted to the way the data is to be displayed and related.
I'm very new to swift programming. I have been playing around with this for a while, but I am not getting anywhere so asking here.
I have a tableview which I can load the data into the view from CoreData no problem. I have an ADD button at the top that segue's to a new tableview, with a long list of options they can pick from. This tableview also works fine, and includes a search bar.
When the user selects an item row from the second tableview, it inserts that item into CoreData and segue's back to the first tableview. This is where my problem is, the data does NOT update on the visible view.
I call tableview.reloaddata() and I can see my code calling the fetchedResultsController with the new query that would return with the new data. But the code never gets to the cellForRowAtIndexPath func so therefore the visible data view never changes. It remains the same display that was visible when the add button was pressed.
How does the visible data get updated? What am I missing?
When using an NSFetchedResultsController, if you want it to "automatically" update the contents of the tableview then there are a couple of things you need to make sure of...
You have to become the NSFetchedResultsControllerDelegate and implements the methods necessary for the updating of the table view. These are quite lengthy and can be found on the Ray Wenderlich website. The code on here is in Objective-C but it's fairly easy to convert to Swift.
The second thing you need is to make sure that the core data update is done on a background thread. Again the website linked above shows this.
Once you've done that then you don't actually need to run [tableview reloadData] because the fetched results controller methods will manage everything for you.
I am having a basic question for like best practise.
The setup:
ListViewController:
UiTableView with ManagedObjects. The objects will be loaded from a server.
First load 20 objects. Scroll to the end of the table, the next 20 objects will be loaded.
Selecting a cell will load the DetailViewController.
I have a ListObject with an array of the items (and other properties with informations about the list, not relevant for the DetailVC)
DetailViewController:
The details of the selected object are shown. The VC also has 2 buttons to show the next object details or the previous object.
Now e.g. there are 20 objects loaded in the ListVC and I select row 10, the
DetailVC with Object at index 10 will show.
Then I click trough the next objects until object number 20.
Now when i click the 'next' Button, the next 20 objects have to be loaded from the server.
(Show object #21 but there are only 20 objects loaded).
Is there a best practice to load the next objects?
I have a class for data loading.
- (void)loadDataWithRequest:completionHandler:
When the NSUrlSession DownloadTask finishes, the completionHandler gets called and this calls the class ApiParser for json parsing and adds the result to the List Object.
So i have to call this in the DetailVC for the next 20 objects.
Now what is the best practice to do this? Or is there a better way to implement the data loading?
I could pass a ListVC reference to the DetailVC and call [listvc loadDataWithRequest:completionhandler] and load the detail from [listvc.listobject.items objectAtIndex]
Or i just could pass the ListObjectItems to the detailVC. Somehow load the new objects and
have a KVO to the ListObjectItems count.
Other methods would be delegates or NotificationCenter.
But i guess the best practice is not to put the loadData Method in the ListVC, but somewhere else.
How about to put the dataLoad method as instance method in the ListObject class and listen for the KVO in ListVC and DetailVC?
So many possibilities. But what is a good way?
When the "next" or "previous" buttons are pressed you could inform the "master table view" of the action. This would then load the next batch if necessary before presenting the detail view. Don't block the UI though, show a spinner or something in the blank detail view while waiting for the next batch to come back.
In summary: don't put any loading logic in your detail view. It should only be responsible for displaying the "details" and possibly a loading spinner if you tell it to display nil (as in, not finished loading yet).
Ideally, you would handle the data to be diplayed, in this case the ListObject, seperate from the view controller which is displaying the data, in this case the ListVC or DetailVC.
Each VC should then keep a reference to the data source, which could be a class holding the ListObject, called ListDataSource. This class should hold the methods for loading data from the server. Then, each VC can tell the ListDataSource to load 20 more objects.
This delegation of responsibilities is a pretty good example of a common programming paradigm called MVC. More on that here.
Sorry for the late response and thanks for all the replies.
I now have a ListObject method to load the next data.
And in the ListVC and the DetailVC I use KVO to listen to changes to the ListObject.
Works good so far...
I'm new to CoreData, and my problem is that i want to make an NSManagedObject from a ViewController Class that has a table view, basically i want to save an object inside a tableView "every time the user adds a cell", but that ViewController is presented from a tableview menu, "object at index", the question is, how can i save data for that
ViewController from my AppDelegate? or how can i access that ViewController From my AppDelegate...
Here's an image of my Storyboard and somehow explaining what I'm trying to achieve.
Thanks!!
I've read through your question ten times and i don't seem to be understanding it fully.
From what i understand you want to save the data into core data from the bottom tableviewcontroller which is a UIViewController with an UITableView as a subview.
I don't see how that should be difficult unless i understood the problem wrong.
The basic Xcode template for an iOS project using Core Data implements the initialization within the app delegate but relying on the app delegate as a connector is something i don't do. I always abstract that information into a singleton which can be accessed from any class that implements that logic.
Also the basic Xcode template for a core data project also contains logic for adding entries within the tableview so i would recommend looking at that.
If you want specific example source code i can do that but i recommend looking at the core data template.