web-dev-qa-db-fra.com

Après la mise à niveau vers Xcode 11.2 à partir de Xcode 11.1, l'application se bloque en raison de _UITextLayoutView

Après la mise à niveau vers Xcode 11.2 à partir de Xcode 11.1, mon application se bloque:

*** Arrêt de l'application en raison d'une exception non interceptée 'NSInvalidUnarchiveOperationException', raison: 'Impossible d'instancier la classe nommée _UITextLayoutView car aucune classe nommée _UITextLayoutView n'a été trouvée; la classe doit être définie dans le code source ou liée à partir d'une bibliothèque (assurez-vous que la classe fait partie de la bonne cible) '

Pourquoi cela arrive-t-il? Comment puis-je éviter ce plantage?

350

Félicitations

La nouvelle version de Xcode (11.2.1) est disponible maintenant, ce qui est le meilleur moyen de se débarrasser de ce problème.

Solutions de contournement

@Mojtaba Hosseini la solution que j'ai proposée était de l'aide et de la participation de mon côté à mes collègues développeurs via StackOverflow. Vous, moi et tout le reste du développeur ici savons déjà que lorsque la nouvelle version sera annoncée par Apple, ce problème aura disparu.

Mais à côté de tout

La solution susmentionnée a été définitivement acceptée par Apple Review car il n'y a aucune API privée impliquée du tout. Cette approche est très similaire à la propriété de création comme

@interface UITextView (Layout)

Ou

UITextView + Layout.h

Ainsi, lorsque vous créez une propriété, vous utilisez directement Apple Composants privés et les remodulez selon vos besoins ou vos besoins.

L'exemple simple est les classes AMFNetworking

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

J'espère que j'en ai fini avec l'allégation

La réponse ci-dessous était juste une aide de mon côté pour permettre au développeur de continuer à développer comme vous, nous avons initialement proposé au développeur de restaurer Xcode. Ce fut une mauvaise pratique de télécharger à nouveau 8 Go de Xcode car nous savons tous que la nouvelle version de Xcode sera bientôt disponible.

Bien qu'il soit corrigé dans Xcode 11.2.1, j'ai une solution pour Xcode 11.2 par laquelle vous pouvez vous débarrasser de ce plantage:

*** Arrêt de l'application en raison d'une exception non interceptée 'NSInvalidUnarchiveOperationException', raison: 'Impossible d'instancier la classe nommée _UITextLayoutView car aucune classe nommée _UITextLayoutView n'a été trouvée; la classe doit être définie dans le code source ou liée à partir d'une bibliothèque (assurez-vous que la classe fait partie de la bonne cible) '

SOLUTION

Accédez à la recherche de paramètres de construction pour "DEAD_CODE_STRIPPING" et définissez-le sur NO.

DEAD_CODE_STRIPPING = NO

Alors

créer des fichiers UITextViewWorkaround

ITextViewWorkaround.h

    #import <Foundation/Foundation.h>


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

ITextViewWorkaround.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

l'exécuter dans le délégué de l'application

#import "UITextViewWorkaround.h"

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

            [UITextViewWorkaround executeWorkaround];
    return yes;
    }

Compilez le code et vous aurez une application en cours d'exécution :)

145

Mise à jour: corrigé! ????????

La SEULE solution consiste à mettre à jour

Ce bug est corrigé dans Xcode 11.2.1. Vous pouvez donc télécharger et utiliser à partir d'ici.

Les storyboards contenant un UITextView ne provoqueront plus le blocage de l'application sur les versions du système d'exploitation antérieures à iOS 13.2, tvOS 13.2 ou macOS 10.15.2. (56808566, 56873523)


Xcode 11.2 est déconseillé par Apple le 5 novembre 2019

si vous essayez de soumettre votre application qui construit avec Xcode 11.2 à l'AppStore, vous serez rejeté:

Avertissement de fonctionnement de l'App Store Connect

