После обновления до Xcode 11.2 с Xcode 11.1 приложение вылетает из-за _UITextLayoutView

351

После обновления до Xcode 11.2 с Xcode 11.1 мое приложение вылетает:

*** Завершение работы приложения из-за необработанного исключения «NSInvalidUnarchiveOperationException», причина: «Не удалось создать экземпляр класса с именем _UITextLayoutView, поскольку не найден класс с именем _UITextLayoutView; класс должен быть определен в исходном коде или связан с библиотекой (убедитесь, что класс является частью правильной цели) '

Почему это происходит? Как я могу предотвратить этот сбой?

Судхакар Таригоппула
источник
17
Похоже, ошибка Xcode 11.2. Проверьте ветку forum.developer.apple.com/thread/125287 . Скорее всего, это связано с TextViews в иерархии
Павел Степанов
3
@DanielStorm, к сожалению, это не помогло. Я только что добавил простой UITextView на один экран, на котором его раньше не было (и раньше он тоже не падал :)). Теперь вылетает с той же ошибкой. Проблема сохраняется для всех устройств / симуляторов, за исключением последней iOS 13.2
Павел Степанов
3
Кто-нибудь знает, приведет ли это к краху производственных приложений, созданных с помощью Xcode 11.2, при работе на устройствах iOS 13.1.2?
gfpacheco
2
это очень хороший вопрос, отсюда и 198 голосов, поэтому я действительно не уверен, почему кто-то пометил его как «
Майк Волмар,
4
@MikeVolmar Я проголосовал за закрытие и больше не актуально. Это исправлено с 11.2.1. У этого вопроса было очень короткое окно полезности.
rmaddy

Ответы:

145

поздравление

Доступна новая версия Xcode (11.2.1), которая является лучшим способом избавиться от этой проблемы.

обходные

@Mojtaba Hosseini Решение, которое я предложил, было от помощи и участия моей стороны до моих коллег-разработчиков через StackOverflow. Вы, я и все остальные разработчики здесь уже знаете, что когда Apple выпустит новую версию, эта проблема исчезнет.

Но кроме всего

Вышеупомянутое решение было определенно принято Apple Review, так как не было задействовано никакого частного API. Этот подход очень похож на создание свойства, как

@interface UITextView (Layout)

Или

UITextView + Layout.h

Поэтому, когда вы создаете свойство, вы напрямую используете APPLE Private Components и повторно модулируете их в соответствии с вашими требованиями или требованиями.

Простой пример - AMFNetworking классы

- (void)setImageWithURL:(NSURL *)url {
    [self setImageWithURL:url placeholderImage:nil];
}

Надеюсь, я закончил с утверждением

Ответ, приведенный ниже, был лишь некоторой помощью с моей стороны, которая позволила разработчику продолжить развитие, так как вы изначально предложили разработчику откатить Xcode. Это была плохая практика, чтобы снова загрузить 8 ГБ XCode, поскольку мы все знаем, что скоро будет выпущена новая версия XCode.

Хотя это исправлено в Xcode 11.2.1, у меня есть одно решение для Xcode 11.2, с помощью которого вы можете избавиться от этой аварии:

*** Завершение работы приложения из-за необработанного исключения «NSInvalidUnarchiveOperationException», причина: «Не удалось создать экземпляр класса с именем _UITextLayoutView, поскольку не найден класс с именем _UITextLayoutView; класс должен быть определен в исходном коде или связан с библиотекой (убедитесь, что класс является частью правильной цели) '

РЕШЕНИЕ

Перейдите к поиску параметров сборки для "DEAD_CODE_STRIPPING" и установите для него значение NO

DEAD_CODE_STRIPPING = NO

затем

создавать файлы UITextViewWorkaround

UITextViewWorkaround.h

    #import <Foundation/Foundation.h>


    @interface UITextViewWorkaround : NSObject
    + (void)executeWorkaround; 
@end

UITextViewWorkaround.m

#import "UITextViewWorkaround.h"
#import  <objc/runtime.h>



    @implementation UITextViewWorkaround

    + (void)executeWorkaround {
        if (@available(iOS 13.2, *)) {
        }
        else {
            const char *className = "_UITextLayoutView";
            Class cls = objc_getClass(className);
            if (cls == nil) {
                cls = objc_allocateClassPair([UIView class], className, 0);
                objc_registerClassPair(cls);
    #if DEBUG
                printf("added %s dynamically\n", className);
    #endif
            }
        }
    }

    @end

выполнить его в приложении делегата

