I have two view controllers (BuildingsViewController and RoomsViewController) that both use a function within the App Delegate called upload. The upload function basically d
If you are targeting iOS 4.0 and later, you can use the window's rootViewController
property to get the current view controller.
[window.rootViewController viewWillAppear];
If you want your application to run on versions prior to iOS 4.0, then you could add an instance variable to the application delegate to remember which view controller called the upload
method, having the controller send itself as a parameter.
- (void)upload:(UIViewController *)viewController {
self.uploadingViewController = viewController; // This is the property you add
...
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self.uploadingViewController viewWillAppear];
self.uploadingViewController = nil;
}
You should also consider using a different method to reload the buttons, something like reloadButtons
, since it is not related to the view appearing in this case. You would then call that method from within viewWillAppear
.
Worse comes to worst, you can have both view controllers adhere to a simple one method protocol that will remove that button and refresh the view. Then in your connectionDidFinishLoading method, since you know your view controller must adhere to that protocol, by your design, you simply do something like
ViewController<MyProtocol> curView = (Get the current view controller somehow);
[curview refreshView];
Step 1:
In your App Delegate .h file you need to declare a protocol like so:
@protocol AppConnectionDelegate <NSObject>
@required
-(void)connectionFinished:(NSObject*)outObject;
@end
In the same file, add an ivar like so:
id *delegate;
Declare the ivar as a property:
@property (nonatomic, assign) id<AppConnectionDelegate> delegate;
In the App Delegate .m file, synthesize the ivar:
@synthesize delegate;
In the App Delegate .m file, on connectionDidFinishLoading do:
if([self.delegate respondsToSelector:@selector(connectionFinished:)])
{
[self.delegate connectionFinished:objectYouWantToSend];
}
In your viewcontroller's .h file, implement the AppConnectionDelegate by importing a reference to the app delegate file:
#import "AppDelegate_iPhone.h" //if using iPhone
#import "AppDelegate_iPad.h" //if using iPad
In the same file, at the end of the first line of the interface declaration do:
@interface AppDelegate_iPhone : AppDelegate_Shared <AppConnectionDelegate>
Declare ivars accordingly:
AppDelegate_iPhone *appDelegate; //if using iPhone
AppDelegate_iPad *appDelegate; // if using iPad
In your viewcontroller's .m file in the viewDidLoad(), get a reference to your app delegate using:
If iPhone;
appDelegate = (AppDelegate_iPhone*)[[UIApplication sharedApplication] delegate];
If iPad:
appDelegate = (AppDelegate_iPad*)[[UIApplication sharedApplication] delegate];
Then set the viewcontroller to be the delegate in viewDidLoad() by doing:
appDelegate.delegate = self;
Now you need to simply implement the connectionFinished method in the .m file:
- (void)connectionFinished:(NSObject*)incomingObject
{
//Do whatever you want here when the connection is finished. IncomingObject is the object that the app delegate sent.
}
Now whenever your app delegate's connectionDidFinishLoading is called, the view controller will be notified.
[It's a best practice to set appDelegate.delegate = nil if you're done using the connectionFinished callback]
This is tried and tested. If you have questions, leave a comment......
--EDIT--
This is a robust alternative to NSNotification. I use both depending on the requirements. The process I use to decide between using NSNotification or a delegate callback using a protocol is simply:
For notifications:
One sender, multiple listeners.
No reference possible between sender and listener.
Complex/multiple objects need not be sent
For delegate callbacks using protocols:
One sender, limited (usually 1) listeners.
A reference between sender and listener is possible.
Complex/multiple objects are to be sent (for example, response objects that need to be sent)
I know sending objects is possible through notifications but I prefer protocols for that.
--EDIT--
To do the refresh of the view do not call viewWillAppear
if the view is already displayed. What you want to do is the following:
When ConnectionDidFinishLoading
method is triggered post a notification
[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshView" object:nil];
In your viewController
observe for this notification. You do it by adding this code to your init or viewDidLoad
method
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshView:) name:@"refreshView" object:nil];
Now implement -(void)refreshView:(NSNotification *) notification
method in your viewController
to manage your view to your liking.