Після оновлення до Xcode 11.2 з Xcode 11.1 програма перестає працювати через _UITextLayoutView


351

Після оновлення до Xcode 11.2 з Xcode 11.1 мій додаток виходить з ладу:

*** Закінчення програми через невиконаний виняток "NSInvalidUnarchiveOperationException", причина: "Не вдалося інстанціювати клас з назвою _UITextLayoutView, оскільки не знайдено клас з іменем _UITextLayoutView; клас повинен бути визначений у вихідному коді або пов'язаний з бібліотеки (переконайтесь, що клас є частиною правильної цілі) '

Чому це відбувається? Як я можу запобігти цій аварії?


17
Схоже на помилку Xcode 11.2. Перевірте тему forums.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 (макет)

Або

UITextView + Layout.h

Отже, коли ви створюєте властивість, ви безпосередньо використовуєте приватні компоненти APPLE та перемодулюєте їх відповідно до ваших потреб чи вимог.

Простий приклад - класи 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" і встановіть його на "НІ"

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
Якщо ви працюєте на вас, будь ласка, виправте їх, тому інші можуть спробувати це рішення також
aftab Muhammed khan

3
@Hardy_Germany Я тестував це трохи, для Swift ви можете спробувати: class UITextViewWorkaround: NSObject {class func ExecuteWorkaround () {if #available (iOS 13.2, *) {} else {let className = "_UITextLayoutView" var cls = objcNameCame ) якщо 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 так поза курсом, чому б нам ніколи нічого не змінити в АПЛІЙНИХ КЛАСАХ.
хан

5
Випускається лише Xcode 11.2.1 GM GM (beta). Стабільна версія може вийти незабаром.
Лал Кришна

221

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

ТОЛЬКО Рішення - оновити

Ця помилка є фіксованою в Xcode 11.2.1. Тож ви можете завантажити та використовувати його звідси.

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


Apple Xbox 11.2 застаріла 5 листопада 2019 року

якщо ви коли-небудь спробуєте надіслати додаток, яке будується з Xcode 11.2, AppStore, вам буде відхилено:

Попередження про експлуатацію підключення магазину додатків

ПОПЕРЕДЖЕННЯ ITMS-90703 : "Невизначений збір Xcode. Через вирішені проблеми з архівом додатків, 5 листопада 2019 року ми застаріли Xcode 11.2. Завантажте Xcode 11.2.1 або новішу версію, відновіть додаток та повторно надішліть його."

Таким чином, всі обхідні шляхи, зроблені з Xcode 11.2, марні


Це помилка для Xcode 11.2 та виправлена ​​в Xcode 11.2.1.

Рішення (и)

Відкат до попередньої версії випуску 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 Staff Edford

Підтвердження


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

  1. Оновіть macOS до 10.15.1 або новішої версії
  2. Встановіть Xcode 11.2.1 або пізнішої версії
  3. Зараз слід працювати на оновленому пристрої.

Для тих, хто має раскадровку:

  1. Підклас UITextView
  2. Призначте його всім UITextViewоб’єктам
  3. Не забудьте оновити будь-які зміни властивостей, які можуть втратити підкласи.

Для тих, хто комфортний із завитками методів (Objc та динамічна поведінка)

Перейдіть до відповіді мухаммед-хана @aftab для Objective-C та відповіді @MikRo для адаптованої версії Swift

Тільки не робіть цього більше:

Навіть якщо в цих двох останніх химерних обхідних шляхах не використовується приватний API Apple , вони будуть відхилені в AppStore, оскільки Apple не прийме збірок із версіями Xcode згідно з 11.2.1 !

І ще раз:

Apple Xbox 11.2 застаріла 5 листопада 2019 року


3
Сумно, але рішення працює для мене. Дякую! 11.1 робіт. Я б не пропонував переходити до чистого коду, тому що я думаю, що незабаром з'явиться виправлення. Якщо ви не заперечуєте: оновіть цю відповідь, коли з’явиться нова версія, яка працює. Було б погано, якщо люди почнуть завантажувати подію 11.1, хоча там є виправлена ​​версія :)
Sebastian Weiß

2
У мене вже є 11.1, але не працювало, я не оновив до 11.2.
JAHelia

6
Зауважте, що ви, ймовірно, повинні видалити додаток зі свого пристрою розробки та / або очистити папку збірки Xcode ( CMD + Shift + K)
JeroenJK

3
Як я можу перейти на v11.2.1? Це не відображається в магазині додатків. А завантажуючи насіння GM з порталу розробників, намагаємось завантажувати додаток приблизно за 8 Гб!
mesqueeb

3
Крім того, якщо це застаріле, чому зараз Apple просто не видаляє 11.2 в магазині додатків?
Малькольм Сальвадор

40

Виправлення виправлено в Xcode 11.2.1.

EDIT: Оскільки виправлення зараз випущено, вам слід перейти до цієї версії 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()
}

34

Я адаптував рішення Obj-C хана до Свіфта :

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!


куди нам потрібно додати цей код? У делегатних файлах?
SIDHARTH PU

@SIDHARTHPU ви можете зателефонувати в ньогоdidFinishLaunchingWithOptions
Лал Кришна

спробував різноманітні виправлення з цього питання, і цей зробив трюк до Xcode 11.3 ?! Дякую!
FlimFlam Vir

1
Це найкоротше і блискуче рішення!
sVd

1
@LalKrishna Створіть новий файл під назвою UITextViewWorkaround.swift та додайте до нього вище код. Потім додайте UITextViewWorkaround.executeWorkaround () це до didFinishLaunchingWithOptions перед оператором return.
ашишн

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.

Примітка: ви втратите будь-які атрибути, створені на дошках. Це може мати серйозні наслідки (наприклад, налаштування делегата, розмір тощо)


Це , здається, хороший крок в напрямку вирішення проблеми, але не зовсім рішення ще ...
Fattie

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, це виправило збій.


2
Це найпростіший виправлення - оновити iPhone iOS до 13.2
Reefwing

6
Оновлення iOS явно не є виправданням, враховуючи, що ОП розмовляє з точки зору розробника.
keeshux

2
Apple підтвердила, що помилка виникає у версіях iOS до 13.2 та Xcode 11.2.
Чак Крутсінгер

Зменшений XCode до версії 11.1 (11A1027) - все одно мати такий самий збій (
rommex

якщо ви оновите або поновите програму, і вона все ще вибиває чисту папку збірки Xcode (CMD + Shift + K) за коментарем Wojteck нижче, який зафіксував це для мене під час оновлення
Майк Вольмар

17

11.2.1 ГМ-насіння вирішує це питання

(і його можна використовувати для публікації в App Store)

Перейдіть на сторінку https://developer.apple.com/download/ . Завантажте насіння Xcode 11.2.1 GM

Примітки до випуску підтверджують, що вона виправляє цю помилку:

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


5
Зауважте, що після встановлення насіння Xcode 11.2.1 GM ви, ймовірно, повинні видалити додаток із свого пристрою розробки та / або очистити папку збірки Xcode (CMD + Shift + K).
Войтек Дмишевич

13

Ви можете перейти до завантаження останньої версії бета-версії Xcode (11.2.1 GM) з веб-сайту розробника Apple.

Тут пряме посилання

Xcode 11.2.1 GM насіння


Зауважте, що після встановлення насіння Xcode 11.2.1 GM ви, ймовірно, повинні видалити додаток із свого пристрою розробки та / або очистити папку збірки Xcode (CMD + Shift + K).
Войтек Дмишевич

встановлюється та працює без будь-якої іншої процедури. Виправлена ​​проблема ✌️
BossOz

як це встановити? Він дав мені папку, але не здійсненний
Скоби

1
просто завантажте поштовий індекс за наданим посиланням та дістаньте його. Потім скопіюйте додаток у папку програми.
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)
        }
    }
}

1
Працює чудово. @ код garafajon спричинив проблеми з коробками в несподіваних місцях. Це вирішує ці проблеми ~ чудова робота!
екрензін

8

Для швидкого виправлення ви можете додати UITextViewбезпосередньо з коду, а не через ІБ. Принаймні, це працювало на мене. Хоча з моєї точки зору, краще відкатати попередній Xcode / дочекатися нового.


6

Це помилка з Xcode 11.2. Підкласові текстові огляди завершуються на всіх пристроях, на яких не встановлено нову збірку iOS (13.2). Вам, мабуть, краще не створювати реліз із цією збіркою.

Тепер ви можете:

  • понизити Xcode до 11.1 або
  • оновіть свій пристрій до iOS 13.2

1
Так чи впливає ця помилка лише на перегляди тексту підкласових текстів?
Даррен

1
Оновлення iOS під час оновлення Xcode вирішує проблему.
Буїн Брайан

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.