LoginSignup
46
27

More than 5 years have passed since last update.

ビルドで待たないための、Simulator 上で実行中の view をいじる方法

Last updated at Posted at 2016-12-28

Simulator ですでに動作している iOS アプリの view をちょっといじりたい時に便利な手段を紹介します。

手順

アプリを一時停止する

ます、メニューの Debug > Pause か、デバッグバーの Pause ボタンでアプリケーションを一時停止させます。

Debug < Pause ^⌘Y

Pause ボタンは、デバッグバーの左から3番目のボタンです

UIApplication が見えるスタックへ移動する

画面操作慣れしている方向け

Debug Navigator の Process View Display から、Thread 1 の main をクリックします。

スクリーンショット 2016-12-28 14.59.13.png

LLDBer 向け

main thread を選択

(lldb) thread list
Process 16234 stopped
* thread #1: tid = 0x5345c, 0x000000010b1b4f72 libsystem_kernel.dylib`mach_msg_trap + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
  thread #4: tid = 0x53536, 0x000000010b1bbefa libsystem_kernel.dylib`kevent_qos + 10, queue = 'com.apple.libdispatch-manager'
  thread #6: tid = 0x53538, 0x000000010b1b4f72 libsystem_kernel.dylib`mach_msg_trap + 10, name = 'com.apple.uikit.eventfetch-thread'

(lldb) thread select 1

main 関数の frame を選択

(lldb) thread backtrace
* thread #1: tid = 0x5345c, 0x000000010b1b4f72 libsystem_kernel.dylib`mach_msg_trap + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x000000010b1b4f72 libsystem_kernel.dylib`mach_msg_trap + 10
    frame #1: 0x000000010b1b445e libsystem_kernel.dylib`mach_msg + 226
    frame #2: 0x0000000109e69ba4 CoreFoundation`__CFRunLoopServiceMachPort + 212
    frame #3: 0x0000000109e69021 CoreFoundation`__CFRunLoopRun + 1345
    frame #4: 0x0000000109e68884 CoreFoundation`CFRunLoopRunSpecific + 420
    frame #5: 0x000000010be19a6f GraphicsServices`GSEventRunModal + 161
    frame #6: 0x00000001076c1c68 UIKit`UIApplicationMain + 159
  * frame #7: 0x0000000106bf614f TableViewTraining`main + 111 at AppDelegate.swift:12
    frame #8: 0x000000010ae8f68d libdyld.dylib`start + 1
    frame #9: 0x000000010ae8f68d libdyld.dylib`start + 1

(lldb) frame select 7
frame #7: 0x0000000106bf614f TableViewTraining`main + 111 at AppDelegate.swift:12
   9    import UIKit
   10   
   11   @UIApplicationMain
