Application error with voice every time you enable textbox with link in it

Stack trace:

* thread #1: tid = 0x1ee50f, 0x00000001096f5d05 libswiftFoundation.dylib`static Foundation.DateComponents._unconditionallyBridgeFromObjectiveC (Swift.Optional<__ObjC.NSDateComponents>) -> Foundation.DateComponents with unmangled suffix "_merged" + 85, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
frame #0: 0x00000001096f5d05 libswiftFoundation.dylib`static Foundation.DateComponents._unconditionallyBridgeFromObjectiveC (Swift.Optional<__ObjC.NSDateComponents>) -> Foundation.DateComponents with unmangled suffix "_merged" + 85
frame #1: 0x000000010558e36f Invest`@objc InvestDashboard.textView(UITextView, shouldInteractWith : URL, in : _NSRange) -> Bool + 79 at InvestDashboard.swift:0
frame #2: 0x000000011fd478fc UIKit`-[UITextViewAccessibility accessibilityActivate] + 838
frame #3: 0x000000011fed29d2 UIAccessibility`-[NSObject(UIStorage) accessibilityPerformAction:withValue:fencePort:] + 1448
frame #4: 0x000000011feaa63d UIAccessibility`_performActionCallback + 163
frame #5: 0x000000011fc0cec4 AXRuntime`_AXXMIGPerformAction + 107
frame #6: 0x000000011fc06f06 AXRuntime`_XPerformAction + 216
frame #7: 0x000000011fc16541 AXRuntime`mshMIGPerform + 266
frame #8: 0x0000000106d1ff89 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
frame #9: 0x0000000106d1ff01 CoreFoundation`__CFRunLoopDoSource1 + 465
frame #10: 0x0000000106d18045 CoreFoundation`__CFRunLoopRun + 2389
frame #11: 0x0000000106d17494 CoreFoundation`CFRunLoopRunSpecific + 420
frame #12: 0x000000010cc38a6f GraphicsServices`GSEventRunModal + 161
frame #13: 0x00000001078c2964 UIKit`UIApplicationMain + 159
frame #14: 0x000000010467e99f InvestDemo`main + 111 at AppDelegate.swift:29
frame #15: 0x000000010b88268d libdyld.dylib`start + 1
frame #16: 0x000000010b88268d libdyld.dylib`start + 1

      

This happens whenever I use an activate TextView that has a link in it. I've tried many different things like overriding accessibilityActivate() -> Bool

, but the app crashes before this method is ever called. Any suggestions?

+3


source to share


3 answers


I solved this problem and wanted to share so others with the same confusing problem can fix it.

The first thing to do is to subclass UITextView

and override in that subclass func accessibilityActivate() -> Bool

. Then make a delegate that handles what happens when the TextView is activated and calls it through an overridden method.

Then set the TextView delegate based on UIAccessibilityIsVoiceOverRunning()

, so if voice trigger is started, set UITextViewDelegate

to nil

that prevents the crash from occurring, and then the activation action is handled by the method you overridden in the subclass above. Finally, set up a listener for UIAccessibilityVoiceOverStatusChanged

and set the parameter UITextViewDelegate

in nil

when going from enabled to enabled and set it to the original delegation class for the opposite scenario.



Some codes:

//: Playground - noun: a place where people can play

import UIKit

class Test : UITabBarController, UITextViewDelegate, ActivationDelegate {

    var voiceOverRunning : Bool {
        get {
            return UIAccessibilityIsVoiceOverRunning()
        }
    }

    var testView = AccessibilityView()

    override func viewDidLoad() {
        if !voiceOverRunning {
            testView.delegate = self
        } else {
            testView.activationDelegate = self
        }

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(self.didChangeVoiceOver),
            name: NSNotification.Name(rawValue: UIAccessibilityVoiceOverStatusChanged),
            object: nil)
    }

    func doStuff() {
        /*
         Do what you want to happen here on activation
         */
    }


    @objc
    func didChangeVoiceOver(){
        testView.delegate              = voiceOverRunning ? nil : self
        testView.activationDelegate    = voiceOverRunning ? self : nil
    }


}

protocol ActivationDelegate : class {
    func doStuff()
}
class AccessibilityView : UITextView {

    var activationDelegate : ActivationDelegate!

    override func accessibilityActivate() -> Bool {
        activationDelegate.doStuff()
        return true
    }
}

      

+1


source


I've seen this issue, except for my unconditional bridge error in NSURL. This happens when I have static text set as a UIAccessibilityTrait and the UITextView has a link in the attributed text. The only possible answer I have found is that it is a bug in the header header signature and one of the languages ​​is trying to call delegate methods differently than it should. My solution was to remove the delegate method (shouldInteractWith url), but it also worked if I duplicated the method and made some of the parameters optional. I haven't really seen how the delegate methods are called, so I think the browser opening the link is handled automatically.

TL; DR; I think you have three options:



  • You can turn off static text if you don't need it.
  • Add duplicate delegate methods with optional parameters until you find a signature that works.
  • Remove delegate methods entirely.
+1


source


I just ran into this and noticed this detail: the crash only happens for me when I have iOS 9 version UITextViewDelegate

. My code looked like this:

extension ViewController: UITextViewDelegate {
    @available(iOS 10.0, *)
    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        return true
    }
    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
        return true
    }
}

      

Removing textView(_:shouldInteractWith:in:)

and @available

(and raising my goal to iOS 10) resolved the crash.

Unfortunately for me this is not an option.

I have registered https://bugreport.apple.com/web/?problemID=34187849 for the problem. I'm pretty sure it will just be ignored as it includes iOS 9 support.

+1


source







All Articles