#import "UITextViewWorkaround.h"

        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
            // Override point for customization after application launch.

            [UITextViewWorkaround executeWorkaround];
    return yes;
    }

Скомпилируйте код, и у вас будет запущено приложение :)

афтаб мухаммед хан
источник
2
Если это работает для вас, пожалуйста,
оцените,
3
@Hardy_Germany Я немного протестировал это, для Swift вы можете попробовать: class UITextViewWorkaround: NSObject {class func executeWorkaround () {if #available (iOS 13.2, *) {} else {let className = "_UITextLayoutView" var cls = objc_getClass (className ) if cls == nil {cls = objc_allocateClassPair (UIView.self, className, 0) objc_registerClassPair (cls as! AnyClass) #if DEBUG print ("добавлено% @ динамически \ n", className); #endif}}}}
Джон Нимис
2
@DaveDude DEAD_CODE_STRIPPING = НЕТ требуется, если вы используете Swift Package Manager с Xcode 11.2
Cœur
5
@pradipsutariya да, конечно, почему бы нам никогда не изменить что-либо в APPLE CLASSES.
Афтаб Мухаммед Хан
5
Выпущено только Xcode 11.2.1 GM seed (бета). Стабильная версия может скоро выйти.
Лал Кришна
221

Обновление: исправлено! 🎉🎊

ЕДИНСТВЕННОЕ решение - обновить

Эта ошибка является фиксированной в Xcode 11.2.1. Таким образом, вы можете скачать и использовать его здесь.

Раскадровки, содержащие UITextView, больше не будут вызывать сбой приложения в версиях операционной системы, предшествующих iOS 13.2, tvOS 13.2 или macOS 10.15.2. (56808566, 56873523)


Xcode 11.2 устарела Apple 5 ноября 2019 года

если вы когда-нибудь попытаетесь отправить свое приложение, созданное с помощью Xcode 11.2, в AppStore, вам будет отказано:

App Store Connect Операция Предупреждение

ПРЕДУПРЕЖДЕНИЕ ITMS-90703 : «Устаревшая сборка Xcode. Из -за решенных проблем с архивами приложений мы устарели в Xcode 11.2 5 ноября 2019 года. Скачайте Xcode 11.2.1 или более новую версию, пересоберите приложение и повторите отправку».

Таким образом, все обходные пути, сделанные с Xcode 11.2, бесполезны


Это ошибка для Xcode 11.2 и исправлена ​​в Xcode 11.2.1.

Решение (s)

Откат к предыдущей версии выпуска Xcode из: Откат больше не вариант, и AppStore отклонит любую сборку с Xcode ниже 11.2.1, посмотрите на это

https://developer.apple.com/services-account/download?path=/Developer_Tools/Xcode_11.1/Xcode_11.1.xip

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

Вы можете найти все другие версии Xcode и ссылку на другие ресурсы (включая релизные и бета-версии) здесь на https://developer.apple.com/download/more

Обходной путь

Это очень сложный, но рабочий обходной путь. Замените все UITextViews в раскадровке s и Xib s чистым кодом версией .


Обратите внимание, что эта ошибка найдена и исправлена ​​Apple

Исправлена

Также ранее ошибка была подтверждена сотрудниками Apple Edford

подтверждение


Для тех, кто с iOS 13.2 и не может больше использовать Xcode 11.1:

  1. Обновите macOS до 10.15.1 или новее
  2. Установите Xcode 11.2.1 или новее
  3. Надо работать сейчас на обновленном устройстве.

Для тех, у кого раскадровка:

  1. Подкласс UITextView
  2. Назначьте это всем UITextViewобъектам
  3. Не забудьте обновить любые изменения свойств, которые могут потеряться в подклассе.

Для тех, кто знаком с методом Swizzling (Objc и динамическое поведение)

Перейдите к ответу @aftab Мухаммеда Хана для Objective-C и ответа @MikRo для адаптированной версии Swift.

Просто не делай этого больше:

Даже если эти два последних обходных обходных пути не используют закрытый API Apple , они будут отклонены в AppStore, поскольку Apple не будет принимать сборки с версиями Xcode под 11.2.1. !

И снова:

Xcode 11.2 устарела Apple 5 ноября 2019 года

Мойтаба Хоссейни
источник
3
Грустно, но решение работает для меня. Спасибо! 11,1 работ. Я бы не советовал переходить на чистый код, потому что готов поспорить, что скоро выйдет исправление. Если вы не возражаете: обновите этот ответ, как только появится новая версия, которая работает. Было бы плохо, если бы люди начали скачивать событие 11.1, хотя там есть фиксированная версия :)
Себастьян Вайс
2
У меня уже есть 11.1, но я не работал, я не обновился до 11.2.
JAHelia
6
Обратите внимание, что вам, вероятно, следует удалить приложение с устройства разработки и / или очистить папку сборки Xcode ( CMD + Shift + K)
JeroenJK
3
Как я могу перейти на v11.2.1? Это не появляется в магазине приложений. А загрузка GM GM с портала разработчика пытается загрузить приложение примерно за 8 ГБ!
Mesqueeb
3
Кроме того, если это устарело, почему Apple сейчас просто не удаляет 11.2 в магазине приложений?
Малкольм Сальвадор
40

Проблема была исправлена ​​в Xcode 11.2.1.

РЕДАКТИРОВАТЬ: Поскольку исправление теперь выпущено, вы должны переключиться на ту версию XCode и закомментировать этот обходной путь. Как сказал Моджтаба Хоссейни в своем ответе:

... последние два обходных пути используют закрытый API Apple и будут отклонены из обзора Apple!

Пока Apple не выпустила исправление, это был хороший обходной путь для продолжения разработки и тестирования.


Для Xcode 11.2, основанного на идее Афтаба Мухаммеда Хана и с помощью Джона Нимиса, я только что протестировал следующий код.

Никаких изменений в файлах раскадровки не требуется!

Отредактировал мой файл AppDelegate.swift и добавил этот класс

//******************************************************************
// MARK: - Workaround for the Xcode 11.2 bug
//******************************************************************
class UITextViewWorkaround: NSObject {

    // --------------------------------------------------------------------
    // MARK: Singleton
    // --------------------------------------------------------------------
    // make it a singleton
    static let unique = UITextViewWorkaround()

    // --------------------------------------------------------------------
    // MARK: executeWorkaround()
    // --------------------------------------------------------------------
    func executeWorkaround() {

        if #available(iOS 13.2, *) {

            NSLog("UITextViewWorkaround.unique.executeWorkaround(): we are on iOS 13.2+ no need for a workaround")

        } else {

            // name of the missing class stub
            let className = "_UITextLayoutView"

            // try to get the class
            var cls = objc_getClass(className)

            // check if class is available
            if cls == nil {

                // it's not available, so create a replacement and register it
                cls = objc_allocateClassPair(UIView.self, className, 0)
                objc_registerClassPair(cls as! AnyClass)

                #if DEBUG
                NSLog("UITextViewWorkaround.unique.executeWorkaround(): added \(className) dynamically")
               #endif
           }
        }
    }
}

