iOS 15 Crash on [WebLowPowerModeObserver _didReceiveLowPowerModeChange] when convert HTML to NSAttributedString

The app which is archived by XCode 12.5 and running on iOS 15 when I convert HTML to NSAttributedString. (iOS 14 is fine).

Here is the crash report.

Thread 0 name:
Thread 0 Crashed:
0   libsystem_platform.dylib      	0x00000001f2e5e0c0 _os_unfair_lock_recursive_abort + 36 (lock.c:508)
1   libsystem_platform.dylib      	0x00000001f2e58a10 _os_unfair_lock_lock_slow + 304 (lock.c:567)
2   Foundation                    	0x00000001841e6730 -[NSProcessInfo(NSProcessInfoHardwareState) isLowPowerModeEnabled] + 68 (NSProcessInfo.m:708)
3   WebCore                       	0x0000000192499004 -[WebLowPowerModeObserver _didReceiveLowPowerModeChange] + 56 (LowPowerModeNotifier.mm:63)
4   CoreFoundation                	0x00000001829bdee8 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 28 (CFNotificationCenter.c:652)
5   CoreFoundation                	0x0000000182a59b9c ___CFXRegistrationPost_block_invoke + 52 (CFNotificationCenter.c:173)
6   CoreFoundation                	0x0000000182a2cf54 _CFXRegistrationPost + 456 (CFNotificationCenter.c:199)
7   CoreFoundation                	0x00000001829d3d54 _CFXNotificationPost + 716 (CFNotificationCenter.c:1147)
8   Foundation                    	0x00000001841d8028 -[NSNotificationCenter postNotificationName:object:userInfo:] + 96 (NSNotification.m:560)
9   Foundation                    	0x00000001842509d4 NSProcessInfoNotifyPowerState + 188 (NSProcessInfo.m:693)
10  Foundation                    	0x00000001841e6768 -[NSProcessInfo(NSProcessInfoHardwareState) isLowPowerModeEnabled] + 124 (NSProcessInfo.m:714)
11  WebCore                       	0x0000000191a1d118 -[WebLowPowerModeObserver initWithNotifier:] + 96 (LowPowerModeNotifier.mm:50)
12  WebCore                       	0x000000019249916c WebCore::LowPowerModeNotifier::LowPowerModeNotifier(***::Function<void (bool)>&&) + 52 (LowPowerModeNotifier.mm:76)
13  WebCore                       	0x00000001933bec4c WebCore::Page::Page(WebCore::PageConfiguration&&) + 1848 (memory:2099)
14  WebKitLegacy                  	0x00000001a64e2e34 -[WebView(WebPrivate) _commonInitializationWithFrameName:groupName:] + 3060 (WebView.mm:1568)
15  WebKitLegacy                  	0x00000001a64e2214 -[WebView(WebPrivate) _initWithFrame:frameName:groupName:] + 116 (WebView.mm:1715)
16  UIFoundation                  	0x000000018d78e028 -[NSHTMLReader _loadUsingWebKit] + 832 (NSHTMLReader.m:2570)
17  UIFoundation                  	0x000000018d78f15c -[NSHTMLReader attributedString] + 32 (NSHTMLReader.m:3212)
18  UIFoundation                  	0x000000018d7484e8 _NSReadAttributedStringFromURLOrData + 8420 (NSAttributedStringAdditions.m:2651)
19  UIFoundation                  	0x000000018d746378 -[NSAttributedString(NSAttributedStringUIFoundationAdditions) initWithData:options:documentAttributes:error:] + 156 (NSAttributedStringAdditions.m:1462)
20 MyAppExtensions                 0x108aa0894 NSAttributedString.init(htmlString:font:useDocumentFontSize:) + 36 (__hidden#925_:36)
21 MyAppName                           0x1045eca18 {foo_class}.convertHTML(_:) + 670 (xxxx.swift:670)
22 MyAppName                           0x1045e5c58 {foo_class}.some_function_3 + 620 (xxxx.swift:620)
23 MyAppName                           0x1045e4760 {foo_class}.some_function_2 + 212 (xxxx.swift:212)
24 MyAppName                           0x1045e4200 {foo_class}.some_function_1 + 138 (xxxx.swift:138)
. (some other functions related to my business logic)
.
.
.
37  CoreFoundation                	0x00000001829b5304 __invoking___ + 148
38  CoreFoundation                	0x00000001829d2ad4 -[NSInvocation invoke] + 468 (NSForwarding.m:3378)
39  CoreFoundation                	0x0000000182a09934 -[NSInvocation invokeWithTarget:] + 80 (NSForwarding.m:3475)
40  Lime                          	0x00000001037fba58 0x102838000 + 16530008
41  CoreFoundation                	0x00000001829c118c ___forwarding___ + 968 (NSForwarding.m:3626)
42  CoreFoundation                	0x00000001829c05c0 _CF_forwarding_prep_0 + 96
43  MyAppName                          	0x0000000103807558 0x102838000 + 16577880
44  MyAppName                          	0x000000010382084c 0x102838000 + 16681036
45  UIKitCore                     	0x000000018501d584 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 56 (UIGestureRecognizer.m:136)
46  UIKitCore                     	0x0000000184fe61d0 _UIGestureRecognizerSendTargetActions + 116 (UIGestureRecognizer.m:1481)
47  UIKitCore                     	0x0000000184faf05c _UIGestureRecognizerSendActions + 284 (UIGestureRecognizer.m:1520)
48  UIKitCore                     	0x0000000184fe8580 -[UIGestureRecognizer _updateGestureForActiveEvents] + 636 (UIGestureRecognizer.m:0)
49  UIKitCore                     	0x0000000184fa06fc _UIGestureEnvironmentUpdate + 1988 (UIGestureEnvironment.m:206)
50  CoreFoundation                	0x00000001829d4570 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36 (CFRunLoop.c:1804)
51  CoreFoundation                	0x00000001829a3854 __CFRunLoopDoObservers + 572 (CFRunLoop.c:1917)
52  CoreFoundation                	0x000000018299e8ec __CFRunLoopRun + 1052 (CFRunLoop.c:2979)
53  CoreFoundation                	0x00000001829b23c8 CFRunLoopRunSpecific + 600 (CFRunLoop.c:3268)
54  GraphicsServices              	0x000000019e1c338c GSEventRunModal + 164 (GSEvent.c:2200)
55  UIKitCore                     	0x00000001853580bc -[UIApplication _run] + 1100 (UIApplication.m:3457)
56  UIKitCore                     	0x00000001850d5be8 UIApplicationMain + 2124 (UIApplication.m:5013)
57  libswiftUIKit.dylib           	0x0000000199f86184 UIApplicationMain(_:_:_:_:) + 104 (UIKit.swift:530)
58  Lime                          	0x000000010284d894 main + 180 (main.swift:7)
59  dyld                          	0x0000000104e59a24 start + 520 (dyldMain.cpp:876)

Any thoughts? Thanks

===

Add more information, the converting HTML to NSAttributedString function is like

convenience public init(htmlString html: String, font: UIFont? = nil, useDocumentFontSize: Bool = true) throws {
  let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
   .documentType: NSAttributedString.DocumentType.html,
   .characterEncoding: String.Encoding.utf8.rawValue
  ]

  guard let data = html.data(using: .utf8, allowLossyConversion: true) else {
   self.init(string: "")
   return
  }

  guard let fontFamily = font?.familyName else {
   try self.init(data: data, options: options, documentAttributes: nil)
   return
  }

  let attr = try NSMutableAttributedString(data: data, options: options, documentAttributes: nil)

  let fontSize: CGFloat? = useDocumentFontSize ? nil : font!.pointSize
  let range = NSRange(location: 0, length: attr.length)
  attr.enumerateAttribute(.font, in: range, options: .longestEffectiveRangeNotRequired) { attrib, range, _ in
   if let htmlFont = attrib as? UIFont {
    let traits = htmlFont.fontDescriptor.symbolicTraits
    var descrip = htmlFont.fontDescriptor.withFamily(fontFamily)

    if (traits.rawValue & UIFontDescriptor.SymbolicTraits.traitBold.rawValue) != 0 {
     descrip = descrip.withSymbolicTraits(.traitBold)!
    }

    if (traits.rawValue & UIFontDescriptor.SymbolicTraits.traitItalic.rawValue) != 0 {
     descrip = descrip.withSymbolicTraits(.traitItalic)!
    }

    attr.addAttribute(.font, value: UIFont(descriptor: descrip, size: fontSize ?? htmlFont.pointSize), range: range)
   }
  }

  self.init(attributedString: attr)

I generally recommend that you avoid using this HTLML-to-attribute string code path. See this thread for the backstory.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

This crash only applies to iOS 15, are there any changes resulting in this crash?

iOS 15 is a major OS release so it’s impossible to enumerate all the changes that could create this specific crash.

Personally I try to avoid the HTML initialisation path entirely. At indicates by the thread I mentioned earlier it has never been particularly reliable. You would be better served by either:

  • Loading the HTML in a web view proper, if the HTML is unconstrained

  • Switching to iOS 15’s new Markdown support, if the HTML is constrained

Having said that, this code shouldn’t crash and you should feel free to file a bug about that. Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Can you point to which iOS 15 markdown support are you referring to

WWDC 2021 Session 10109 What’s new in Foundation is an excellent intro.

from what I see its only supports SwiftUI which don't use in our app.

While SwiftUI uses this stuff, it’s not the only client. The Markdown support is implemented at the Foundation level and gives you back an attributed string that you can then use with your UI framework of choice.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

This issue is happening to lot of other people as on ios 15 any update from apple side? https://stackoverflow.com/questions/69340198/ios-15-crash-when-initialize-nsattributedstring-with-html-string.

We have submitted ios 15 bug for this but haven't heard back.

We have submitted ios 15 bug for this

What was the bug number?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Bug number FB9668167

Bug number FB9668167

Thanks!

Your bug is flagged as a duplicate of another bug that’s still being investigated.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

iOS 15 Crash on [WebLowPowerModeObserver _didReceiveLowPowerModeChange] when convert HTML to NSAttributedString
 
 
Q