I'm building an iPhone app where most of the content is dynamically loaded from my web server. The content is updated once per day. Here's the issue I ran into when testing my app on my device. I noticed that I would just close the app, and the next day I didn't see the new content. I had to go close the app fully (via multitasking) and then go back into it to update the content.
I could use this in the app delegate:
- (void)applicationWillEnterForeground:(UIApplication *)application
but, I load all the content in each View Controller... how should I go about re-loading my data?
Also...
If I update the array of objects that the data is pulled from in the UITableView, will the UITableView update automatically?
Thanks for any help!!
Note the documentation for that method also says, "The application also posts a UIApplicationWillEnterForegroundNotification notification shortly before calling this method to give interested objects a chance to respond to the transition."
Your view controller could be considered an interested object.
Table views can be told to reloadData.
Related
For example, I have a Notification that occurs when there is an "unauthorized" error returned from the api server that should bring the user back to the login screen. This event could appear anywhere in the program.
Do I create a new viewless controller to manage states and have it monitor for this notification and then present the login view controller?
I'm thinking about push notifications too, received by the app delegate. Some of these may cause the data model to get updated and then the screen to change. Who should make the screen change? In the past I put all this in the AppDelegate. But there must be a more elegant way!
I also found out about FlowControllers. But they don't play nicely with Interface Builder, at least according to this solution.
Please let me know if you need more specific information about my project.
What I'm looking for is a mechanism to keep my app from resetting to the root view controller every time the application gets backgrounded or goes inactive. There are many apps out there that operate this way, namely Instagram, eBay, etc.
My instincts told me initially to poke into the AppDelegate's applicationWillEnterForeground method, where I would try to present the viewcontroller I'm after, however when I instantiate the viewController, I can present it, but without the navigation controller that normally be there.
This makes me think that I need to save the "state" of the application (maybe the NavigationController's stack?) and then restore the stack somehow when it gets relaunched.
I have watched the execution timings of each event and notice that closing the application and relaunching it will start the application fresh. I assume that my NSUserDefaults are still in place and thus could be checked for a logged in user. This could help determine which view in the navigation controller to push to (either login or dashboard).
Any direction is greatly appreciated.
The most revealing answer in this post was the use of some storage (NSUserDefaults) in order to store persistent data across uses.
For my specific case, this was storing a key holding user info. Then when the application loads, the would-be first view comes up, but if that key is missing, will modally pull a login view in front of it.
To do this I would use NSUserDefaults to store the current view of the app and then switch to that view when your app finishes launching. See the answers to this question: Swift: How to store user preferences?
An iOS app I'm creating shows a setup screen upon first launch which requires data to be written to the database.
Upon launch, I need to access this value form the database.
If it is set, launch main view controller
Else show setup view controller.
As far as I'm aware theres two ways I can do this, programmatically setting it from the AppDelegate or using an initial View Controller as a splash screen and performing the look up and segue there.
What would be the best way to approach this? Is it wrong to do a database lookup in didFinishLaunchingWithOptions?
Using a splash screen is probably the better option as it provides better scope for modification in the future and allows you to update the user on progress. It is fine for the app delegate to run logic to determine how the app starts but you should endeavour to keep the app delegate minimal and focussed.
I very much doubt that you would get this approved (if your goal is the App Store). Your app delegate needs to create a window, and set a rootViewController to that window before it returns YES in appFinishLaunching:
You simply do not have enough time to check with a server before creating the first viewController and you'll be creating poor interface if you try. I suggest the first ViewController will need to be informing the user that it is checking with the server with an activityIndicator or something. The best :)
According to Apple documentation, "To help your widget look up to date, the system occasionally captures snapshots of your widget’s view. When the widget becomes visible again, the most recent snapshot is displayed until the system replaces it with a live version of the view."
What I am seeing, however, is that the snapshot is removed from screen before the live view is prepared. This results in a flash effect where the old snapshot is taken off screen, the view is blank for a split second, then the new view appears.
Is the developer responsible for making the transition between the snapshot and the live view seamless? If so, what is the strategy behind doing that? I don't see any way to directly control that transition.
I was able to mitigate the effect greatly by moving data loading to
widgetPerformUpdateWithCompletionHandler: and keeping drawing in viewWillAppear:, but I do still see a flash once every 15 (or so) opens of the Notification Center.
I had this same issue and finally figured out the issue I was having with my widget. It turns out it was related to a misunderstanding about the Widget Life Cycle on my behalf.
From the documentation I thought that the today view would keep a 'snapshot' of my widgets state until the widgetPerformUpdateWithCompletionHandler method completion handler was called with success.
This does not seem to be the case. From what I can see the 'snapshot' is just used when the Today View is animating in (when the user pulls down the notification centre). As soon as the today view is loaded and stationary your widget is loaded from scratch (inflated from xib if using) and viewDidLoad is called. At this moment you should populate you widget with cached data (not from a web request). If you don't you will see temporary data from your nib. This is what causes the flashing.
When viewDidLoad is complete widgetPerformUpdateWithCompletionHandler is called which allows you to fetch fresh data. When the fresh data is fetched you should call the completion handler and cache the data it so it can be used when the widget is loaded later on from scratch (in viewDidLoad).
A simple way to cache the data is in user defaults.
You need to be careful about your compilation handler in the
-(void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler
method. What happens is that your extension probably has an error and everytime view appers it is being called again. Try to attach your extension to debugger(Debugger->Attach to Process-> your extension id) and see the result by putting some breakpoints.
I found lots of "reloadData" for TableView questions here, but my case is different.
I have a notification App, that uses UILocalNotification to fire reminders.
I need to refresh my tableview in real time after an alert fires, without the need of closing and opening the app to do so...
Example:
User is viewing the scheduled reminders (tableView), when suddenly one of the reminders fires. At this moment, the tableView will reload, but only if the user quits application or go back to another view and open the tableView again. That can't happen cause the application breaks if the user press the row in the tableView witch showed the current reminder (that's already completed and doesn't exists anymore).
I need to reload tableView in real time, without leaving the tableView Controller view. any idea on how to do that?
When a local notification for your app fires while the app is in the foreground, the system sends the application:didReceiveLocalNotification: message to your app delegate. From there, you should notify the view controller (via a direct reference and message send or possibly with a custom NSNotification) to do whatever it needs to do in this case.