After upgrading to Xcode 11.2 from Xcode 11.1, app

2020-01-24 10:11发布

After upgrading to Xcode 11.2 from Xcode 11.1 my app crashes:

*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named _UITextLayoutView because no class named _UITextLayoutView was found; the class needs to be defined in source code or linked in from a library (ensure the class is part of the correct target)'

Why is this happening? How can I prevent this crash?

15条回答
闹够了就滚
2楼-- · 2020-01-24 10:52

The issue was fixed in Xcode 11.2.1.

EDIT: As the fix is now released, you should switch to that Xcode version and comment out this workaround. As Mojtaba Hosseini in his answer mentioned:

... these last two swizzling workarounds are using Apple private API and will be reject from Apple review!

For the time until the fix was released by Apple, this was a good workaround to continue developing and testing.


For Xcode 11.2, based on the idea of Aftab Muhammed Khan and with the help of John Nimis I just tested the following code.

No change in the storyboard files necessary!

Edited my AppDelegate.swift file and added this class

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

and within the delegate call for "didFinishLaunchingWithOptions" call the workaround

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()
}
查看更多
我想做一个坏孩纸
3楼-- · 2020-01-24 10:52

1. Problem:

There is an issue with Xcode 11.2 wherein Storyboards containing a UITextView will cause the app to crash on OS versions earlier than iOS 13.2 if compiled with Xcode 11.2.

Xcode 11.2

Check this apple documentation.

2. Solution:

The only solution is to update your Xcode to 11.2.1 or 11.3.

Xcode 11.2.1 was particularly released to fix this crash issue.

enter image description here Check this apple documentation.

3. Suggestion:

I would suggest you to go with latest version of Xcode 11.3 since this supports developing apps for iOS 13.3 and also there are many new features. Check this apple documentation.

查看更多
我想做一个坏孩纸
4楼-- · 2020-01-24 10:53

I used a successful workaround, but it was painful. This is the process that I followed:

  1. Open the XIB in a text editor
  2. Find the offending TextView. In my case:
<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. Note its id (in my case: id="782-j1-88c")
  2. Override the class as noted in the answers above and recreate the options (mine is Objective-C, sorry):
@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. Note the constraints that include your text view id, and recreate those constraints against the other element ids in your view or view controller. In my case:
- (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;
}

Doing this fixed the issue for me with no loss in desired functionality. Fortunately I had only one UITextView to replace. Otherwise, this gets untenable.

查看更多
成全新的幸福
5楼-- · 2020-01-24 10:55

A quicker fix:

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

Add this code somewhere and then replace all storyboard instances to FixedTextView.

Note: you will lose any attributes created in the storyboards. This could have serious implications (e.g. delegate setting, size, etc.)

查看更多
▲ chillily
6楼-- · 2020-01-24 10:56

Updated Solution: Update to Xcode 11.2.1. It works on iOS 11, 12 or 13 devices for me.

Refer to apple's documentation This update fixes a critical issue that could cause apps using UITextView to crash.

Old Solution: Downloaded Xcode 11.1 from https://developer.apple.com/download/more/ Switching back from 11.2 to 11.1 fixed the crash.

Also, for me even with Xcode 11.2, when I upgraded my iPhone to 13.2, that fixed the crash.

查看更多
不美不萌又怎样
7楼-- · 2020-01-24 10:59

This issue was fixed in Xcode version 11.2.1, and called out in the release notes:

This update fixes a critical issue that could cause apps using UITextView to crash

Xcode release notes screenshot

查看更多
登录 后发表回答