AVERTISSEMENT ITMS-90703 : "Build Xcode obsolète. En raison de problèmes d'archives d'application résolus, nous avons abandonné Xcode 11.2 le 5 novembre 2019. Téléchargez Xcode 11.2. 1 ou plus récent, reconstruisez votre application et soumettez-la de nouveau. "

Ainsi, toutes les solutions de contournement effectuées avec le Xcode 11.2 sont inutiles


C'est un bogue pour Xcode 11.2, et corrigé dans Xcode 11.2.1.

Solutions)

Revenez à la version précédente de Xcode - release à partir de: La restauration n'est plus une option et AppStore rejettera toute construction avec Xcode en dessous de 11.2.1 jetez un œil à cela

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

Notez que vous devez utiliser Safari pour le télécharger et vous devez d'abord connectez-vous à Apple portail développeur .

Vous pouvez trouver toutes les autres versions de Xcode et d'autres liens de ressources (y compris les versions et versions bêta) ici à https://developer.Apple.com/download/more

La solution

C'est une solution de contournement très difficile mais qui fonctionne. Remplacer tous les UITextViews dans le storyboard s et Xib s avec la version code pur .


Notez que ce n bug est trouvé et corrigé par Apple

Fixed

Plus tôt également, le bug a été confirmé par Apple Staff edford

Confirmation


Pour ceux avec iOS 13.2 et ne pouvant plus utiliser Xcode 11.1:

  1. Mettre à jour macOS vers 10.15.1 ou version ultérieure
  2. Installez Xcode 11.2.1 ou une version ultérieure
  3. Cela devrait fonctionner maintenant sur l'appareil mis à jour.

Pour ceux qui ont un storyboard:

  1. Sous-classe UITextView
  2. Assignez-le à tous les objets UITextView
  3. N'oubliez pas de mettre à jour les modifications de propriété susceptibles de perdre dans le sous-classement.

Pour ceux à l'aise avec la méthode swizzling (Objc et comportement dynamique)

Dirigez-vous vers @ aftab muhammed khanréponse pour Objective-C et @ MikRoréponse pour Swift version adaptée

Ne le faites plus:

Même si ces deux dernières solutions de contournement n'utilisent pas l'API privée d'Apple , elles seront rejetées dans l'AppStore car Apple n'acceptera pas les builds avec les versions Xcode sous 11.2.1 !

Et encore une fois:

Xcode 11.2 est déconseillé par Apple le 5 novembre 2019

221
Mojtaba Hosseini

Le problème a été résolu dans Xcode 11.2.1.

EDIT: Comme le correctif est maintenant publié, vous devez passer à cette version Xcode et commenter cette solution de contournement. Comme l'a mentionné Mojtaba Hosseini dans sa réponse:

... ces deux dernières solutions de contournement utilisent Apple API privée et seront rejetées par Apple review!!

Pour le temps jusqu'à ce que le correctif soit publié par Apple, c'était une bonne solution de contournement pour continuer à développer et à tester.


Pour Xcode 11.2, basé sur l'idée d'Aftab Muhammed Khan et avec l'aide de John Nimis, je viens de tester le code suivant.

Aucun changement dans les fichiers du storyboard nécessaire!

Modifié mon fichier AppDelegate.Swift et ajouté cette classe

//******************************************************************
// 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
           }
        }
    }
}

et dans l'appel délégué pour "didFinishLaunchingWithOptions" appeler la solution de contournement

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()
}
40
Hardy_Germany

J'ai adapté la solution Obj-C de khan à 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!)
            }
        }
    }

}

Appelez-le à la fin de didFinishLaunchingWithOptions dans AppDelegate.

Merci @Aftab!

34
MikRo

Une solution plus rapide:

///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)
        }
    }
}

Ajoutez ce code quelque part, puis remplacez toutes les instances de storyboard par FixedTextView.

Remarque: vous perdrez tous les attributs créés dans les storyboards. Cela pourrait avoir de graves conséquences (par exemple, la configuration, la taille, etc.) des délégués.

22
garafajon

