Presenting iOS 8 UIAlertController from Singleton Object - ios

I currently have a locationManager (not CLLocationManager) singleton that is getting my location when the app starts and that manages the rest of the location services in the app.
When getting initialized the location manager if the state is denied triggers an alert prompting to change the authorization state. Since it is a nsobject I can't present it, and I've been looking for other options but most are hacks. Is it actually possible to present it this way?
Thanks in advance

I'm sure some will argue about whether or not you SHOULD. With that being said, you COULD by doing this:
[[(<#YourAppDelegate#> *)[UIApplication sharedApplication].delegate window].rootViewController presentViewController:<#(UIViewController *)#> animated:<#(BOOL)#> completion:<#^(void)completion#>];
It should be noted that if you're using a Mac app as opposed to iOS, multiple windows could be present and you may want to use the key window. This could occasionally be a system window so it's something you should be aware of. Here's a post explaining the differences:
https://stackoverflow.com/a/21698751/2611971
If you'd prefer to present on your keyWindow, you could use this:
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:<#(UIViewController *)#> animated:<#(BOOL)#> completion:<#^(void)completion#>];

You can set your main view controller object as an observer for a AuthorizationDenied notification via Notification Center. And post that notification when it's denied, and your view controller will get notified.
In your View Controller loading:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(authorizationDenied:) name:#"AuthorizationDenied" object:nil];
In your singleton class:
[[NSNotificationCenter defaultCenter] postNotificationName:#"AuthorizationDenied" object:nil];

Related

Method in viewWillAppear and viewDidLoad didn't loaded

I have created a method to check the status of a server in my viewcontroller, I need to check this, everytime I will open the app.
I call [self checkStatus]; from viewWillAppear and viewDidLoad, but when I open the app, by clicking home button, and I try to open the app again (clicking the app icon in applications) this method is not called. I have a NSLog to view when it is launched or not.
I'm frustrated. Thanks for your help.
You can react to app changes using NotificationCenter:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doSomething:) name:UIApplicationDidBecomeActiveNotification object:nil];
BTW: don't forget to removeObserver when you don't need it!
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
You can also use UIApplicationWillEnterForegroundNotification etc, depending what do you need.
You should read about app lifecycle on Apple Developer pages :). Read:
AppleDeveloperLink Especially section: "Execution States for Apps" to know more about app lifecycle.
StackOverflowLink to know more about view lifecycle.
iOS is not calling those methods again, but the delegate methods in the AppDelegate. You have to propagate the message to your controllers then.
I hope this will help you: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/

Using NSNotificationCenter to call method in main app from extensions widget?

I have a widget that I would like to call back to my main app so as to make a call to the server to update data. I looked into delegation, but registering the widget's view controller as a delegate didn't seem very practical. So I moved on to trying to use NSNotificationCenter. I have set it up, but the selector is not being called. In my main iOS app I have this in the viewDidLoad method.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(loadNewData:)
name:kUpdateData
object:nil];
And at the bottom of that file I have this:
/**
* Updates the table when the today widget is called for updated info
**/
- (void)loadNewData:(NSNotification *) notification
{
[self loadTableData];
}
That's in my main app. Now, in my notification center widget/extension, I make this call:
[[NSNotificationCenter defaultCenter]
postNotificationName:kUpdateData
object:nil];
The postNotificationName being passed in, `kUpdateData', is a constant that is resolved to #"updateData". I can see in the debugger that the postNotificationName method is being called, but the main app is not responding to it (regardless of it is in the foreground or the background). What am I doing wrong?
As a side note, the only reason I am doing this is to remove the need for repetitive code and re-implementing things I have already made.
As far as i know extension cant access or call main app methods... what can do is either do the server execution in extension or set a value in shared NSUserDefault so when your app is brought to foreground you can check this value and connect with server accordinly.

Run Loop to set color to button ios?

I've got sort of a problem with my ios application. It handles the Apple Push Notification (APN) and everything BUT, my app handle it in it appDelegate.m
The problem is I want to make a button to change color if the user have a notification, so I search a way to do it and I found "Run Loop", is this possible to have a Run Loop in a secondary thread to check infinitely if there is a new notification? (with a wait of 5/10 seconds between each verification) I don't really know how to declare it neither to make it works alone. (I'm pretty new with xCode and used the AFNetworking asynchronous methods for the rest of the app so I'm not really good with threading and co.)
It could be really great if someone is able to give me a way to implement a simple run loop in my app.
Thank you!
EDIT : I have a white button for User profile, and I want it to change to Red when the user have a notification, the button is already declared and works in a viewController, but I don't manage to link it to the appDelegate, that's why I'm asking to do a RunLoop who could handle a BOOL sent by the appDelegate, that my view do only in the viewDidLoad (that don't really work when app is in background etc...)
I don't really see why you need a Run loop?
You could use NSNotificationCenter. https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html
AppDelegate.m
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"didRecieveNotification" object:nil userInfo:userInfo];
}
}
And add your ViewController where the button lives as a observer:
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleNotification:) name:#"didRecieveNotification" object:nil];
}
-(void)handleNotification:(NSNotification *)notification
{
YourButton.backgroundColor = [UIColor redColor];
}

How to call method when app enters foreground from background

Is there a simple way to call a method when my app enters the foreground from the background? I have my program call a method "nowYouSeeMe" in the viewDidLoad method, which works great when running the app the first time. When I use the app and then hit home-button it moves to the background as usual. Now when I press app icon and it brings it to the foreground I basically want it to call the nowYouSeeMe method again.
-(void)nowYouSeeMe{
NSLog(#"I'm back");
}
Any ideas??
As already mentioned there is - (void)applicationDidBecomeActive:(UIApplication *)application;in App Delegate, but most of the time you need the information not in your app delegate but your view Controller. Therefore you can use NSNotificationCenter. In your app delegate you could do the following:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotification:[NSNotification notificationWithName:#"appDidEnterForeground" object:nil]];
Now you can set up listeners in your UIViewControllers setup code:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(appDidEnterForeground) name:#"appDidEnterForeground" object:nil];
Now the method appDidEnterForegroundgets called on your view controller whenever the app enters the foreground.
But you don't even need to post the notification yourself because it is already defined in UIApplication. If you scroll down the documentation (UIApplication Class Reference) you see all the notifications declared in UIApplication.h, in your case UIApplicationWillEnterForegroundNotification.
Notice the difference between UIApplicationWillEnterForegroundand UIApplicationDidEnterForeground, but most times you want to use UIApplicationWillEnterForeground, just to set everything up and be ready when the app is displayed.
Of course you should define a constant somewhere for your notifcationname and if you don't need the observer anymore remove it.
Edit: you could also use #selector(nowYouSeeMe) as in your question, missed that
In the appDelegate there is method called applicationDidBecomeActive:(UIApplication *)application it is triggered when your app became active.
Try calling the method via the below app delegate method :
- (void)applicationDidBecomeActive:(UIApplication *)application;
You should implement the applicationWillEnterForeground: method in your AppDelegate, like this:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[self.controller nowYouSeeMe];
}
provided that you have a reference to that controller as a property in your AppDelegate.
As per everybody else's answer, the application delegate will get a call-out via applicationDidBecomeActive:.
The application will also post the UIApplicationDidBecomeActiveNotification notification. So anyone that isn't the app delegate can just observe that.
You shouldn't use the application delegate as a lazy does-everything singleton if you can avoid it; if it's the one specific view controller that wants to do something only if it is active and the app returns to the foreground then there's no reason to involve the application delegate — it's a behaviour of the view controller, not the application.

Refreshing Parse.com data when the app becomes active

[Edited with solution below]
I want to call a Parse.com query whenever the app becomes active, so that if it's brought up from the foreground, a new set a data will be called.
I realize there is a method for this in the AppDelegate
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
But I want to know how I can put the query information obtained in my AppDelegate and put it in my ViewController where I can display the information.
Any ideas on what I might do? Or if there is another way to make the query when the app becomes active? Thanks.
So here is what I came up with. I had my method (called getData) in the ViewController, and in the viewDidLoad method, I inserted this code
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(getData)
name:UIApplicationDidBecomeActiveNotification object:nil];
And now it works just as I had hoped. Thanks!
This is a really broad question, but what you can do is you can post a notification and make your view controller listen to it.
Then after your app re enter from background, you can post the notification and in the observer method that you implemented in the view controller, you can pull the data from Parse.
See this question to understand the sequence of the method calls.

Resources