и внутри вызова делегата для "didFinishLaunchingWithOptions" вызовите обходной путь

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // Override point for customization after application launch.

    // This is the workaround for Xcode 11.2
    UITextViewWorkaround.unique.executeWorkaround()
}
Hardy_Germany
источник
34

Я адаптировал ханское решение Obj-C для Swift :

import UIKit

@objc
class UITextViewWorkaround : NSObject {

    static func executeWorkaround() {
        if #available(iOS 13.2, *) {
        } else {
            let className = "_UITextLayoutView"
            let theClass = objc_getClass(className)
            if theClass == nil {
                let classPair: AnyClass? = objc_allocateClassPair(UIView.self, className, 0)
                objc_registerClassPair(classPair!)
            }
        }
    }

}

Назовите это в конце didFinishLaunchingWithOptionsв AppDelegate.

Спасибо @Aftab!

Mikro
источник
где нам нужно добавить этот код? В файлах делегатов?
Сидхарт ПУ
@SIDHARTHPU вы можете позвонить в этоdidFinishLaunchingWithOptions
Лал Кришна
пробовал множество исправлений по этому вопросу, и этот добился цели до Xcode 11.3 ?! Спасибо!
FlimFlam Vir
1
Это самое короткое и блестящее решение!
SVD
1
@LalKrishna Создайте новый файл с именем UITextViewWorkaround.swift и добавьте в него приведенный выше код. Затем добавьте UITextViewWorkaround.executeWorkaround () в didFinishLaunchingWithOptions перед оператором возврата.
ашишн
22

Более быстрое решение:

///Substitute class for _UITextLayoutView bug
class FixedTextView: UITextView {
    required init?(coder: NSCoder) {
        if #available(iOS 13.2, *) {
            super.init(coder: coder)
        }
        else {
            let rect = CGRect(origin: .zero, size: CGSize(width: 100, height: 44*3))
            super.init(frame: rect, textContainer: nil)
        }
    }
}

Добавьте этот код куда-нибудь, а затем замените все экземпляры раскадровки на FixedTextView .

