Setting the text of the UITextView results on failure

I am trying to set a UITextView text that has some illegal characters like "Unicode Character" OBJECT REPLACEMENT CHARACTER (U + FFFC) ".
Basically, I have a UITextView . Now the user clicks on it and opens the keyboard. Now I use speech with text from the keyboard (also called dictation). When the dictation is being processed (while the UITextView has that special character that matches the default linker animation), I try to set the value of the text view using:

 textView.text = @"" 

This creates the following failure:

  *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds' 

The stack trace I received from crashtics:

 0 CoreFoundation __exceptionPreprocess + 130 2 CoreFoundation -[NSException initWithCoder:] 3 CoreFoundation mutateError + 222 4 Foundation -[NSString stringByReplacingCharactersInRange:withString:] + 134 5 UIKit __37-[UITextInputController textInRange:]_block_invoke + 310 6 UIFoundation -[NSTextStorage coordinateReading:] + 36 7 UIKit -[UITextInputController textInRange:] + 232 8 UIKit -[TIDocumentState(UITextInputAdditions) _contextAfterPosition:inDocument:] + 190 9 UIKit -[TIDocumentState(UITextInputAdditions) initWithDocument:] + 150 10 UIKit +[TIDocumentState(UITextInputAdditions) documentStateOfDocument:] + 52 11 UIKit -[UIKeyboardImpl updateForChangedSelectionWithExecutionContext:] + 288 12 UIKit -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 352 13 UIKit -[UIKeyboardTaskQueue performTask:] + 248 14 UIKit -[UIKeyboardImpl updateForChangedSelection] + 96 15 UIKit -[UIKeyboardImpl selectionDidChange:] + 102 16 UIFoundation -[NSTextStorage coordinateReading:] + 36 17 UIKit -[UITextInputController _coordinateSelectionChange:] + 100 18 UIKit -[UITextInputController _setSelectedTextRange:] + 604 19 UIKit -[UITextView setAttributedText:] + 392 20 UIKit -[UITextView setText:] + 134 

I also created a sample project that demonstrates this problem. You can get this project from: https://dl.dropboxusercontent.com/u/80141854/TextViewDictationCheck.zip

An exception can be reproduced in the following steps:

  • List item
  • Run the project in xcode.
  • Click on the text view. keyboard.
  • press the microphone button next to the location on the keyboard.
  • After a while (4-5 seconds) press.
  • Now you will see a rotating engine in text form. Press send while this counter moves in text mode.
  • You will get an exception.

I found one way to avoid this glitch: When setting up the UITextView text, we can use the following code:
I also found another workaround that we can use when reloading text in a UITextView:

 [self.textView setSelectedRange:NSMakeRange(0, [[self.textView textStorage] length])]; [self.textView insertText:@""]; [self.textView setText:@""]; 

But I still don't understand why this happens if we use setText: to set the text.

+7
ios objective-c unicode uitextview
source share
1 answer

The exception occurs in Foundation code, not code. There is a race condition that causes this failure if the line changes during dictation processing. It puts the placeholder on the line when you touch the microphone button, and then replaces it with text when it finishes processing. If you change the line and remove the placeholder, it will crash.

The fix is ​​to make sure you don't change the line during dictation processing. You can do this by checking the main language of the input mode. It is set to dictation during dictation:

 - (IBAction)sendPressed:(id)sender { NSString *primaryLanguage = [self.textView textInputMode].primaryLanguage; if(![primaryLanguage isEqualToString:@"dictation"]) { // Your original method body: NSString *textViewText = self.textView.text; textViewText = @""; self.textView.text = nil; self.textView.text = @""; } 

}

This skips the code to remove the text field if dictation is in progress.

+3
source share

All Articles