WKWebView crashes if user answers an incoming iMessage
Asked Answered
P

3

17

My apps have a significant crash -

CALayer position contains NaN: [377.833 nan] 

with the following stack -

Fatal Exception: CALayerInvalidGeometry
0  CoreFoundation                 0x18283afe0 __exceptionPreprocess
1  libobjc.A.dylib                0x18129c538 objc_exception_throw
2  CoreFoundation                 0x18283af28 -[NSException initWithCoder:]
3  QuartzCore                     0x185b50acc CA::Layer::set_position(CA::Vec2<double> const&, bool)
4  QuartzCore                     0x185b50c48 -[CALayer setPosition:]
5  QuartzCore                     0x185b51198 -[CALayer setFrame:]
6  UIKit                          0x1889657a8 -[UIView(Geometry) setFrame:]
7  UIKit                          0x188979364 -[UIImageView _setViewGeometry:forMetric:]
8  UIKit                          0x1889c6c38 -[UIScrollView _adjustScrollerIndicators:alwaysShowingThem:]
9  UIKit                          0x188abfb34 -[UIScrollView(UIScrollViewInternal) _adjustForAutomaticKeyboardInfo:animated:lastAdjustment:]
10 WebKit                         0x18c14af3c -[WKWebView _keyboardChangedWithInfo:adjustScrollView:]
11 CoreFoundation                 0x1827d55f4 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__
12 CoreFoundation                 0x1827d4d08 _CFXRegistrationPost
13 CoreFoundation                 0x1827d4a84 ___CFXNotificationPost_block_invoke
14 CoreFoundation                 0x1828437a8 -[_CFXNotificationRegistrar find:object:observer:enumerator:]
15 CoreFoundation                 0x18271895c _CFXNotificationPost
16 Foundation                     0x18322a930 -[NSNotificationCenter postNotificationName:object:userInfo:]
17 UIKit                          0x1893500e4 -[UIInputWindowController postStartNotifications:withInfo:]
18 UIKit                          0x189352350 __77-[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:]_block_invoke.907
19 UIKit                          0x188a383cc -[UIInputViewAnimationStyle launchAnimation:afterStarted:completion:forHost:fromCurrentPosition:]
20 UIKit                          0x189351dc8 -[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:]
21 UIKit                          0x1893588b0 -[UIInputWindowController setInputViewSet:]
22 UIKit                          0x189351494 -[UIInputWindowController performOperations:withAnimationStyle:]
23 UIKit                          0x188a30d94 -[UIPeripheralHost(UIKitInternal) setInputViews:animationStyle:]
24 UIKit                          0x1890f7160 -[_UIRemoteKeyboards keyboardChanged:shouldConsiderSnapshottingKeyboard:isLocalEvent:]
25 UIKit                          0x1890f6e8c __37-[_UIRemoteKeyboards

Looking at the logs of the users I found few common things -

  1. All of the users are in a view controller that contains a WKWebView
  2. All the logs point that the app got "applicationWillResignActive" before the crash
  3. The stack shows that a keyboard was opened, but we do not have away to open the keyboard on that View Controller
  4. all users are iOS 10.3 +

The only scenario that fit was that a user got an iMessage while the app was with a visible WKWebView and force touched it to a quick answer. We tested this scenario and BOOOM the app crashed.

So we found the crash, but we do not have a clue what is going on. Any one faced that issue or has an idea what could it be?

Thanks

Plerre answered 18/7, 2017 at 9:43 Comment(7)
Can you reproduce this issue with a project built from scratch (so just minimal setup + WKWebView)?Nomology
I second the motion to reproduce with a separate project. In the mean time, in your current project that is actually crashing, set a symbolic break point on [CALayer setPosition:] and print out the position being set by doing po NSStringFromCGPoint(position). Also set a symbolic breakpoint on [UIView setFrame:] right before it happens. Again, print the frame. See what is being set. See if the frame of your webview is valid or not. Check your constraints, etc..Dendrite
Tried and played with scenario you mentioned but couldn't produce a crash. Seems something else is broken.Disincentive
Did you try to resign keyboard in applicationWillResignActive?Karp
This usually happens to invalid float values, also NaN is most commonly returned when you have a division by zero...Jocular
Could that the keyboard be opened on a controller presented from the web view controller?Richma
Anyway, it seems that the webview is ending with a zero/negative height, which probably crashes it. So make sure the controller can handle that.Richma
S
2

Not sure if it helps you. I have also faced the NAN issue and it happens if any value is corrupted or invalid. So if you can find out where your value is getting corrupted means it is printing NAN then on that you can put the guard statement.

Soricine answered 28/7, 2017 at 3:23 Comment(0)
S
2

(1) First Double check your layout is correct, use "Autolayout" and make sure your constraints are correct and you are setting the subviews correct.

Try to visually debug the layout to see if there are any strange things happening.

Debug->View Debugging->Capture View Hierarchy.

(2) From the stack trace I notice that the keyboard gets presented, and because of this, the views need to be adjusted to make place for the keyboard. It is noticeable this happens as soon as an message arrives in the stack trace.

I would also attempt to resignFirstResponder, maybe in your AppDelegate

- (void)applicationWillResignActive:(UIApplication *)application {
   [_wkWebView resignFirstResponder];
}

(3) I have also found that there is a bug, where the WKWEbView will not resignFirstResponder.. this might be related:

Bug 167898 - [iOS] -[WKWebView becomeFirstResponder] and -[WKWebView resignFirstResponder] don’t get called when non-programmatic first responder changes happen

Maybe a workaround then would be to present another view as soon as your application will resign.

- (void)applicationWillResignActive:(UIApplication *)application {
    // if _wkWebView is showing then hide and show other view
}
Sepulture answered 28/7, 2017 at 12:9 Comment(0)
E
0

set the CG_NUMERICS_SHOW_BACKTRACE environmental variable in the Xcode run scheme and it will dump the stacktrace that caused the non-numeric value to occur.

Elytron answered 30/7, 2017 at 11:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.