how to call function from another class and reload that view from the current class? - iphone

I am working on an application which uses bump technology.I do have four tab in which one is a table view .I wrote this bump API in app delegate class so that when the application is open it should be able to transfer the data.Transfer function is working properly.But the problem is that I am inserting the data into sq-lite and the data from sqlite is displayed in one of the tab bar item view.So when the user selects this tab bar item and receives the data i would like to insert and also reload the view with the new changes.As told before insertion i working.But the problem is reloading the view.Can any one help me with this problem?

You can perform insertion in background using NSOperation and post notification whenever you insert/edit a record. Add listener to the View controller where you are displaying data.
So whenever the controller receive the notification, it will call the method to reload data from database.
#implementation MyClass
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (id) init
{
self = [super init];
if (!self) return nil;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(reloadData:) name:#"COREDATA_OBJECT_EDITED" object:nil];
return self;
}
- (void) reloadData:(NSNotification *) notification
{
if ([[notification name] isEqualToString:#"COREDATA_OBJECT_EDITED"])
{
//load records from database and reload tableview
}
}
#end
//Method where you are saving data objects in some other class
- (void) saveDataObject
{
//Save Data object, if saved successfully then post notification to listener to reload the data
// All instances of MyClass will be notified
[[NSNotificationCenter defaultCenter] postNotificationName:#"COREDATA_OBJECT_EDITED" object:self];
}

Related

iOS How to tell the App Delegate to present a new view from the current view

I have an iPhone application that receives notifications when the user is not currently using the application. When the user clicks on the notification, they should be brought to a new view when the user opens the application as a result of opening the notification.
The delegate method within the App Delegate I will use to pass my information from the notification is:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
//Pass my data from JSON Payload in here
//Tell current view to go to new view
}
I believe that a reference to a last view controller the user was interacting with before exiting the application would be a method to go about it and storing the Object in NSUserDefaults.
Any suggestions on how I could implement this would be appreciated.
try it with the NSNotificationCenter :) register an observer where the push should be done and fire a notification from your appdelegate. take a look to this tutorial for registration and firering ;)
// AppDelegate
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
//Pass my data from JSON Payload in here
NSObject *obj = myInformationForTheReciever;
[[NSNotificationCenter defaultCenter] postNotificationName:#"goToView" object:obj];
}
-
// MyViewController
-(void)viewDidLoad
{
[super viewDidLoad];
// do your stuff
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(goToView:) name:#"goToView" object:nil];
}
- (void)goToView:(NSNotification*)notification
{
NSObject* myInformationForTheReciever = [notification object];
// do stuff with that
}

Call [tableView reloadData]; on a viewController from a modalViewController

I have a modalViewController that comes up over the top of a viewController with a tableView. When the user clicks a button on the modalViewController I want to reload the tableView within the viewController with this:
[tableView1 reloadData];
I do not want to put the reload in the viewDidAppear or viewWillAppear methods as they get called when i do not need the tableView to reload (i.e. when the user clicks the back button to return to the tableView).
Is there a way to do this?
Try
1) write one method which reloads the table data.
2) Call it on the back button clicked.
This is the classic delegate pattern problem, in your modal view controller you need a delegate reference to the current view controller presenting it
//Modal
#protocol ModalVCDelegate
- (void)tappedBackButton;
#end
#class ModalVC: UIViewController
#property id<ModalVCDelegate> delegate;
#end
#implementation
- (void)backButtonTapped:(id)sender
{
if (self.delegate)
[self.delegate tappedBackButton];
}
#end
Now, in your presenting VC, just process this delegate message
//Parent VC
- (void)showModal
{
ModalVC *vc = [ModalVC new];
vc.delegate = self;
//push
}
- (void)tappedBackButton
{
[self.tableView reloadData];
//close modal
}
You can use delegate . If find it more harder then alternative is to use NSNotificationCenter. You can see accepted answer for Refreshing TableView. This is really very short, easy and understandable way.
using Notification like bellow Method:-
Create NSNotificationCenter at yourViewController's ViewdidLoad Mehod
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(ReloadDataFunction:)
name:#"refresh"
object:nil];
[super viewDidLoad];
}
-(void)ReloadDataFunction:(NSNotification *)notification {
[yourTableView reloadData];
}
Now you can Call this Notification from your modelViewController BackButton or else you want from calling this Refresh notification like putting this line of code:-
[[NSNotificationCenter defaultCenter] postNotificationName:#"refresh" object:self];
NOTE: postNotificationName:#"refresh" this is a key of particular Notification
Try to use this one
Make a Button and click on this button and than you can reload your data.
This button make custom and use it on background.
- (IBAction)reloadData:(id)sender
{
[tblView reloadData];
}
You can use NSNotification to refresh table on ViewController.
Inside viewController :
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
Write code in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reloadMainTable:)
name:#"ReloadTable"
object:nil];
- (void) reloadMainTable:(NSNotification *) notification
{
[tableView reload];
}
Inside ModelViewController:
[[NSNotificationCenter defaultCenter]
postNotificationName:#"ReloadTable"
object:nil];
Here you can also send custom object instead of nil parameter. But be care full about removal of NSNotification observer.

Reload UITableView from another tab