-> 12   class AppDelegate: UIResponder, UIApplicationDelegate {
   13   
   14       var window: UIWindow?
   15 

View の一覧を確認する

Console から LLDB を実行する

デバッグコンソールから、Xcode に組み込まれているデバッガ LLDB を実行します。

dwx-dt-debugarea-1_2x.png

LLDB を使うと、コマンドラインから様々なデバッグ操作ができます。試しに help と入力すると、次のようにヘルプが表示されます:

(lldb) help
Debugger commands:

  apropos           -- List debugger commands related to a word or subject.
  breakpoint        -- Commands for operating on breakpoints (see 'help b' for
  ...

ここからは、LLDB の expression コマンドを使って、View の一覧を確認していきます。なお、-O も一緒に指定しますが、これは人間の読みやすい形式で表示するオプションです1

UIApplication は、アプリが起動している間存在するシングルトンなクラスです。このクラスのインスタンスから、現在表示されている View までたどることができます:

(lldb) expression -O -- UIApplication.shared
<UIApplication: 0x7f9772d00d40>

UIApplication は、現在有効な UIWindowUIApplication#keyWIndow に持っています:

(lldb) expression -O -- UIApplication.shared.keyWindow!
<UIWindow: 0x7f977660c400; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x6000000556c0>; layer = <UIWindowLayer: 0x6000002210e0>>

この UIWindow は、UIWindow#rootViewControllerViewController を持っています:

(lldb) expression -O -- UIApplication.shared.keyWindow!.rootViewController!
<UINavigationController: 0x7f9774031800>

この UIViewController#view から、UIView を入手できます:

(lldb) expression -O -- UIApplication.shared.keyWindow!.rootViewController!.view!
<UILayoutContainerView: 0x7f9772d09a30; frame = (0 0; 414 736); autoresize = W+H; gestureRecognizers = <NSArray: 0x600000056c80>; layer = <CALayer: 0x618000221060>>

さらに、この UIView の子孫 View を追いかけてみましょう。UIView は、recursiveDescription というデバッグ用のメソッドを備えています。ただ、Swift からは直接呼び出せないので、UIView の親クラスであるNSObject#value(forKey:) 経由で呼び出す必要があります:

(lldb) expression -O -- UIApplication.shared.keyWindow!.rootViewController!.view!.value(forKey: "recursiveDescription")!
<UILayoutContainerView: 0x7f9772d09a30; frame = (0 0; 414 736); autoresize = W+H; gestureRecognizers = <NSArray: 0x600000056c80>; layer = <CALayer: 0x618000221060>>
   | <UINavigationTransitionView: 0x7f9776607490; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x600000221b40>>
   |    | <UIViewControllerWrapperView: 0x7f9772f0b4a0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x610000220c80>>
   |    |    | <UITableView: 0x7f9773007a00; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x6080000577c0>; layer = <CALayer: 0x608000222d20>; contentOffset: {0, -64}; contentSize: {414, 270}>
   |    |    |    | <UITableViewWrapperView: 0x7f9773007400; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x608000057af0>; layer = <CALayer: 0x608000222e00>; contentOffset: {0, 0}; contentSize: {414, 736}>
   |    |    |    |    | <TableViewTraining.MealTableViewCell: 0x7f977486b000; baseClass = UITableViewCell; frame = (0 180; 414 90); clipsToBounds = YES; autoresize = W; layer = <CALayer: 0x6000002215a0>>
   |    |    |    |    |    | <UITableViewCellContentView: 0x7f977660ca50; frame = (0 0; 414 89.6667); opaque = NO; gestureRecognizers = <NSArray: 0x600000058c00>; layer = <CALayer: 0x600000221ac0>>
   |    |    |    |    |    |    | <UIStackView: 0x7f9776609ab0; frame = (0 0; 414 89.6667); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x600000221e60>>
   |    |    |    |    |    |    |    | <UIImageView: 0x7f97766056c0; frame = (0 0; 90 89.6667); clipsToBounds = YES; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x600000221c00>>
   |    |    |    |    |    |    |    | <UIStackView: 0x7f9776604dd0; frame = (100 0; 314 89.6667); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x600000221ce0>>
   |    |    |    |    |    |    |    |    | <UILabel: 0x7f9776611b90; frame = (0 0; 314 20.3333); text = 'Kuniwak3'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60000008f910>>
   |    |    |    |    |    |    |    |    | <UIView: 0x7f977660ceb0; frame = (0 30.3333; 314 59.3333); autoresize = RM+BM; layer = <CALayer: 0x6000002226a0>>
   |    |    |    |    |    |    |    |    |    | <TableViewTraining.RatingControl: 0x7f97766123f0; frame = (37 7.66667; 240 44); autoresize = RM+BM; layer = <CALayer: 0x600000222700>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f97766125b0; frame = (0 0; 44 44); opaque = NO; layer = <CALayer: 0x600000222a40>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9776614340; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x600000223b20>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f97766128b0; frame = (49 0; 44 44); opaque = NO; layer = <CALayer: 0x600000222b00>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9776614520; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x600000223c20>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9776612b70; frame = (98 0; 44 44); opaque = NO; layer = <CALayer: 0x600000222b60>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9776614700; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x600000223cc0>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9776612e30; frame = (147 0; 44 44); opaque = NO; layer = <CALayer: 0x600000222c00>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f97766148e0; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x600000223d60>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f97766130f0; frame = (196 0; 44 44); opaque = NO; layer = <CALayer: 0x600000222ca0>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9776614ac0; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x600000223e00>>
   |    |    |    |    |    | <_UITableViewCellSeparatorView: 0x7f97766133b0; frame = (15 89.5; 399 0.5); layer = <CALayer: 0x600000223000>>
   |    |    |    |    |    | <_UITableViewCellSeparatorView: 0x7f9776614060; frame = (20 89.6667; 394 0.333333); layer = <CALayer: 0x600000221b20>>
   |    |    |    |    | <TableViewTraining.MealTableViewCell: 0x7f977503ba00; baseClass = UITableViewCell; frame = (0 90; 414 90); clipsToBounds = YES; autoresize = W; layer = <CALayer: 0x610000220f60>>
   |    |    |    |    |    | <UITableViewCellContentView: 0x7f9772f08dc0; frame = (0 0; 414 89.6667); opaque = NO; gestureRecognizers = <NSArray: 0x60800005b3f0>; layer = <CALayer: 0x610000221fc0>>
   |    |    |    |    |    |    | <UIStackView: 0x7f9772f0f520; frame = (0 0; 414 89.6667); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x610000221300>>
   |    |    |    |    |    |    |    | <UIImageView: 0x7f9772f0f6e0; frame = (0 0; 90 89.6667); clipsToBounds = YES; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x610000221000>>
   |    |    |    |    |    |    |    | <UIStackView: 0x7f9772f0f8c0; frame = (100 0; 314 89.6667); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x610000221180>>
   |    |    |    |    |    |    |    |    | <UILabel: 0x7f9772f0fa80; frame = (0 0; 314 20.3333); text = 'Kuniwak2'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x61000008feb0>>
   |    |    |    |    |    |    |    |    | <UIView: 0x7f9772c10be0; frame = (0 30.3333; 314 59.3333); autoresize = RM+BM; layer = <CALayer: 0x608000225340>>
   |    |    |    |    |    |    |    |    |    | <TableViewTraining.RatingControl: 0x7f9772c12b00; frame = (37 7.66667; 240 44); autoresize = RM+BM; layer = <CALayer: 0x608000225280>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772c12780; frame = (0 0; 44 44); opaque = NO; layer = <CALayer: 0x608000225240>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c15510; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x608000226600>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772c12dc0; frame = (49 0; 44 44); opaque = NO; layer = <CALayer: 0x6080002253e0>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c159d0; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x608000226700>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772c13080; frame = (98 0; 44 44); opaque = NO; layer = <CALayer: 0x608000225480>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c15bb0; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6080002267a0>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772c13340; frame = (147 0; 44 44); opaque = NO; layer = <CALayer: 0x608000225520>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c15d90; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x608000226840>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772c13600; frame = (196 0; 44 44); opaque = NO; layer = <CALayer: 0x6080002255c0>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c15f70; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6080002268e0>>
   |    |    |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772c13d20; frame = (15 89.5; 399 0.5); layer = <CALayer: 0x608000225920>>
   |    |    |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772c15230; frame = (20 89.6667; 394 0.333333); layer = <CALayer: 0x608000225260>>
   |    |    |    |    | <TableViewTraining.MealTableViewCell: 0x7f9774812a00; baseClass = UITableViewCell; frame = (0 0; 414 90); clipsToBounds = YES; autoresize = W; layer = <CALayer: 0x61800003fe60>>
   |    |    |    |    |    | <UITableViewCellContentView: 0x7f9772d02e20; frame = (0 0; 414 89.6667); opaque = NO; gestureRecognizers = <NSArray: 0x608000057070>; layer = <CALayer: 0x618000422700>>
   |    |    |    |    |    |    | <UIStackView: 0x7f9772d093a0; frame = (0 0; 414 89.6667); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x618000422740>>
   |    |    |    |    |    |    |    | <UIImageView: 0x7f9772d0b760; frame = (0 0; 90 89.6667); clipsToBounds = YES; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x618000422760>>
   |    |    |    |    |    |    |    | <UIStackView: 0x7f9772d0c070; frame = (100 0; 314 89.6667); opaque = NO; autoresize = RM+BM; layer = <CATransformLayer: 0x618000422880>>
   |    |    |    |    |    |    |    |    | <UILabel: 0x7f9772d0c440; frame = (0 0; 314 20.3333); text = 'Kuniwak1'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x61800008d7f0>>
   |    |    |    |    |    |    |    |    | <UIView: 0x7f9772f0d630; frame = (0 30.3333; 314 59.3333); autoresize = RM+BM; layer = <CALayer: 0x610000220b00>>
   |    |    |    |    |    |    |    |    |    | <TableViewTraining.RatingControl: 0x7f9772f0d7d0; frame = (37 7.66667; 240 44); autoresize = RM+BM; layer = <CALayer: 0x6100002237c0>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772c09280; frame = (0 0; 44 44); opaque = NO; layer = <CALayer: 0x608000222b20>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c10260; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x608000224460>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772d0cbf0; frame = (49 0; 44 44); opaque = NO; layer = <CALayer: 0x618000422bc0>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c0fab0; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x608000224560>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772d0d1c0; frame = (98 0; 44 44); opaque = NO; layer = <CALayer: 0x618000422a80>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c10440; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x608000224600>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772d0d480; frame = (147 0; 44 44); opaque = NO; layer = <CALayer: 0x618000422ba0>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c10620; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6080002246a0>>
   |    |    |    |    |    |    |    |    |    |    | <UIButton: 0x7f9772d0d740; frame = (196 0; 44 44); opaque = NO; layer = <CALayer: 0x618000422c40>>
   |    |    |    |    |    |    |    |    |    |    |    | <UIImageView: 0x7f9772c10800; frame = (0 0; 44 44); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x608000224740>>
   |    |    |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772d0eb30; frame = (15 89.5; 399 0.5); layer = <CALayer: 0x618000422fc0>>
   |    |    |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772c0e7f0; frame = (20 89.6667; 394 0.333333); layer = <CALayer: 0x6080002235c0>>
   |    |    |    | <UIImageView: 0x7f9772f080b0; frame = (3 666.667; 408 2.33333); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x610000222580>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f0a880; frame = (20 359.667; 394 0.333333); autoresize = W; layer = <CALayer: 0x610000220d00>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f09d40; frame = (20 449.667; 394 0.333333); autoresize = W; layer = <CALayer: 0x610000220e40>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f09610; frame = (20 539.667; 394 0.333333); autoresize = W; layer = <CALayer: 0x610000220f80>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f0fd10; frame = (20 629.667; 394 0.333333); autoresize = W; layer = <CALayer: 0x610000221a80>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f0fed0; frame = (20 719.667; 394 0.333333); autoresize = W; layer = <CALayer: 0x610000220ee0>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f10190; frame = (20 809.667; 394 0.333333); autoresize = W; layer = <CALayer: 0x6100002216c0>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f10350; frame = (20 899.667; 394 0.333333); autoresize = W; layer = <CALayer: 0x6100002213c0>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f10510; frame = (20 989.667; 394 0.333333); autoresize = W; layer = <CALayer: 0x610000221e40>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f106d0; frame = (20 1079.67; 394 0.333333); autoresize = W; layer = <CALayer: 0x6100002222a0>>
   |    |    |    | <_UITableViewCellSeparatorView: 0x7f9772f10890; frame = (20 1169.67; 394 0.333333); autoresize = W; layer = <CALayer: 0x610000222940>>
   |    |    |    | <UIImageView: 0x7f9772f0c940; frame = (408.667 405; 2.33333 264); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x610000221440>>
   | <UINavigationBar: 0x7f9772f08510; frame = (0 20; 414 44); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x6000000560e0>; layer = <CALayer: 0x610000220d40>>
   |    | <_UIBarBackground: 0x7f9772f0a670; frame = (0 -20; 414 64); userInteractionEnabled = NO; layer = <CALayer: 0x610000222aa0>>
   |    |    | <UIImageView: 0x7f9772f0ac70; frame = (0 64; 414 0.333333); userInteractionEnabled = NO; layer = <CALayer: 0x610000222100>>
   |    |    | <UIVisualEffectView: 0x7f9772f0ae50; frame = (0 0; 414 64); layer = <CALayer: 0x610000222b00>>
   |    |    |    | <_UIVisualEffectBackdropView: 0x7f977660a010; frame = (0 0; 414 64); autoresize = W+H; userInteractionEnabled = NO; layer = <UICABackdropLayer: 0x600000221ec0>>
   |    |    |    | <_UIVisualEffectFilterView: 0x7f9772d0a000; frame = (0 0; 414 64); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x618000221080>>
   |    | <<UINavigationItemView: 0x7f9772f08be0; frame = (163 8; 88 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x610000220ba0>>: item=<<UINavigationItem: 0x6000001de5a0>: title:'Your Meals'> title=Your Meals>
   |    |    | <UILabel: 0x7f9772f09380; frame = (0 3; 88 21.3333); text = 'Your Meals'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x61000008dc50>>
   |    | <UINavigationButton: 0x7f9776608890; frame = (366 6; 39 30); opaque = NO; layer = <CALayer: 0x600000221340>>
   |    |    | <UIImageView: 0x7f9772f089d0; frame = (11 6.33333; 17 17); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x610000221fe0>>
   |    | <_UINavigationBarBackIndicatorView: 0x7f9772d0a5d0; frame = (12 11.6667; 13 21); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x618000422900>>

操作する UIView を入手する

先ほど入手した UIViewUIView#subviews から辿って行ってもよいですが、アドレスとクラスがわかっていれば、簡単にインスタンスを入手できます。

例えば、下の UIImageView インスタンスを操作したいとしましょう:

<UIImageView: 0x7f9772f0ac70; frame = (0 64; 414 0.333333); userInteractionEnabled = NO; layer = <CALayer: 0x610000222100>>

アドレスとは、0x7f9772f0ac70 の部分のことです。これとクラスを使うと、次のように unsafeBitCast(_:to:) を使ってインスタンスを取得できます:

(lldb) expression -O -- unsafeBitCast(0x7f9772f0ac70, to: UIImageView.self)
<UIImageView: 0x7f9772f0ac70; frame = (0 64; 414 0.333333); userInteractionEnabled = NO; layer = <CALayer: 0x610000222100>>

入手した UIView を料理する

ここまで出来れば、UIView をいかようにでも料理できます。

例えば、ある UIImageView の画像を消すには、次のようにします:

(lldb) expression -O -- unsafeBitCast(0x7f97766056c0, to: UIImageView.self).image = nil

(lldb) continue

Before

スクリーンショット 2016-12-28 16.44.21.png

After

スクリーンショット 2016-12-28 16.44.53.png

まとめ

Simulator で実行中の iOS アプリケーションの任意の UIView を操作する方法として、次の2つのコマンドを紹介しました。

(lldb) expression -O -- UIApplication.shared.keyWindow!.rootViewController!.view!.value(forKey: "recursiveDescription")!

(lldb) expression -O -- unsafeBitCast(0x7f9772f0ac70, to: UIImageView.self)

Enjoy, debugging!

参考文献


  1. expression -O -- hogepo hoge というエイリアスでも実行できます。 

46
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
27