WKWebView process termination - ios

I am using WKWebView in an application and sometimes I get a blank screen because the process dealing with content crashes.
WKNavigationDelegate has a webViewWebContentProcessDidTerminate: method and I implemented it in my view controller.
I can see the memory growth of the webkit process in Instruments but whenever the screen goes blank the methods never gets called.
Other methods of the delegate are working correctly.
Any ideas on this?

well, webViewWebContentProcessDidTerminate delegate can be called if process terminates. However, it is not called once the screen goes blank. There is a delay.

Related

After my app is suspended by the system, the Initial View Controller does not load properly

I'm having an issue that exclusively occurs when I launch my app after it was suspended (while in background) by iOS. In any other situation, the issue won't occur - which already is quite weird. As using the XCode debugger prevent suspension of the app when it goes to background, I have been collecting logs through the Unified Logging system to investigate.
The logs indicate that when I launch the app after suspension by the system, the storyboard scene that is defined as Initial View Controller does get displayed but the code that sits in the viewDidLoad() function of the associated view controller class is not being run.
This happens exclusively after suspension by the system, and will never happen if I manually (or through the XCode stop button) kill the app and relaunch it.
I'm totally stuck as I don't understand why this is happening and why there would be a difference induced by the system suspension.
My project is declaring the main storyboard as "Main Interface" in the target settings. In this storyboard, a scene is defined as Initial View Controller. This scene has a custom class defined, and when I click the arrow next to the custom class name, XCode does take me to the class declaration code.
The class declaration code looks like this:
import UIKit
import SwiftUI
import Firebase
import os.log
class InitialLoadViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//custom code
}
}
The custom code starts with a logging statement that I don't see printed when the issue occurs.
Hope someone may have an idea about what's happening!
thank you 🙏
I could be completely wrong, but I believe that while your app is not getting reloaded, it is disappearing. Try using viewDidAppear or viewWillAppear instead of viewDidLoad for the code you want to be executed after suspension.
After a lof of debugging I found out my issue was related to some of my app background activities. My app is sometimes receiving silent push notifications that wakes it up in the background to perform a network call that refreshes some local data. This process in itself was working well, but waking up my app in the background was also instantiating some view controllers (ie starting up my UI). But my UI has some dependancy to additional network calls that were not designed to work while the app is active in the background. They were therefore failing and leaving the UI in a fail condition that was not handled when the app is in background.
So I have now basically conditioned some aspects of launching my UI to having my app active in the foreground, rather than just having my app active.

App view seems to reload back to default after some time

I've come across a strange error while programming my iPhone application. Basically when I leave my application in the background and then access it after a long time (i.e. the entire night while I'm sleeping), the viewDidLoad method seems to be called again even though I did not exit the app (I only double tapped the Home button or I tapped the Home button once) but still left the app in the background. However, if I leave the app on for a short period of time (anytime between a few minutes to a few hours), the viewDidLoad method is not called again and everything is as it should be. After doing some research, I found that it is because the viewDidUnload method is called (after the OS finds that the app is suspended for a long time), which calls viewDidLoad again when we bring the app back up. I found this out through this link: view seems to reload itself but it doesn't seem that there's a way to prevent viewDidLoad from being called when the viewDidUnload is called. Is there any way to prevent this viewDidUnload method from being called again? The thing is I want my app to be running for a long time in the background (i.e. a few days in the background) to collect data. Or, is there no way around this? Any help would be appreciated. Thanks!
EDIT: I have realized that after iOS 5, viewDidUnload is deprecated but this phenomenon still occurs. Any ideas on how to fix it? Thanks!
If you want to do stuff in the background you should look into background tasks.

viewWillLayoutSubviews getting called after applicationDidEnterBackground notification

I'm having an issue where my app is crashing on sleep, and sometimes on home. I'm getting a BAD_ACCESS error in a thread called gpus_ReturnNotPermittedKillClient, which tells me that my app is making UI changes in the background, which to my understanding is a no-go. Therefore, I'm stepping through my code to see what happens on home / sleep, and I find that my breakpoint in my VC's -viewWillLayoutSubviews method is getting hit AFTER the breakpoints in the -applicationWillResignActive and -appplicationDidEnterBackground notifications (in which I'm attempting to stop all updates from an asynchronous callback function).
That doesn't seem to make any sense. From the application's perspective, if it's not cool to do UI updates in the background, why call viewWillLayoutSubviews after you're in the background?
EDIT: It appears to do this even when my app doesn't crash. Could it just be lldb getting things out of order?
I think you simply need to be tolerant of this. Per this tech note, you can't do any GLES rendering in the background. My recommendation would be for your app to set a flag when applicationWillResignActive is called, and then before doing any rendering work you check that flag and don't do the work (and perhaps just call -setNeedsDisplay on the view so that if your app becomes active again it will know to draw that view). You seem troubled by the fact that viewWillLayoutSubviews is getting called "late", but I don't see how that really matters. (i.e. layout != rendering) I would be surprised if your view's -drawRect: method were getting called after applicationDidEnterBackground but I would still say that it would be your responsibility to check a flag and not render if your app is in the background.

Main View gets dark when coming back from Background

I am using RouteMe's library and services to display maps.
The main ViewController holds an *RMMapView that inherits from UIView. Basically it just fills up with tiles.
When my app goes to background, and after a while, after other apps are loaded into memory usually, comes back to foreground, The main mapView goes completely black and I can't see anything except for my UI.
(I guess due to lack of memory)
How can I prevent that from happening ?
Thanks!
you cant prevent a Memory warning from happening, however if you are 100% sure that you cant handle the memory warning in some view controller and to stop the call to viewDidUnload remove the implementation of didReceiveMemoryWarning in your view controller
Please note that disabling the viewDidUnload is not recommended, you should reflect about your memory usage and present a better memory management technique

Prevent UIWebView allocating to much memory

I have a problem with UIWebView. I am using this component for loading normal web pages on iPad/iPhone. UIWebView is presented in modalViewController. Some pages are very memory hungry and some also have Flash content.
The problem is that sometimes on some pages I get memory warning
Received memory warning. Level=1
When this happens and when I close this modalViewController (which has page loaded in webView) than the previous view reloads itself automacially - method viewDidLoad is fired again.
I suspect that some pages in UIWebView consume to much memory and than application release memory of its views, but does not crash.
Is there a way to limit memory consumption of webView or is there any other way to avoid this memory warning?
Thanks!
You have very little control of the memory usage of UIWebView objects. You also have very little control of the overall system memory usage. So there is no way to avoid memory warnings. iOS expects your apps to behave properly when receiving memory warnings, so your viewDidLoad method should be written to handle rerunning after a memory warning.
The only things you can do to limit the memory usage of a UIWebView is to have it view simple web pages. It looks like from your question, that's not an option.
Edit: viewDidUnload is called during low-memory conditions. This method is expected to free up anything that's easy to recreate in the viewDidLoad method. Don't release the state information you want to show the user when this view is returned to the screen. Then in your viewDidLoad method check all the objects you create. If they are nil, they need to be initialized, otherwise this isn't the first time your viewDidLoad method was called, and you shouldn't initialize your objects agin.
In other words: viewDidUnload handles low-memory situations and viewDidLoad should not assume it is run once.

Resources