Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSAttributedString crash when converting HTML to Attrubuted String

I have a situation where try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) crashes the app.

In the console it says: Assertion failure in void _prepareForCAFlush(UIApplication *__strong)()

The function is called in an extension String. When I 'po' values in the console:

(lldb) po self
<p>Obfuscated string\n</p>


(lldb) po data`
450 bytes
  count : 450
    pointer : 0x00007fd283d75630
    pointerValue : 140542131787312

(lldb) po NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
Obfuscated string
{
            NSColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
            NSFont = "<UICTFont: 0x7fd283c47330> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 15.00pt";
            NSKern = 0;
            NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 15, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 19/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
            NSStrokeColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
            NSStrokeWidth = 0;
}

The string exists in a label, that is displayed in a UITableViewCell. The function crashes in a specific case, when the "keyboard frame changes". The Table Cells are being drawn again by iOS and this causes to redraw their content.

The crash happens on the main thread, so the function is being called on the main thread.

What could be the cause of this crash and how could I possibly resolve it?

EDIT: Table view cell code

UITableViewDataSource to generate the cell:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellID = cellIdentifier(for: message)
        let cell = tableView.dequeueReusableCell(withIdentifier: cellID) as! MessageTableViewCell
        cell.message = message
        cell.setOutletValues()
        cell.selectionStyle = .none
        cell.delegate = self
        return cell

}

Implementaion of the Cell:

class MessageTableViewCell: UITableViewCell {

    var message: Message!

    // Message Body View
    @IBOutlet weak var messageBodyView: ZeroPaddingTextView!

    func setOutletValues() {
        setMessageBodyOutletValues()
    }

    internal func setMessageBodyOutletValues() {
        if let body = message.body {
            messageBodyView.attributedText = body.htmlToPlainAttributedString()
        }
    }
}

And the function to create a plain attributed string, it does a few additions tothe HTML for styling (this is due to the content that comes in through the API, it needs some additions).

func htmlToPlainAttributedString() -> NSAttributedString {
    let contentString = replacingOccurrences(of: "\n", with: "<br>")
    let styleSheet = "body {font-family: sans-serif; font-size: 15px; color: #000000;}\n a {text-decoration: none;}\n"
    let body = "<body>\(contentString)</body>"
    let html = "<html><head><style type=\"text/css\">\(styleSheet)</style></head>\(body)</html>"
    if let data = html.data(using: String.Encoding.unicode, allowLossyConversion: true) {
        do {
            return try NSAttributedString(data: data, options: [
                NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
        } catch {
            return NSAttributedString()
        }
    }
    return NSAttributedString()
}

Console crash output:

2017-09-05 22:37:14.692 trustedfamily-ios[70389:10080542] *** Assertion failure in void _prepareForCAFlush(UIApplication *__strong)(), /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.7.47/UIApplication.m:2395
2017-09-05 22:38:14.532 trustedfamily-ios[70389:10080542] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unexpected start state'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010452ab0b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x00000001035e8141 objc_exception_throw + 48
    2   CoreFoundation                      0x000000010452ecf2 +[NSException raise:format:arguments:] + 98
    3   Foundation                          0x00000001031b769b -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 165
    4   UIKit                               0x0000000105a31575 _prepareForCAFlush + 499
    5   UIKit                               0x0000000105a6346b _beforeCACommitHandler + 15
    6   CoreFoundation                      0x00000001044d0717 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    7   CoreFoundation                      0x00000001044d0687 __CFRunLoopDoObservers + 391
    8   CoreFoundation                      0x00000001044b5038 CFRunLoopRunSpecific + 440
    9   UIFoundation                        0x000000010a103edc -[NSHTMLReader _loadUsingWebKit] + 1954
    10  UIFoundation                        0x000000010a10522a -[NSHTMLReader attributedString] + 22
    11  UIFoundation                        0x000000010a09ded6 _NSReadAttributedStringFromURLOrData + 8926
    12  UIFoundation                        0x000000010a09bb64 -[NSAttributedString(NSAttributedStringUIFoundationAdditions) initWithData:options:documentAttributes:error:] + 117
    13  trustedfamily-ios                   0x0000000101e9e6ad _TTOFE5UIKitCSo18NSAttributedStringcfzT4dataV10Foundation4Data7optionsGVs10DictionarySSP__18documentAttributesGSqGVs33AutoreleasingUnsafeMutablePointerGSqCSo12NSDictionary____S0_ + 173
    14  trustedfamily-ios                   0x0000000101e9d9d9 _TFE5UIKitCSo18NSAttributedStringCfzT4dataV10Foundation4Data7optionsGVs10DictionarySSP__18documentAttributesGSqGVs33AutoreleasingUnsafeMutablePointerGSqCSo12NSDictionary____S0_ + 89
    15  trustedfamily-ios                   0x0000000101e9d803 _TFE17trustedfamily_iosSS27htmlToPlainAttributedStringfT_CSo18NSAttributedString + 1459
    16  trustedfamily-ios                   0x00000001020152f9 _TFC17trustedfamily_ios20MessageTableViewCell26setMessageBodyOutletValuesfT_T_ + 601
    17  trustedfamily-ios                   0x0000000102013467 _TFC17trustedfamily_ios20MessageTableViewCell15setOutletValuesfT_T_ + 103
    18  trustedfamily-ios                   0x0000000101f9a22f _TFC17trustedfamily_ios32ConversationDetailViewController9tableViewfTCSo11UITableView12cellForRowAtV10Foundation9IndexPath_CSo15UITableViewCell + 1199
    19  trustedfamily-ios                   0x0000000101f9a4d7 _TToFC17trustedfamily_ios32ConversationDetailViewController9tableViewfTCSo11UITableView12cellForRowAtV10Foundation9IndexPath_CSo15UITableViewCell + 87
    20  UIKit                               0x0000000105ba4ab2 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 750
    21  UIKit                               0x0000000105ba4cf8 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
    22  UIKit                               0x0000000105b79639 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2845
    23  UIKit                               0x0000000105b774a4 -[UITableView _setNeedsVisibleCellsUpdate:withFrames:] + 201
    24  UIKit                               0x0000000105b9626a -[UITableView _rectChangedWithNewSize:oldSize:] + 1267
    25  UIKit                               0x0000000105b96a5c -[UITableView setBounds:] + 322
    26  UIKit                               0x0000000105adee73 -[UIView(Geometry) _applyISEngineLayoutValuesToBoundsOnly:] + 598
    27  UIKit                               0x0000000105adf15e -[UIView(Geometry) _resizeWithOldSuperviewSize:] + 125
    28  UIKit                               0x000000010648f0e9 -[UIScrollView(_UIOldConstraintBasedLayoutSupport) _resizeWithOldSuperviewSize:] + 46
    29  CoreFoundation                      0x00000001044bb652 __53-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]_block_invoke + 114
    30  CoreFoundation                      0x00000001044bb56f -[__NSArrayM enumerateObjectsWithOptions:usingBlock:] + 335
    31  UIKit                               0x0000000105addbcc -[UIView(Geometry) resizeSubviewsWithOldSize:] + 183
    32  UIKit                               0x00000001063fa16d -[UIView(AdditionalLayoutSupport) _is_layout] + 168
    33  UIKit                               0x0000000105aea0a6 -[UIView(Hierarchy) _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] + 994
    34  UIKit                               0x0000000105afb55b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1268
    35  QuartzCore                          0x00000001057a4904 -[CALayer layoutSublayers] + 146
    36  QuartzCore                          0x0000000105798526 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 370
    37  UIKit                               0x0000000105ae9334 -[UIView(Hierarchy) layoutBelowIfNeeded] + 1108
    38  trustedfamily-ios                   0x0000000101fe3f4c _TFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintfT2toV12CoreGraphics7CGFloat_T_ + 284
    39  trustedfamily-ios                   0x0000000101fe3fac _TToFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintfT2toV12CoreGraphics7CGFloat_T_ + 44
    40  trustedfamily-ios                   0x0000000101fe3bf7 _TFFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintFT2toV12CoreGraphics7CGFloat8animatedSb8durationSd7optionsVSC22UIViewAnimationOptions_T_U_FT_T_ + 39
    41  trustedfamily-ios                   0x0000000101e572d7 _TTRXFo___XFdCb___ + 39
    42  UIKit                               0x0000000105af13da +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 572
    43  UIKit                               0x0000000105af18dd +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 99
    44  trustedfamily-ios                   0x0000000101fe3b7f _TFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintfT2toV12CoreGraphics7CGFloat8animatedSb8durationSd7optionsVSC22UIViewAnimationOptions_T_ + 943
    45  trustedfamily-ios                   0x0000000101fe3e1f _TToFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintfT2toV12CoreGraphics7CGFloat8animatedSb8durationSd7optionsVSC22UIViewAnimationOptions_T_ + 79
    46  trustedfamily-ios                   0x0000000101fe30e6 _TFC17trustedfamily_ios32ConversationDetailViewController23keyboardWillChangeFramefV10Foundation12NotificationT_ + 2278
    47  trustedfamily-ios                   0x0000000101fe3237 _TToFC17trustedfamily_ios32ConversationDetailViewController23keyboardWillChangeFramefV10Foundation12NotificationT_ + 71
    48  CoreFoundation                      0x00000001044c9c2c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
    49  CoreFoundation                      0x00000001044c9b29 _CFXRegistrationPost + 425
    50  CoreFoundation                      0x00000001044c9892 ___CFXNotificationPost_block_invoke + 50
    51  CoreFoundation                      0x000000010448d102 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1826
    52  CoreFoundation                      0x000000010448c261 _CFXNotificationPost + 673
    53  Foundation                          0x00000001030b6ca4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
    54  UIKit                               0x000000010649ce05 -[UIInputWindowController postStartNotifications:withInfo:] + 225
    55  UIKit                               0x000000010649f0af __77-[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:]_block_invoke.871 + 381
    56  UIKit                               0x0000000105af13da +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 572
    57  UIKit                               0x0000000105af1853 +[UIView(UIViewAnimationWithBlocks) _animateWithDuration:delay:options:animations:start:completion:] + 116
    58  UIKit                               0x000000010649eacb -[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:] + 1503
    59  UIKit                               0x00000001064a6d5e __43-[UIInputWindowController setInputViewSet:]_block_invoke.1318 + 97
    60  UIKit                               0x000000010649a59a -[UIInputWindowController performOperations:withTemplateNotificationInfo:] + 46
    61  UIKit                               0x00000001064a68ea -[UIInputWindowController setInputViewSet:] + 1753
    62  UIKit                               0x000000010649e14c -[UIInputWindowController performOperations:withAnimationStyle:] + 50
    63  UIKit                               0x0000000106114a8a -[UIPeripheralHost(UIKitInternal) setInputViews:animationStyle:] + 1505
    64  UIKit                               0x0000000106115c4b -[UIPeripheralHost(UIKitInternal) _preserveInputViewsWithId:animated:reset:] + 499
    65  UIKit                               0x0000000105bec35d -[UIViewController _presentViewController:modalSourceViewController:presentationController:animationController:interactionController:completion:] + 1145
    66  UIKit                               0x0000000105bedfae -[UIViewController _presentViewController:withAnimationController:completion:] + 4660
    67  CoreFoundation                      0x00000001044b2c6c __invoking___ + 140
    68  CoreFoundation                      0x00000001044b2b40 -[NSInvocation invoke] + 320
    69  UIKit                               0x0000000105bd1633 -[_UIDelayedPresentationContext finishDelayedPresentation:] + 230
    70  UIKit                               0x0000000105be9416 -[UIViewController _endDelayingPresentation] + 93
    71  CoreFoundation                      0x00000001044b2c6c __invoking___ + 140
    72  CoreFoundation                      0x00000001044b2b40 -[NSInvocation invoke] + 320
    73  FrontBoardServices                  0x000000010a1f25f6 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
    74  FrontBoardServices                  0x000000010a1f246d -[FBSSerialQueue _performNext] + 186
    75  FrontBoardServices                  0x000000010a1cb360 -[FBSWorkspace synchronizeSystemAnimationFencesWithCleanUpBlock:] + 1549
    76  UIKit                               0x0000000105a311d4 -[UIApplication _synchronizeSystemAnimationFencesWithSpinCleanUpBlock:] + 543
    77  UIKit                               0x0000000105ab22cd __realPreCommitHandler_block_invoke + 395
    78  QuartzCore                          0x000000010575532c _ZNK2CA11Transaction5Fence13run_callbacksEv + 40
    79  QuartzCore                          0x0000000105727f7c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 528
    80  QuartzCore                          0x0000000105754130 _ZN2CA11Transaction6commitEv + 468
    81  QuartzCore                          0x0000000105754b37 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 115
    82  CoreFoundation                      0x00000001044d0717 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    83  CoreFoundation                      0x00000001044d0687 __CFRunLoopDoObservers + 391
    84  CoreFoundation                      0x00000001044b5720 __CFRunLoopRun + 1200
    85  CoreFoundation                      0x00000001044b5016 CFRunLoopRunSpecific + 406
    86  GraphicsServices                    0x000000010a9eda24 GSEventRunModal + 62
    87  UIKit                               0x0000000105a38134 UIApplicationMain + 159
    88  trustedfamily-ios                   0x0000000101ff6837 main + 55
    89  libdyld.dylib                       0x000000010894465d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
like image 783
Bocaxica Avatar asked Sep 05 '17 13:09

Bocaxica


2 Answers

Try to make your html convert in NSAttributedString inside

DispatchQueue.main.async {

}

like image 92
IBAction Avatar answered Oct 31 '22 17:10

IBAction


I'm seeing this crash in a very similar situation in the field but can't reproduce it myself.

Let's try this and see if it helps:

guard UIApplication.shared.applicationState == .active else { return NSAttributedString() }
like image 45
mbi Avatar answered Oct 31 '22 16:10

mbi