How to remove SFSafariViewController as a child view controller correctly?
Asked Answered
L

2

11

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?

Lindsey answered 24/2, 2016 at 9:41 Comment(0)
P
1

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.

Pussy answered 29/2, 2016 at 10:9 Comment(3)
tried the order suggested, but still the same problem remains.Lindsey
Would yoube able to use a WKWebkitView and add it as a subview to your main VC instead of using SVC?Pussy
Can you send the whole code to me for testing or a sample prototype that demonstrates this issue?Pussy
W
1

you are probably leaking svc. nil it out after removing it.

svc.willMoveToParentViewController(nil)
svc.view.removeFromSuperview()
svc.removeFromParentViewController()
svc = nil

if this doesn't solve it, try enabling zombies or use the leaks instrument

Worn answered 3/3, 2016 at 9:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.