Примечание: вы потеряете все атрибуты, созданные в раскадровке. Это может иметь серьезные последствия (например, настройка делегата, размер и т. Д.)

garafajon
источник
Похоже, это хороший шаг к
обходному
18

Обновленное решение: обновление до Xcode 11.2.1 . Он работает на iOS 11, 12 или 13 устройств для меня.

Обратитесь к документации Apple Это обновление устраняет критическую проблему, которая может привести к сбою приложений, использующих UITextView.

Старое решение: скачанный Xcode 11.1 с https://developer.apple.com/download/more/ Переключение с 11.2 на 11.1 исправило сбой.

Кроме того, для меня даже с Xcode 11.2, когда я обновил свой iPhone до 13.2, это исправило сбой.

anoo_radha
источник
2
Это самое простое решение - обновить iPhone iOS до 13.2
Reefwing
6
Обновление iOS явно не является исправлением, учитывая, что OP говорит с точки зрения разработчика.
keeshux
2
Apple подтвердила, что ошибка возникает с версиями iOS до 13.2 и Xcode 11.2.
Чак Круцингер
Понижение версии XCode до версии 11.1 (11A1027) - по-прежнему происходит тот же сбой (
rommex
если вы обновляете или понижаете версию, и она по-прежнему вылетает из папки сборки Xcode (CMD + Shift + K) согласно комментарию Войтека ниже, который исправил это для меня при обновлении
Майк Волмар,
17

11.2.1 GM seed решает эту проблему

(и его можно использовать для публикации в App Store)

Перейдите на https://developer.apple.com/download/ . Скачать Xcode 11.2.1 GM seed

Примечания к выпуску подтверждают, что это исправляет эту ошибку:

введите описание изображения здесь

ремесло
источник
5
Обратите внимание, что после установки Xcode 11.2.1 GM seed вам, вероятно, следует удалить приложение с устройства разработки и / или очистить папку сборки Xcode (CMD + Shift + K).
Войтек Дмышевич
13

Вы можете скачать последнюю бета-версию Xcode (11.2.1 GM) с сайта разработчика Apple.

Здесь прямая ссылка

Xcode 11.2.1 GM seed

BossOz
источник
Обратите внимание, что после установки Xcode 11.2.1 GM seed вам, вероятно, следует удалить приложение с устройства разработки и / или очистить папку сборки Xcode (CMD + Shift + K).
Войтек Дмышевич
установлен и запущен без какой-либо другой процедуры. Проблема исправлена ​​✌️
BossOz
как мне установить это? Это дало мне папку, но нет исполняемого файла
Scobee
1
просто скачайте zip по предоставленной ссылке и распакуйте его. Затем скопируйте приложение в папку приложения.
BossOz
1
проблема в том, что при извлечении я получаю два файла: контент и метаданные ... вот почему я спросил, что с ними делать. Я использовал архивную утилиту, потому что щелкать по ней обычно не удавалось. Я попробую еще раз
Скоби
12

Улучшение @garafajon ответа. Для меня это работает в большинстве случаев.

///Substitute class for _UITextLayoutView bug
class FixedTextView: UITextView {
    required init?(coder: NSCoder) {
        if #available(iOS 13.2, *) {
            super.init(coder: coder)
        }
        else {
            super.init(frame: .zero, textContainer: nil)
            self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            self.contentMode = .scaleToFill

            self.isScrollEnabled = false   // causes expanding height

            // Auto Layout
            self.translatesAutoresizingMaskIntoConstraints = false
            self.font = UIFont(name: "HelveticaNeue", size: 18)
        }
    }
}
Awsom3D
источник
1
Работает отлично. Код @ garafajon вызвал проблемы с ящиками в неожиданных местах. Это решает эти проблемы ~ отличная работа!
экрензин
8

В качестве «быстрого» исправления вы можете добавить UITextViewнепосредственно из кода, а не через IB. По крайней мере, у меня это сработало. Хотя с моей точки зрения лучше откатиться на предыдущий Xcode / дождаться нового.

Павел Степанов
источник
6

Это ошибка в Xcode 11.2. Подклассифицированные текстовые представления не работают на всех устройствах, на которых не установлена ​​новая сборка iOS (13.2). Вы, вероятно, лучше не создавать релиз с этой сборкой.

Ты можешь сейчас:

  • понизить Xcode до 11.1 или
  • обновить устройство до iOS 13.2
