ObjecTips

Swift & Objective-C で iOS とか macOS とか

Xcode 11.2 + Storyboard UITextView でクラッシュ

Xcode 11.2 で Storyboard か xib で UITextView を使っていると iOS 13.2 より前のバージョンでクラッシュするという凶悪なバグが発生している。
実際にクラッシュを起こしてみると以下の様に _UITextLayoutView ってクラスは無いとエラーメッセージが表示された。

*** 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)'

Stack Overflow

stackoverflow.com

Apple Developer Forums

forums.developer.apple.com

これらの書き込みをまとめると

  • 影響範囲は現行最新版の iOS 13.2 より前の全てのバージョン
  • 発生条件は Storyboard か xib で UITextView を使っている事
  • 回避策1 UITextView を全てコードで生成する
  • 回避策2 Xcode 11.1 を使う

回避策については Apple の人も同様に言っている https://forums.developer.apple.com/thread/125287#391939

対策

UITextView の Storyboard 生成をコード生成に置き換えるかどうかはプロジェクト次第(コスト次第)だと思う。
もしソースの公開されていない外部ライブラリを使っている場合、中でどういう実装をしているのか分からないので Xcode 11.1 に戻した方が無難そう。
何らかの事情で Xcode 11.2 を使い続ける場合、配布ビルドのみ Xcode 11.1 で行うのもアリかと。


余談

Developer Forums に _UITextLayoutView を動的に追加すれば良いなんてコメントもあった。 https://forums.developer.apple.com/thread/125287#391979

なるほどと思い実際に試してみたところ以下の Objective-C 実装を application(_:didFinishLaunchingWithOptions:) のタイミングで実行する事で iOS 12 でもクラッシュを回避する事ができた。
がしかしコメントにもある様に、実際にこの実装でリリースするのは如何なものかいう感じなので次のバージョンの Xcode が出るまでの開発中の一時凌ぎとして使うならといったところ。興味が湧いて実装しただけなので参考までに。*1

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

@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

_UITextLayoutViewsuperClassUIView である事は以下の記事の方法で確認した。

koze.hatenablog.jp

以上

追記

iOS と tvOS については Xcode 11.2.1 GM で修正された。
https://developer.apple.com/documentation/xcode_release_notes/xcode_11_2_1_gm_seed_release_notes/

*1:この実装を掲載した後まるっと StackOverflow に転載されていてびっくり