Nano Hash - криптовалюты, майнинг, программирование

Сбой UIWebview [UIThreadSafeNode _responderForEditing]

Итак, у меня есть приложение, основанное на веб-просмотре. Я сделал несколько модификаций клавиатуры (это не проблема, я удалил их все для устранения неполадок).

На симуляторе iPhone 6+ в ландшафтном режиме, если что-то копируется, и вы переходите к кнопке вставки с клавиатуры (не контекстной), приложение вылетает. Я также заметил это при попытке использовать кнопку отключения клавиатуры.

Следующий сбой выглядит следующим образом:

    -[UIThreadSafeNode _responderForEditing]: unrecognized selector sent to instance 0x7ff4364344c0
    *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIThreadSafeNode _responderForEditing]: unrecognized selector sent to instance 0x7ff4364344c0'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010df98f45 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010da12deb objc_exception_throw + 48
    2   CoreFoundation                      0x000000010dfa156d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x000000010deeeeea ___forwarding___ + 970
    4   CoreFoundation                      0x000000010deeea98 _CF_forwarding_prep_0 + 120
    5   UIKit                               0x000000010c31eb4a -[UIKeyboardLayoutStar touchDownWithKey:atPoint:executionContext:] + 1445
    6   UIKit                               0x000000010c878ef0 -[UIKeyboardTaskExecutionContext returnExecutionToParentWithInfo:] + 278
    7   UIKit                               0x000000010c3169de -[UIKeyboardLayoutStar performHitTestForTouchInfo:touchStage:executionContextPassingUIKBTree:] + 1525
    8   UIKit                               0x000000010c31de57 -[UIKeyboardLayoutStar touchDown:executionContext:] + 533
    9   UIKit                               0x000000011df96fb5 -[UIKeyboardLayoutStarAccessibility touchDown:executionContext:] + 61
    10  UIKit                               0x000000010c8793ab -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 332
    11  UIKit                               0x000000010c1347bd -[UIKeyboardLayout touchDown:] + 159
    12  UIKit                               0x000000010c1352ef -[UIKeyboardLayout touchesBegan:withEvent:] + 415
    13  UIKit                               0x000000010bee2cc2 -[UIWindow _sendTouchesForEvent:] + 308
    14  UIKit                               0x000000010bee3c06 -[UIWindow sendEvent:] + 865
    15  UIKit                               0x000000010be932fa -[UIApplication sendEvent:] + 263
    16  UIKit                               0x000000011df66a29 -[UIApplicationAccessibility sendEvent:] + 77
    17  UIKit                               0x000000010be6dabf _UIApplicationHandleEventQueue + 6844
    18  CoreFoundation                      0x000000010dec5011 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    19  CoreFoundation                      0x000000010debaf3c __CFRunLoopDoSources0 + 556
    20  CoreFoundation                      0x000000010deba3f3 __CFRunLoopRun + 867
    21  CoreFoundation                      0x000000010deb9e08 CFRunLoopRunSpecific + 488
    22  GraphicsServices                    0x000000010ead2ad2 GSEventRunModal + 161
    23  UIKit                               0x000000010be7330d UIApplicationMain + 171

Очевидно, что, поскольку я использую веб-просмотр, нет фактического текстового просмотра, который можно было бы связать с ним.

Как бы я решил это? Меня не волнует прохождение проверки в магазине приложений, поэтому приветствуется частный API или другие методы, не одобренные Apple.

Будем очень благодарны любой помощи. Благодарю вас.


Ответы:


1

Это ошибка Apple, потому что этот селектор должен быть передан UIResponder, но UIThreadSafeNode является подклассом NSObject. Чтобы решить эту проблему, вы можете реализовать категорию NSObject:

@interface UIView (FirstResponder)

-(id)findFirstResponder;

@end

@implementation UIView (FirstResponder)

- (id)findFirstResponder
{
    if (self.isFirstResponder) {
        return self;
    }
    for (UIView *subView in self.subviews) {
        id responder = [subView findFirstResponder];
        if (responder) return responder;
    }
    return nil;
}

@end


@interface NSObject (KeyboardBUI)

-(_Nonnull id)_responderForEditing;

@end

@implementation NSObject (KeyboardBUI)

-(_Nonnull id)_responderForEditing
{
    return self;
}

-(void)cut:(nullable id)sender
{
    NSString *selection = [[self getWebView] stringByEvaluatingJavaScriptFromString:@"window.getSelection().toString()"];
    [[self getWebView] stringByEvaluatingJavaScriptFromString:@"document.execCommand('delete', false, null)"];
    [UIPasteboard generalPasteboard].string = selection;
}

-(void)paste:(nullable id)sender
{
    NSString *text = [UIPasteboard generalPasteboard].string;
    [[self getWebView] stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.execCommand('insertHTML', false, '%@')", text]];
}

-(void)copy:(nullable id)sender
{
    NSString *selection = [[self getWebView] stringByEvaluatingJavaScriptFromString:@"window.getSelection().toString()"];
    [UIPasteboard generalPasteboard].string = selection;
}

-(void)toggleItalics:(nullable id)sender
{
    [[self getWebView] stringByEvaluatingJavaScriptFromString:@"document.execCommand(\"Italic\")"];
}

-(void)toggleUnderline:(nullable id)sender
{
    [[self getWebView] stringByEvaluatingJavaScriptFromString:@"document.execCommand(\"Underline\")"];
}

-(void)toggleBoldface:(nullable id)sender
{
    [[self getWebView] stringByEvaluatingJavaScriptFromString:@"document.execCommand(\"Bold\")"];
}

-(UIWebView * __nullable)getWebView
{
    UIWebView *retVal = nil;
    id obj = [[[[[UIApplication sharedApplication] keyWindow] findFirstResponder] superview] superview];
    if ([obj  isKindOfClass:[UIWebView class]]) {
        retVal = obj;
    }
    return retVal;
}

@end

ПРИМЕЧАНИЕ. Я не знаю, пройдет ли это проверку Apple Appstore.

UIView (FirstResponder) из этого ответа.

скопировать/вставить/вырезать из этого ответа

04.02.2016
  • Я должен был обновить этот вопрос, так как теперь я переключился на использование WKWebView. Так что это уже не проблема. Но тем не менее я ценю ответ. Я проголосую за, и, надеюсь, если это поможет кому-то в той же ситуации, они смогут пометить ответ как принятый. 04.02.2016
  • Это работает, за исключением того, что вы должны избегать любых апострофов в скопированном тексте при построении строки execCommand в paste. Один из способов сделать это: NSString *text = [[UIPasteboard generalPasteboard].string stringByReplacingOccurrencesOfString:@"'" withString:@"'"]; 17.05.2016
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..