mark.so.cgn
источник
1
Так влияет ли эта ошибка только на текстовые представления с подклассами?
Даррен
1
Обновление iOS при обновлении Xcode решает проблему.
Buyin Брайан
2
Вопрос в том, произойдет ли сбой в выпущенном приложении с каждой iOS меньше 13,2 ... Я боюсь попробовать ...
mark.so.cgn
6

Я использовал успешный обходной путь, но это было больно. Это процесс, которому я следовал:

  1. Откройте XIB в текстовом редакторе
  2. Найдите обидчика TextView. В моем случае:
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="782-j1-88c" customClass="LCAnsiConsoleTextView">
  <rect key="frame" x="16" y="20" width="343" height="589"/>
  <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
  <fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="12"/>
  <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
  1. Обратите внимание на его id(в моем случае:id="782-j1-88c" )
  2. Переопределите класс, как указано в ответах выше, и заново создайте параметры (у меня Objective-C, извините):
@implementation FixedTextView

- (id) initWithCoder:(NSCoder*)coder
{
    if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){13,2,0}])
        self = [super initWithCoder:coder];
    else {
        self = [super initWithFrame:CGRectMake(16, 3, 343, 605)];
        self.editable = YES;
        self.selectable = YES;
        self.insetsLayoutMarginsFromSafeArea = YES;
        self.clipsToBounds = YES;
        self.clearsContextBeforeDrawing = YES;
        self.autoresizesSubviews = YES;
        self.contentMode = UIViewContentModeScaleToFill;
        self.scrollEnabled = YES;
        self.userInteractionEnabled = YES;
        self.multipleTouchEnabled = YES;
        self.translatesAutoresizingMaskIntoConstraints = NO;
        self.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0];
    }
    return self;
}
  1. Обратите внимание на ограничения, которые включают в себя ваш идентификатор текстового представления, и воссоздайте эти ограничения для других идентификаторов элементов в вашем представлении или контроллере представления. В моем случае:
- (id) initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self xibSetup];
        [self initView];
/*
        <constraint firstItem="75C-lt-YtE" firstAttribute="top" secondItem="782-j1-88c" secondAttribute="bottom" constant="8" symbolic="YES" id="8SH-5l-FAs"/>
        <constraint firstItem="782-j1-88c" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leadingMargin" id="Mve-aZ-HCe"/>
        <constraint firstItem="782-j1-88c" firstAttribute="leading" secondItem="75C-lt-YtE" secondAttribute="leading" id="dPG-u3-cCi"/>
        <constraint firstItem="782-j1-88c" firstAttribute="trailing" secondItem="iN0-l3-epB" secondAttribute="trailingMargin" id="sjT-0Q-hNj"/>
        <constraint firstItem="782-j1-88c" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" id="vic-vZ-osR"/>
*/
        [self.command.topAnchor constraintEqualToAnchor:self.console.bottomAnchor constant:8].active = YES;
        [self.console.leadingAnchor constraintEqualToAnchor:self.layoutMarginsGuide.leadingAnchor].active = YES;
        [self.console.leadingAnchor constraintEqualToAnchor:self.command.leadingAnchor].active = YES;
        [self.console.trailingAnchor constraintEqualToAnchor:self.trailingAnchor].active = YES;
        [self.console.topAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor].active = YES;

    }
    return self;
}

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

Эрик Ланге
источник
2

У меня была та же проблема, я только что обновил свой Xcode 11.2 до 11.2.1, он работал нормально.

После обновления я протестировал то же самое на iOs 13 и iOS 12, и все работало нормально.

Мохаммад Парвез
источник
Дубликат ответа от BossOz.
Cœur
0

1. Проблема:

Существует проблема с Xcode 11.2, в которой раскадровки, содержащие UITextView, приводят к сбою приложения в версиях ОС, предшествующих iOS 13.2, если они скомпилированы с Xcode 11.2.

Xcode 11.2

Проверьте эту яблочную документацию .

2. Решение:

Единственное решение - обновить ваш Xcode до 11.2.1 или 11.3.

Xcode 11.2.1 был специально выпущен, чтобы исправить эту проблему.

введите описание изображения здесь Проверьте эту яблочную документацию.

3. Предложение:

Я бы посоветовал вам перейти на последнюю версию Xcode 11.3, поскольку она поддерживает разработку приложений для iOS 13.3, а также есть много новых функций. Проверьте эту яблочную документацию .

Джайпракаш Дубей
источник
-1

Эта проблема была исправлена ​​в версии XCode 11.2.1 и вызвана в примечаниях к выпуску:

Это обновление устраняет критическую проблему, которая может привести к сбою приложений, использующих UITextView.

Скриншот заметок о выпуске XCode

pkamb
источник