I am having trouble trying to reload UITableView cell data which are being loaded from an XML source.
Here is the scenario. App contains tabs, in one of them there is a tableview which gets it's data from an XML file and works just ok, but the thing is when I want to change the feed category and change the XML from another tab I can refresh the current tableview.
For switching between tabs I use
self.tabBarController.selectedIndex = 1;
and pass the category feed to the other tab which I want to load
xmlParser = [[XMLParser alloc] loadXMLByURL:categories];
and it still loads the same old feed, not the new one which has been passed. I checked with NSLog and the feed value passes properly but it just wont load after switching.
I also tried to [self.tableView reloadData]; from both current tab and the category tab and it didn't work either.
You can use NSNotifications to send a notification from your other tab and have a oberver in your tableview that responds to that notification.
Example
(Tab calling the reload of the tableview) put this code whenever you want to reload the data, so when a button is pushed or a download is finished etc.
NSNotification * notification = [NSNotification notificationWithName:#"updateTable" object:nil];
[[NSNotificationCenter defaultCenter] postNotification:notification];
In the UITableViewController / the class with the UITableView, do the following.
in your viewDidLoad add:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateTableView) name:#"backtolist" object:nil];
Then add the function updateTableView
- (void) updateTableView: (NSNotification*) note
{
//Do whatever needs to be done to load new data before reloading the tableview
[_tableView reloadData];
}
Hope this helps
Ophychius was correct in his suggestion to use Notifications. I'm assuming you have all of the data sources for your table view updating when the XML is finished loading. This also assumes you're using dynamic cells. In the class that loads the XML, post a Notification when the new XML is finished loading.
[[NSNotificationCenter defaultCenter] postNotificationName:#"XMLLoaded" object:nil];
In the table view class, register as an observer for the Notification you posted from the XML class.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(reloadTable:) name:#"XMLLoaded" object:nil];
As you can see, this calls a selector when this notification is received. Either call your method where you build the table, or create another simple method to call reloadData from.
-(void)reloadTable:(NSNotification *)notif
{
NSLog(#"In ReloadTable method. Recieved notification: %#", notif);
[self.tableView reloadData];
}
Finally (as Leonardo pointed out below), in your viewDidUnload (or dealloc for ios6) method, remove the class as an observer of that notification.
- (void)viewDidUnload
{
[super viewDidUnload];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
I am just guessing, without having seen the rest of the code.
I suppose your table view has an NSArray datasource, did you make sure that your array datasource is updated too ? Does your xml parser, or controller, transfer those data to the NSArray ?
Because if you call reloadData it is just going to refetch the same array. And if it is not updated, you would get old data.

Race condition in refreshing view when application becomes active

On Facebook's iPhone app, the news feed refreshes every time the app becomes active. I would like to do something similar, but I'm concerned about a race condition. The general bootstrapping of my app is as follows:
UIApplicationDelegate
- (void)applicationDidFinishLaunching:(UIApplication*)application
{
[window addSubview:[self.navigationController view];
[window makeKeyAndVisible];
}
- (void)applicationDidBecomeActive:(UIApplication*)application
{
[rootViewController refresh];
}
RootViewController
#pragma mark custom
- (void)refresh
{
if (self.newsFeedModel == nil) {
self.newsFeedModel = [[NewsFeedModel alloc] initWithDelegate:self];
}
[self.newsFeedModel request];
}
#pragma mark UIViewController
- (void)viewDidLoad
{
// initialize the table
// add subviews and whatnot
}
#pragma mark NewsFeedDelegate
- (void)newsFeedSucceeded:(NSMutableArray*)feed
{
// reload table view with new feed data
}
After sprinkling NSLog everywhere, I determined the order of operations to be:
applicationDidFinishLaunching
applicationDidBecomeActive
refresh
viewDidLoad
newsFeedSucceeded
Notice how refresh is called before the root view has been loaded. While we're busy querying the server, the root view loads. When the server responds, the root view is populated with the feed. This works in most cases because the network operation takes a long time. However, if the network operation finishes faster than view can be loaded, then I will be attempting to construct the news feed before the view has been loaded. This would be bad. What is the best Cocoa Touch practice for solving this race condition? I would just set a bunch of flags to determine what state we're in and refresh the news feed depending on the state, but I'm wondering if there were built in events in Cocoa Touch to handle this for me.
I think you want to take a look at applicationWillEnterForeground: instead.
applicationDidBecomeActive: can be called while your app is still running in the foreground. For instance if a text message comes while your app is in the foreground and the user dismisses it, applicationDidBecomeActive: will get called.
You can subscribe to the UIApplicationWillEnterForegroundNotification event in your RootViewController using NSNotificationCenter. I would do this in RootViewController initWithNibName: or whichever init method you are using.
Now you just need to call refresh in 2 places. Once at the end of viewDidLoad and again whenever applicationWillEnterForeground: is called.
This should solve your race condition problem. Since RootViewController is handling it's own refreshing when it knows it is ok to do so.
RootViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
return self;
}
- (void)viewDidLoad
{
// initialize the table
// add subviews and whatnot
[self refresh];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self refresh];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}

How to refresh UITableView after app comes becomes active again?

I would like my UITableView to reloadData once my app is active again, after a user exits the application. I know I need to implement (in my app delegate):
- (void)applicationDidBecomeActive:(UIApplication *)application
but im not sure how to reference the current UITableView?
UPDATE:
My UITableView is a separate controller. It is actually presented as follows
AppDelegate > Root View Controller > Pushes UITabBarController modally which has a UITableViewController
following up on Ole's answer above
add this when initializing the viewcontroller
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(becomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
add the actual method in the controller
- (void)becomeActive:(NSNotification *)notification {
NSLog(#"becoming active");
}
be sure to clean up the notification
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
If you can't access your view controller from the app delegate, you could also have your controller listen to the UIApplicationDidBecomeActiveNotification notification.
you can create your class called TableViewManager. in there register list of UITableView so that you can refresh any table you want.
it's like this, in yourTableViewManager class, you have a method called
- (void)RefreshTableView:(UITableView *)tableView {
if(tableView != nil)
[tableView reloadData]; }