On receiving a notification i want to change my uiwebview - ios

The notification I receive contains an url to open in a UIWebView. But I cannot access the UIWebview from my AppDelegate (this is where is receive the notification).
-(void) application:(UIApplication *)application didReceiveRemoteNotification(NSDictionary* ) userInfo{
// handle notification (this works)
//HERE I want to call my UIWebView and load the url I got.
}

One way to do this is to post a notification that your UIWebView receives. Check out the NSNotificationCenter Class Reference or this example on SO.

In my app I have used the following, this is when the UIWebView is already on the screen:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSString *urlString = [userInfo objectForKey:#"url"];
if( [self.window.rootViewController isKindOfClass:[UINavigationController class]] ){
UINavigationController *currentNavigationController = (UINavigationController*)self.window.rootViewController;
if( [currentNavigationController.visibleViewController isKindOfClass:[NHCallVC class]] ){
SomeViewController *currentViewController = (SomeViewController*)currentNavigationController.visibleViewController;
[currentViewController.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];
}
}
}
The structure with the UINavigationController seems complex, but this was needed for the way I set up my app. This can be different in your app.
The idea is to get the viewcontroller that is opened and load a URL on the UIWebView. The code is assuming the UIViewController with the UIWebView is currently open. The code should be altered if you want to navigate to the correct UIViewController before opening the url in the UIWebView.

Place an observer to the view where UIWebView resides such as:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(recievedNotification:) name:#"ReceivedNotification" object:nil];
Write the appropriate code within recievedNotification function which changes the UIWebView's target url.
And post a notification in didReceiveRemoteNotification function in APP Delegate such as:
[[NSNotificationCenter defaultCenter] postNotificationName:#"ReceivedNotification" object:nil];
Good luck.

Related

Methods not called after openURL function ONLY if app is not active

After visiting a share url on a website, viewers are prompted to open the link in my application. If the application is running, it works perfectly.
However, if the application is closed, the viewDidLoad and viewWillAppear methods are not called on my ViewController, so I am not able to open the desired ViewController.
Does anyone know how to allow to get the viewDidLoad function to run if the app is launched from the openURL function?
I currently have:
AppDelegate:
-(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if (!url) { return NO; }
NSString *party_url = [NSString stringWithFormat:#"%#%#/", PARTYURL, url.lastPathComponent];
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:#"WebViewNotification" object:party_url]];
return YES;
}
ViewController:
- (void)viewDidLoad {
[super viewDidLoad];
appDelegate = [AppDelegate getDelegate];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(webViewNotification:) name:#"WebViewNotification" object:nil];
}
- (void)webViewNotification:(NSNotification *)notification {
NSString *url = [notification object];
PartyViewController *partyViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PartyViewController"];
partyViewController.partyUrl = url;
[self.navigationController pushViewController:partyViewController animated:YES];
}
Again, this works fine if the app was previously opened. However, if it is closed, this does not work. Thank you!
When your app launched from a link without any other operation you don't have a presented ViewController contains this code in your views stacks. so this code will never been executed. consider directly present partyViewController in your CustomTabBarController.

NSNotificationCenter and didReceiveRemoteNotification

I have some problems with NSNotificationCenter and didReceiveRemoteNotification. I want to open my ViewController when i receive new notification from APNS. Inside body notification i have objectId - it's key.
I try to open my ViewController into didReceiveRemoteNotification but it's not working ((
AppDelegate.m
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[[NSNotificationCenter defaultCenter]
postNotificationName:kDidReceiveRemoteNotification
object:userInfo];
}
NewsDetailViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(didReceiveRemoteNotification:)
name:kDidReceiveRemoteNotification
object:nil];
}
- (void)didReceiveRemoteNotification:(NSNotification *)notification
{
NSLog(#"%s %#",__func__,[notification.userInfo description]);
}
Const.h
#define kDidReceiveRemoteNotification #"UIApplicationDidReceiveRemoteNotification"
ViewController not loaded. i dont know what to do.
The current flow of the sample code you've attached is:
When receiving push notification, post a notification to NSNotificationCenter (something completely different and unrelated to push notifications).
When another view is loaded (someone needed to load this view before the push notification was received), subscribe to this NSNotificationCenter notification.
When the notification is posted, print it to log.
It was hard for me to understand this from your question, but if the view controller you're trying to launch as a result of receiving the push notification is NewsDetailViewController, then your code doesn't do that. What you're code does is prints out the notification to log (assuming that somebody else made sure that NewsDetailViewController is loaded before the push notification was received).
In order to load the NewsDetailViewController when the push notification is received, you don't need to post the notification to NSNotification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NewsDetailViewController *newsVC = [[NewsDetailViewController alloc] initWithNibName:#"NewsDetailViewController" bundle:nil];
[self.window.rootViewController.view addSubview:newsVC.view];
}
Or any other loading logic that works better for you. But in the current code you posted, there is no connection between receiving the push notification and loading the ViewController.
I hope this helps. Good luck!

NSNotification centre to observe whether an application is opened through URL Scheme

