iOS App - Refresh last webView on applicationDidBecomeActive - objective-c

I have a single view iOS app, that contains a webView that displays my website. When the app is returned to from multitasking (when it is brought back as the active app) I would like the webView to get the URL it is currently on, and refresh (or reload) that current page in the webView (I'm thinking using this method):
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSLog(#"applicationDidBecomeActive");
}
How would I do this? Do I need to subscribe to some sort of notification? Please help point me in the right direction, and provide some code.

There are some point to get noticed are like:
Application should allow user to run in background mode. You can define this in info.plist
Implement UIWebViewDelegate in your view controller. There is one method: webViewDidStartLoad:
Inside that method get the current url
NSString *currentURL = [webView stringByEvaluatingJavaScriptFromString:#"window.location"];
(For more details refer this.)
Save this url string to some where, and while relaunching your application the method which you mentioned in the question gets called. Inside that method, load your web view with this url string.
Hope this is what you required.
Enjoy coding :)

Related

How to set PresentingViewController with current ViewController in iOS 7+

In my iOS 7+ app I'm using the latest version of Harpy, which perform an app version check and present an alert if there's a new version of my app available in the App Store.
Due to the structure of my app, I'm facing this issue in the debugger:
Attempt to present <UIAlertController: 0x144538530> on <DCLoginViewController: 0x14460c1a0> whose view is not in the window hierarchy!
this is because harpy is configured in the AppDelegate and has a parameter that define the presentingViewController:
[[Harpy sharedInstance] setPresentingViewController:_window.rootViewController];
I believe the issues arise because my app check if the user is already logged in, if so, instead of presenting the DCLoginViewController, it jumps to the next view which is "LoadingViewController".
How can I set the presentingViewController to be this LoadingViewController or even the ViewController currently on screen at execution time?
Thanks for your help.
You don't have to launch Harpy in the AppDelegate. You can launch it after LoadingViewController has loaded. It's only recommended to launch it in the AppDelegate as the idea is to show the alert as soon as the app is loaded. It's more of a UX thing than anything else.

iAd interstitial delegate methods doesn't get called

I want to use interstitial ads in my app, so I implemented all necessary delegate methods.
The problem is, if I use [self requestInterstitialAdPresentation] to show the ad, only the interstitialAdDidLoad: method gets called.
The interstitialAdActionDidFinish: methods doesn't get called...
But if I use the deprecated [self.interstitial presentFromViewController:self] to show the ad, everything works.
Is there anything new to implement to get things work ?
Thanks in advance
Ok, I resolved the problem.
Since IOS7 with its iAd Additions there's no need for an adInterstitialDelegate. The only thing to do, is preparing the ads or set the interstitialPresentationPolicy to something other than none (as you can read in the documentation) and as a last step requesting the ad using the requestInterstitialAdPresentation: method.
iOS 9.2.1, Xcode 7.2.1, ARC enabled
#Jellyjoey I confirmed, viewDidAppear is called when the ad is closed. And as you might expect, when you tap the ad, viewDidDisappear gets called.
It has to do with how you are presenting the interstitial ad:
Completing an Advertising Action
If the full-screen ad displayed the rich media ad inside your app, it
calls your delegate’s interstitialAdActionDidFinish: method after the
ad finishes. Your implementation of this method should restore any
services paused by your app when the action started.
Important: If your app was moved into the background because the
willLeave parameter was YES, then the app’s user interface is never
covered by the banner view and your app does not receive a call to
interstitialAdActionDidFinish:. However, if your interface was covered
by the banner view, your app could still be moved into the background
later, either because the advertisement launched another app or
because the user chose to do so. In all cases, if your user interface
was covered by the banner view, it is uncovered and your delegate’s
interstitialAdActionDidFinish: is invoked before your app moves to the
background. Because the app may be moving into the background, your
delegate should return quickly from its interstitialAdActionDidFinish:
method.
To view the excerpt above and the rest of the guidelines for interstitial ads:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/iAd_Guide/Full-ScreenAdvertisements/Full-ScreenAdvertisements.html#//apple_ref/doc/uid/TP40009881-CH5-SW24
Here are two examples provided by Apple of how to use full page ads:
https://developer.apple.com/library/ios/samplecode/iAdInterstitialSuite/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010627-Intro-DontLinkElementID_2

Define a controller for NSDocument for document-based application

I'm not very sure how Document-Based Applications works.
I've created some actions for NSObject in the Mainmenu.xib. One of this is called when the user click on "File>new":
-(IBAction) newDocument:(id)sender{
Document* newDoc =[[Document alloc] init];
[[NSDocumentController sharedDocumentController]addDocument:newDoc];
[newDoc addWindowController: [[NSWindowController alloc] initWithWindowNibName:[newDoc windowNibName] owner:newDoc]];
[newDoc showWindows];
}
I've also this code inside the openDocument:(id) sender action that does the same but of course loading data to define the application workspace.
If I run the application it show a blank document without to call newDocument action. I don't know how to stop default blank document and to set newDocument: to be called.
Then if i do openDocument: too (so I've two documents, one blank and one not) and I do some operation on the second document it also replicate in the first blank one.
I've double check delegates, file owners, and also if the - (void)windowDidBecomeMain:(NSNotification *)notification return different pointers and all seem to be ok.
Probably I've not understood document based application work flow but I've read the Apple guide and other istructions. What do I miss?
An IBAction method is called, when the user did something. So this is not called from the system at app launch.
You can customize the behavior at app launch with -applicationShouldOpenUntitledFile: (NSApplicationDelegate) and – this is probably your next question – -applicationShouldHandleReopen:hasVisibleWindows: (NSApplicationDelegate). Changing the behavior in both cases is not recommended.
Looking to your action method, I see no reason, why you want to customize it.
A instance of your document class is created automatically.
You can create a window controller for it in your document subclass. This is documented.
Just let NSDocumentController do the work for you. What is the problem of the default behavior?
No. I thought to be confused instead the only problem was about releasing observer notification. When you call the close message for a NSDocument notification observers still persist. Working in ARC I miss this point.
So This is the solution at my issue. Thank you anyway.

iOS 5 bug: UIWebView and goBack and goForward

I found a bug in iOS 5.
When you are using a UIWebView and access some sites, you create your history links, look like any other browser.
If you like to use a navegation bar, can use the functions goBack and goForward
In iOS 4.3 and below, when you call this function the program call the delegate function
webView:shouldStartLoadWithRequest:navigationType:
But in iOS 5.0 this can happens or not. If the site is in cache, it not call this function. I saw this happens in only 1 level (1 click in goBack or 1 to goFoward), in the second click it pass in the function.
Why they change it???? Even it is in cache, the program have to ask for me.. Now how solve this: I am trying make a stack with the browser history and I check the url. But i am having problem ;(
There are no other way?
I can't see the browser history? I have to create my ow list?
I can't clean the cache to force it pass in the function?
Any sugest?
It's not a bug, if there is enough available RAM on the device then it will keep some of the pages in memory, therefore they are not being "loaded" again when you go back.
You should create your own goBack: and goForward: actions on your own controller, and link the goBack/goForward buttons to them:
- (IBAction)goBack:(id)sender
{
[self doStuff];
[self.webView goBack:sender];
}

Plugin objects in WebView getting destroyed?

Here's my situation:
I've written a simple web browser. Tabbed browsing was easy enough to get working once I wrapped my head around the concepts and figured how to perform operations on specific tabs. It works well and is pretty reliable under most circumstances.
A problem has plagued me, however, and I cannot figure out its cause.
Let's say I open a new tab and navigate to YouTube. I click on a video and the flash player loads. The video plays and all works fine. I now create another new tab and navigate to some site. The audio from the youtube player stops completely.
When I switch back to the youtube tab, the page will all still be there just as it was except the player has to reload completely, as if I had just reloaded the page. This seems to apply to other plugin types as well.
What's causing this?
Garbage collection is not enabled and as far as I know I'm creating the web views properly. Is there some silly, simple little thing that I missed somewhere along the line?
The - (void)setHostWindow:(NSWindow *)hostWindow method on WebView is probably what you're looking for.
I had the same problem with the flash in a WebView reloading whenever the syle mask of the enclosing window was changed. Wrapping the call to setStyleMask fixed the problem, as follows:
NSWindow *hostWindow = [[NSWindow alloc] init];
[self.webView setHostWindow:hostWindow];
[[self windowForSheet] setStyleMask:styleMask];
[self.webView setHostWindow:nil];
[hostWindow release];
The documentation for the method isn't stellar, but it does explicitly state a having a WebView inside a NSTabView as one of the use cases:
This method sets the receiver’s host window to hostWindow. Your application should only use this method if a web view is going to be removed from its window temporarily, and you want the web view to continue operating (for example, you don’t want to interrupt a load in progress). Since the receiver retains hostWindow, it is your responsibility to set the host window to nil before closing the window to avoid a retain loop.
For example, you might invoke this method if you attach a web view to an NSTabView object (as in a tabbed browser implementation). The NSTabView object takes views out of the window when they are not in the active tab, so you need to invoke this method before the web view is removed from its window. If you don't invoke this method, plug-ins will stop operating when the web view is removed from its window.
I had a similar problem but with a window with a webView that is closed and restored. Unfortunately the solution by #mlwelles did not solve the problem alone.
What did solve however is removing the webView from the window before it closes (proper "timing" is important). What I came up with is something like this:
id contentView;
id tmpHostWindow;
[window setDelegate:self];
- (BOOL)windowShouldClose:(NSNotification *)notification
{
// set temporary hostWindow on WebView and remove it from
// the closed window to prevent stopping flash plugin
// (windowWillClose would be better but that doesn't always work)
tmpHostWindow = [[NSWindow alloc] init];
[webView setHostWindow:tmpHostWindow];
[window setContentView:nil];
[contentView removeFromSuperview];
return TRUE;
}
- (void)windowDidBecomeKey:(NSNotification *)notification
{
// restore "hidden" webview
// (would be better to do it in applicationShouldHandleReopen
// but that seems to be too early (has no effect)
if ([window contentView] != contentView) {
[window setContentView:contentView];
[webView setHostWindow:nil];
tmpHostWindow = nil;
}
}