I am using the technique provided by this SO answer to preload some URL in SFSafariViewController like this:
addChildViewController(svc)
svc.didMoveToParentViewController(self)
view.addSubview(svc.view)
And I try to remove the Safari View controller with following code:
svc.willMoveToParentViewController(nil)
svc.view.removeFromSuperview()
svc.removeFromParentViewController()
Now I can preload the URL and show the Safari View without problem. However, after I repeat the process (preload/show/remove) several times (probably 30+ times) , the app will crash due to some memory issue because the log shows Memory level is not normal or this app was killed by jetsam
when the app crashes.
Before crash, I saw some logs about possible-leak warnings:
<Warning>: notify name "UIKeyboardSpringBoardKeyboardShow" has been registered 20 times - this may be a leak
<Warning>: notify name "com.apple.SafariViewService-com.apple.uikit.viewService.connectionRequest" has been registered 20 times - this may be a leak
Am I doing it correctly when removing the Safari View controller? Am I missing something? Or any suggestion to work around this issue?
SFSafariViewController is part of the SafariServices framework, and lets your users browse a web page, or a website right inside your app. With it, people can enjoy the same web browsing experience they get in Safari — including features like Password Autofill, Reader, and Secure Browsing — without ever having to leave your app.
When added as a child, a view controller is automatically resized according to the size of the app’s window — but just like a subview of a stand-alone UIView, a child view controller’s view can be resized and repositioned using either frames or Auto Layout constraints. To add a view controller as a child, we use the following three API calls:
When a piece of UI is implemented as a view controller, it can be used in many different contexts — including both being pushed onto a navigation controller, as well as being embedded as a child.
If your adding child view controller code is as you have specified above then I think its order should be a bit different as per the documentation.
addChildViewController(svc)
view.addSubview(svc.view)
svc.didMoveToParentViewController(self)
You should first add the child view and then call didMoveToParentViewController. Try this and see if it works.
Listing 5-1Adding a child view controller to a container
- (void) displayContentController: (UIViewController*) content { [self addChildViewController:content]; content.view.frame = [self frameForContentController]; [self.view addSubview:self.currentClientView]; [content didMoveToParentViewController:self]; }
In the preceding example, notice that you call only the didMoveToParentViewController: method of the child. That is because the addChildViewController: method calls the child’s willMoveToParentViewController: method for you. The reason that you must call the didMoveToParentViewController: method yourself is that the method cannot be called until after you embed the child’s view into your container’s view hierarchy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With