I have a class which will make NSNotificationCenter to observe whether the app is active or it went to background and it will do a set of actions according to that.
I want to set a NSNotificationCenter to observe whether the app is opened through URL scheme .
This is what I tried:
[[NSNotificationCenter defaultCenter] addObserver:[self class] selector:#selector(appOpenedThroughUrl:) name:UIApplicationLaunchOptionsURLKey object:nil];
But its not getting called when the app opens through URL please provide me some idea to do the same.
I don't want to use the delegate:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
+(void)appOpenedThroughUrl:(NSNotification *)notification {
NSLog(#"%#",notification.userInfo);
}
you need to post notification whenever it open through custom url scheme
[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationLaunchOptionsURLKey object:self];

Passing data received from a push notification from the AppDelegate to a ViewController

In my app, there's a collection view displaying a set of images retrieved from a web service. Each image has tags. So the app has the ability to filter images using tags as well.
Now I'm trying to add push notifications to this app. A push notification is sent when new images have been added to the server. These images are tagged say, latest. I'm passing that tag as the message via a push notification and what I need is when the user taps on the push notification to open the app, it should load the latest new images to the collection view.
I'm half way done. I receive the push notification with the message successfully to the didReceiveRemoteNotification method in the AppDelegate.m file. Now I need to pass it on to the view controller where the collection view is. I'm stuck at this point. I can't figure out how to send it over to the view controller.
I tried declaring a property in the App delegate, assign the message value to it and referring it from the view controller but it didn't work. I tied delegates, notification center, user defaults but nothing worked.
Can anyone please tell me how to accomplish this?
Thank you.
Edit:
Here's my code. The last method I tried was the local notifications.
AppDelegate.m
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"PushNotificationMessageReceivedNotification" object:nil userInfo:userInfo];
}
ViewController.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(remoteNotificationReceived:) name:#"PushNotificationMessageReceivedNotification"
object:nil];
}
- (void)remoteNotificationReceived:(NSNotification *)notification
{
NSLog(#"Notification: %#", notification.userInfo);
NSString *msg = [[notification.userInfo valueForKey:#"aps"] valueForKey:#"alert"];
self.label.text = msg;
}
Case 1: if your app is background and user launches app with notification click then you have the check if app launched form notification or normal
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
NSDictionary *remoteNotificationPayload = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotificationPayload) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"notification" object:nil userInfo:remoteNotificationPayload];
}
return YES; }
Case2: If your app is in forground notification will be received in didReceiveRemoteNotification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"userinfo %#",userInfo);
[[NSNotificationCenter defaultCenter] postNotificationName:#"notification" object:nil userInfo:userInfo];
}
Now you and add a observer in any controller with Local notification and do what you wand to do
I don't know it will work or not,its only my suggestion. I did't tried it before but in your case may be it work
user NSUserDefaults for this.
in your appDelegate.m
[[NSUserDefaults standardUserDefaults] setObject:imageArrayFromServer forKey:#"MyAppSpecificGloballyUniqueString"];
in your viewController.m
NSArray *myArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"MyAppSpecificGloballyUniqueString"];

detecting URL webview has left the your iPhone app

i open a url within a Webview and whilst loading i show a spinner in a alert view.
If the url tapped opens an internal app such as iTunes how can i detect the web view has left my app so that when the user returns the dialog has been dismissed.
i have used didFailLoadWithError and this didn't work?
Any ideas?
Thanks dan
FIXED- i forgot to set the delegate Doh!
UIWebViewDelegate method webView:shouldStartLoadWithRequest:navigationType: will ask your webview's delegate if it is allowed to open every single url before trying to open it. You could check for url type in that method and return NO if it's not http or https, then present an alert for the user and let them chose if they want to open it or stay within your app, or just log that app was left to open another one and return YES;
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *urlString = [NSString stringWithFormat:#"%#", request.URL];
NSArray *urlComponents = [urlString componentsSeparatedByString:#"://"];
NSString *urlType = [urlComponents objectAtIndex:0];
if ([urlType isEqualToString:#"http"] || [urlType isEqualToString:#"https"]) {
// present an alert or do whatever you want with this url...
return NO;
}
return YES;
}
First of all, using an alert view to display loading progress in a web view is probably a bad idea, because it blocks all user interaction until it finishes loading.
You already have code that allows the web view to handle certain URLs with the built-in apps, such as iTunes (it doesn't do that on its own), so I guess when you use [[UIApplication sharedApplication] openURL:...] to open the external URL, you could easily hide the spinner there as well.
You could use applicationWillResignActive to detect when the app goes into an inactive state. It goes in your app delegate:
- (void)applicationWillResignActive:(UIApplication *)application {
//close your UIWebView here
}
If you can't access your UIWebView from the delegate, you could register for the UIApplicationDidEnterBackgroundNotification notification from your UIViewController. Make sure you un-register at some point.
//register
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(closeWebView) name:UIApplicationDidEnterBackgroundNotification object:nil];
//un-register
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];

Resources