2016-08-26 7 views
15

プロダクションで自動レイアウト制約のあいまいさをキャッチすることは可能ですか?UIViewAlertForUnsatisfiableConstraintsのブレークポイントに相当しますが、プロダクションアプリケーションの場合は同じですか?プロダクションのUIViewAlertForUnsatisfiableConstraintsをキャッチする

私の目標は、このようなエラーをログシステムに報告するグローバルハンドラを追加することです。

_UIViewAlertForUnsatisfiableConstraints(NSLayoutConstraint* unsatisfiableConstraint, NSArray<NSLayoutConstraint*>* allConstraints)

+0

これは良い質問です。私が理解しているように、シンボリックなブレークポイントでは、特定のシンボル、メソッド、セレクタを壊すことができます。私はグローバルなC関数 'UIViewAlertForUnsatisfiableConstraints()'を試してみて、それが 'UIView'のインスタンスかクラスメソッドかどうかを見てみましたが、これまで何も見つかりませんでした。 – JAL

答えて

5

実際シンボルUIViewAlertForUnsatisfiableConstraints関数です。

これはプライベートなので置き換えることはできません。

しかし、これはプライベートメソッド-[UIView engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:]から呼び出され、スイープすることができます。このメソッドは、およそこのコンテンツを持っている:私はthis articleから正しく理解していれば

void -[UIView engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:] { 
    if ([self _isUnsatisfiableConstraintsLoggingSuspended]) { 
    [self _recordConstraintBrokenWhileUnsatisfiableConstraintsLoggingSuspended:$arg4]; // add constraint to some pool 
    } 
    else { 
    if (__UIConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints) { 
     // print something in os_log 
    } 
    else { 
     _UIViewAlertForUnsatisfiableConstraints($arg4, $arg5); 
    } 
    } 
} 

__UIConstraintBasedLayoutVisualizeMutuallyExclusiveConstraintsはいつもあなたがする必要があるすべては_isUnsatisfiableConstraintsLoggingSuspendedと呼ばれるプライベートブールプロパティをチェックして、オリジナルのメソッドを呼び出すことで、iOSの上でNOを返します。

これは、結果コードの例です:

#import <objc/runtime.h> 

void SwizzleInstanceMethod(Class classToSwizzle, SEL origSEL, Class myClass, SEL newSEL) { 
    Method methodToSwizzle = class_getInstanceMethod(classToSwizzle, origSEL); 
    Method myMethod = class_getInstanceMethod(myClass, newSEL); 
    class_replaceMethod(classToSwizzle, newSEL, method_getImplementation(methodToSwizzle), method_getTypeEncoding(methodToSwizzle)); 
    class_replaceMethod(classToSwizzle, origSEL, method_getImplementation(myMethod), method_getTypeEncoding(myMethod)); 
} 

@interface InterceptUnsatisfiableConstraints : NSObject 
@end 

@implementation InterceptUnsatisfiableConstraints 

+ (void)load { 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    SEL willBreakConstantSel = NSSelectorFromString(@"engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:"); 
    SwizzleInstanceMethod([UIView class], willBreakConstantSel, [self class], @selector(pr_engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:)); 
    }); 
} 

- (void)pr_engine:(id)engine willBreakConstraint:(NSLayoutConstraint*)constraint dueToMutuallyExclusiveConstraints:(NSArray<NSLayoutConstraint*>*)layoutConstraints { 
    BOOL constrainsLoggingSuspended = [[self valueForKey:@"_isUnsatisfiableConstraintsLoggingSuspended"] boolValue]; 
    if (!constrainsLoggingSuspended) { 
    NSLog(@"_UIViewAlertForUnsatisfiableConstraints would be called on next line, log this event"); 
    } 
    [self pr_engine:engine willBreakConstraint:constraint dueToMutuallyExclusiveConstraints:layoutConstraints]; 
} 

@end 

それはiOSの8.2/9月10日に動作します(これはiOSの8.1で動作するので、気をつけていない)が、私はすべての保証を与えることはできません。 また、キーボード/ビデオプレーヤーなどのシステムコンポーネントの制約の問題を検出します。 このコードは脆弱です(システムバージョンの更新やパラメータの変更などでクラッシュする可能性があります)。プロダクションでは使用しないことをお勧めします(自動審査プロセスにも合格しないと思われます)。あなたは最後の言葉を持っていますが、あなたは警告を受けています。

しかし、私はあなたが生産の前にautolayoutのバグを修正するために内部/外部テスターのためのビルドでそれを使うことができると思います。

swiftを使用していることに気付きました。このコードをブリッジヘッダーファイルを使用して迅速なプロジェクトに追加できます。

+0

クール! '_UIViewAlertForUnsatisfiableConstraints'のメソッド宣言はどうやって見つかりましたか? – JAL

+0

@ JALリバースエンジニアリングを少し行い、テストプロジェクトのデバッグに少し時間を費やしました。 –

+0

リバースエンジニアリングされたUIKitの仕組みについて詳しく説明できますか?私はその内部についてもっと学びたいと思いますし、プライベートヘッダーのどれかでこのC関数を見ていませんでした。壊れた制約のあるアプリケーションを作成し、バイナリを逆アセンブルしましたか? – JAL

0

短い答えは、これはプライベートAPIであり、あなたは、少なくともではない関連の危険性を知らずに... ...生産コードでそれを

をいじりされるべきではない:

A)アップル意志アプリストアに送信された商品でこのようなSPIを上書きしようとすると、アプリを拒否します。それが何らかの理由でスリップすると、後日それを捕まえることになり、それは一般に悪化します。

)B)答えは、@Romanの回答のように、しばしば、あなたが今後さらに(または将来)作業しているものを不安定にする可能性があります。私はまだ誰かがこのような脆弱なことをしている第三者の図書館を利用するときに心配しています。

これらの警告が表示された状態で、プライベートメソッドをオーバーライドして、あなたのハートのコンテンツにスウィズルします。ただをくださいコードを出荷しないでください。

関連する問題