iOS: Running database query in viewDidLoad only works once - ios

So let's see if I can write a clear enough description of my problem...
I'm developing an application for a museum, where the user can find artworks either through an id or by scanning a qr tag...
Once either an id is entered or a tag scanned, the application sends the user from the search view, to the info view.
The info view gathers information about the artwork from an SQLite database...
My problem is, that in the info view, I call the function from the database class as such:
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *paintingInfo = [[PaintingDatabase database] findPaintingByID];
(additional code)
}
And I have no problem getting the info... works fine...
But my problem is, that if I go back to the search view and enter a new id or scan a new tag, the call/search isn't run again, since the view is still in memory...
So, how would I go about running
NSArray *paintingInfo = [[PaintingDatabase database] findPaintingByID];
every time I enter the view...?
I've tried placing it in viewDidAppear instead, but I get an EXC_BAD_ACCESS error...

I think you are close to answering your own question. Since viewDidLoad only gets called when your view loads, if you are using the same ViewController you will not get the results you are looking for. One option may be to destroy and create a new ViewController each time. This probably would be acceptable, performance-wise. Another option (that you seem to have explored) is to put your code in viewWillAppear. I would probably look into this more, and figure out what is causing your crash.

It's a bit difficult to tell from a brief description, but this feels to me like it's more of an application architecture issue than a problem with a specific bit of functionality.
You might be better off with an alternative approach, running the query from outside the info view, and then update the properties of the view through a delegate method. That's more of an MVC approach - the controller retrieves the data from the model, then passes the data over to the view to be displayed.
As you've described it, it seems like your info view is taking both view and controller functions - which could be why you're running into problems trying to get different data once the initial view is finished with.
The crash doesn't sound like a problem with the view, though - I'd second the advice to track that down and nail it as a separate issue.

Related

What is the right apporach to get data from Firebase? (on demand or everything at once))

I am setting up a friendsystem in my app.
For now, if I am in the ViewController with the list of friends, I only fetch their userdata, once it`s clicked on their username.
I am now wondering if it is better to already load all data of the listed friends, in the VC where just the list is displayed.
So that way, I can simply pass the userData-Array to next VC that shows their details, instead of loading it in the profile-VC.
What are the pros and cons here?

Preload data from xml, table view doesn't reload

I have following problem. In my app I'm downloading .xml file from server and then parsing it. I call both methods (get and parse) from application:willFinnishLaunchingWithOptions.
Right after parsing is posted notification. In main table view controller is observer and selector is supposed to reload table view. But it doesn't. ViewDidLoad in TVC is called before parsing is completed, also before launching screen disappears.
So my question is: Is possible to freeze application:didFinishLaunchingWithOption till all data are parsed? Thanks
No its not possible. What you could do:
Don't show your TVC. Show a loading Controller. This Controller will do the work with loading the data and parsing it. When its done you can call your TVC
For Example:
LoadingController has a instance of a Manager Class
The Manager downloads your file. ( Extra Communicator or something else)
Your provide success and failure blocks to the manager calls. Means, build a function with func downloadXML(success: blockStuff, failure: blockstuff). In the success your provide the parsing
When parsing is finished you show your TBV with the data
Feel free to ask or comment :)

Auto-refresh upon launch ios

I'm currently going through Bloc bootcamp for ios development and I'm looking for a solution that will reload "new images" upon launch. Essentially it needs to automatically refresh and fetch new images without the user having to pull to refresh. We are building out a replica of instagram if that helps.
It sounds like you've already got the method created to accomplish your task, so it's just a question of calling that method.
I don't know what your code looks like, so I'll attempt a "physics for poets" example:
- (void)pullToRefreshMethod {
// there might be code for configuring the view, etc. in here
// your code to refresh
}
The simplest way to do it when it loads is in your viewDidLoad on the initial ViewController. Let's say your pullToRefreshMethod does other things in addition to refreshing. What you could do is take the code that refreshes and put it in its own method.
- (void)refreshInstagram {
// your code to refresh
}
Then, within your pullToRefreshMethod, you'd call it with:
[self refreshInstagram];
and in your viewDidLoad, you could call it there, too.
Without specific code, I can't give you a specific answer, though.

UITableViewCell binding to Data Model (updates driven by FetchedResultsController)

I'm attempting to have my individual UITableViewCells: I'd love to have the initial values of the model brought over to their UI representation as well as after the user makes a change have the new UI value brought back to the model. Let's just focus on the latter first: UI changes propagating to the model.
For a little more background understanding, I'm running into an issue when adding a new item. This table is driven by an NSFetchedResultsController which sends one didChangeObject with a ChangeInsert and a second didChangeObject for ChangeUpdate. The ChangeInsert triggers an insertRowsAtIndexPaths on the table and the ChangeUpdate does a reloadRowsAtIndexPath.
Because of these two responses my table view asks for cellForRowAtIndexPath twice. This shouldn't be a problem if the same cell is disposed of properly between requests but it doesn't appear to be: I receive an assert that the property in the model is already bound to a RACSignal! I've tried any number of ways to be more explicit such as:
RAC(self.model,value) = [ [RACSignal merge:#[self.valueField.rac_textSignal] ] takeUntil:self.rac_prepareForReuseSignal]
however the reuse signal does not fire in time as it still asserts (aside, is there a recommended way to directly debug a signal like this firing?)
I've tried adding an additional takeUntil:[RACObserve(self, model) to dispose of the signal as soon as the reused cell's model is overwritten (and have it bind to the new model) and understandably this seems to result in the first value disposing. However adding skip:1 to the observe puts me right back where I am.
Please let me know if there is anywhere else I can add clarity or if you have another way to lay these things out. I'm very new to Reactive Cocoa and still learning best practices :)
Thanks!

iOS Managing Async Blocks for Remote Requests

Not sure how to best explain this - If I use blocks to load images for UITableViewCells, how best can I ensure that when an image actually finishes loading - it is the correct image for the cell. Say I'm making an app with user icons - so cell 5 is for John and it starts loading John's image. Say that request gets hung up and by the time it returns, that cell has been reused for Bill at cell 23. We obviously don't want to load John's icon - we just want Bill's.
This is a simplified explanation. I know that we can check if a cell is visible in the block before setting the image - but say in a different scenario I have a method that makes a remote request when called. When the remote request is done, it calls a block defined in that method that updates the UI. If I call it and before it returns I call it again and only want the most recent call's block executed. Is there a good pattern for doing this?
Currently, I try to store a variable that has some state in the method so that when it returns I can check if that state is still valid. Just thought I'd see if there was a better way. Thanks.
Just checking if any updates on this.

Resources