Solution mise à jour: Mise à jour vers Xcode 11.2.1. Cela fonctionne sur les appareils iOS 11, 12 ou 13 pour moi.

Reportez-vous à documentation d'Apple Cette mise à jour corrige un problème critique qui pouvait entraîner le blocage des applications utilisant UITextView.

Ancienne solution: Xcode 11.1 téléchargé depuis https://developer.Apple.com/download/more/ Le retour de 11.2 à 11.1 a corrigé le crash.

De plus, pour moi, même avec Xcode 11.2, lorsque j'ai mis à niveau mon iPhone vers 13.2, cela a corrigé le plantage.

18
anoo_radha

11.2.1 GM seed résout ce problème

(et il peut être utilisé pour publier sur l'App Store)

Accédez à https://developer.Apple.com/download/ . Télécharger Xcode 11.2.1 GM seed

Notes de version confirmez qu'il corrige cette erreur:

enter image description here

17
craft

Vous pouvez aller télécharger la dernière version bêta de Xcode (11.2.1 GM) sur le site Web du développeur Apple Apple.

Ici le lien direct

Xcode 11.2.1 GM seed

13
BossOz

Amélioration de la réponse @garafajon. Pour moi, cela fonctionne dans la plupart des cas.

///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)
        }
    }
}
12
Awsom3D

Comme solution "rapide", vous pouvez ajouter le UITextView directement à partir du code et non via IB. Au moins, cela a fonctionné pour moi. Bien que de mon point de vue, il est préférable de revenir au Xcode précédent/d'attendre le nouveau.

8
Pavel Stepanov

C'est un bug avec Xcode 11.2. Les vues de texte sous-classées se bloquent sur tous les appareils sur lesquels la nouvelle version iOS (13.2) n'est pas installée. Vous feriez probablement mieux de ne pas créer de version avec cette version.

Tu peux maintenant:

  • rétrograder Xcode vers 11.1 ou
  • mettre à niveau votre appareil vers iOS 13.2
6
mark.so.cgn

J'ai utilisé une solution de contournement réussie, mais c'était douloureux. Voici le processus que j'ai suivi:

  1. Ouvrez le XIB dans un éditeur de texte
  2. Recherchez le TextView incriminé. Dans mon cas:
<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. Notez son id (dans mon cas: id="782-j1-88c")
  2. Remplacez la classe comme indiqué dans les réponses ci-dessus et recréez les options (la mienne est Objective-C, désolé):
@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. Notez les contraintes qui incluent votre identifiant de vue de texte et recréez ces contraintes par rapport aux autres identifiants d'élément dans votre vue ou votre contrôleur de vue. Dans mon cas:
- (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;
}

Cela a résolu le problème pour moi sans perte de fonctionnalité souhaitée. Heureusement, je n'avais qu'un UITextView à remplacer. Sinon, cela devient intenable.

6
Eric Lange

J'ai eu le même problème que je viens de mettre à niveau mon Xcode 11.2 vers 11.2.1, cela a bien fonctionné.

Après la mise à niveau, j'ai testé le même sur iOs 13 et iOS 12 et cela fonctionnait bien.

2
Mohammad Parvez

1. Problème:

Il y a un problème avec Xcode 11.2 dans lequel les storyboards contenant un UITextView entraîneront le blocage de l'application sur les versions de système d'exploitation antérieures à iOS 13.2 si elles sont compilées avec Xcode 11.2.

Xcode 11.2

Vérifiez cela documentation Apple .

2. Solution:

La seule solution est de mettre à jour votre Xcode en 11.2.1 ou 11.3.

Xcode 11.2.1 a été particulièrement publié pour résoudre ce problème de plantage.

enter image description here Vérifiez ceci documentation Apple.

3. Suggestion:

Je vous suggère d'utiliser la dernière version de Xcode 11.3 car cela prend en charge le développement d'applications pour iOS 13.3 et il existe également de nombreuses nouvelles fonctionnalités. Vérifiez cela documentation Apple .

0
Jayprakash Dubey