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

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

# 手順
## アプリを一時停止する

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

<img width="393" alt="Debug &lt; Pause ^⌘Y" src="https://qiita-image-store.s3.amazonaws.com/0/6281/08158b6e-2f25-3e59-6d39-d138a82936dc.png">

[<img width="684" alt="Pause ボタンは、デバッグバーの左から3番目のボタンです" src="https://qiita-image-store.s3.amazonaws.com/0/6281/f46664c7-ff11-a445-c87e-9146a5970bbb.png">](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/debugging_with_xcode/chapters/debugging_tools.html#//apple_ref/doc/uid/TP40015022-CH8-SW8)


## `UIApplication` が見えるスタックへ移動する
### 画面操作慣れしている方向け

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

[<img width="260" alt="スクリーンショット 2016-12-28 14.59.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/6281/f6e78ce4-37af-44bb-a5a3-19873601203b.png">](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/debugging_with_xcode/chapters/debugging_tools.html#//apple_ref/doc/uid/TP40015022-CH8-SW8#//apple_ref/doc/uid/TP40015022-CH8-SW19)


### 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](http://lldb.llvm.org/) を実行します。

[![dwx-dt-debugarea-1_2x.png](https://qiita-image-store.s3.amazonaws.com/0/6281/a624cbe4-9400-d407-f126-82851b4f085c.png)](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/debugging_with_xcode/chapters/debugging_tools.html#//apple_ref/doc/uid/TP40015022-CH8-SW7)

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`](http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?revision=288797&view=markup#l220) コマンドを使って、View の一覧を確認していきます。なお、`-O` も一緒に指定しますが、これは人間の読みやすい形式で表示するオプションです[^1]。

[^1]: `expression -O -- hoge` は `po hoge` というエイリアスでも実行できます。

[`UIApplication`](https://developer.apple.com/reference/uikit/uiapplication) は、アプリが起動している間存在するシングルトンなクラスです。このクラスのインスタンスから、現在表示されている View までたどることができます:

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

`UIApplication` は、現在有効な [`UIWindow`](https://developer.apple.com/reference/uikit/uiwindow) を [`UIApplication#keyWIndow`](https://developer.apple.com/reference/uikit/uiapplication/1622924-keywindow) に持っています:

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

この `UIWindow` は、[`UIWindow#rootViewController`](https://developer.apple.com/reference/uikit/uiwindow/1621581-rootviewcontroller) に [`ViewController`](https://developer.apple.com/reference/uikit/uiviewcontroller) を持っています:

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

この [`UIViewController#view`](https://developer.apple.com/reference/uikit/uiviewcontroller) から、[`UIView`](https://developer.apple.com/reference/uikit/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`](https://developer.apple.com/library/content/technotes/tn2239/_index.html#//apple_ref/doc/uid/DTS40010638-CH1-SUBSECTION34) というデバッグ用のメソッドを備えています。ただ、Swift からは直接呼び出せないので、`UIView` の親クラスである[`NSObject#value(forKey:)`](https://developer.apple.com/library/content/technotes/tn2239/_index.html#//apple_ref/doc/uid/DTS40010638-CH1-SUBSECTION34) 経由で呼び出す必要があります:

```
(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` を入手する

先ほど入手した `UIView` の [`UIView#subviews`](https://developer.apple.com/reference/uikit/uiview/1622614-subviews) から辿って行ってもよいですが、アドレスとクラスがわかっていれば、簡単にインスタンスを入手できます。

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

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

アドレスとは、`0x7f9772f0ac70` の部分のことです。これとクラスを使うと、次のように [`unsafeBitCast(_:to:)`](https://developer.apple.com/reference/swift/1641250-unsafebitcast) を使ってインスタンスを取得できます:

```
(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
<img width="423" alt="スクリーンショット 2016-12-28 16.44.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/6281/3d4a4c5c-4704-22be-d695-994116d6f7c8.png">

### After
<img width="423" alt="スクリーンショット 2016-12-28 16.44.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/6281/6fc7a5c3-a3b4-fab7-6273-721492e9dab9.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!


# 参考文献

- [Debugging with Xcode - Guides and Sample Code](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/debugging_with_xcode/chapters/debugging_tools.html)
- [iOS Debugging Magic - Guides and Sample Code](https://developer.apple.com/library/content/technotes/tn2239/_index.html)
- [Reverse-Engineering iOS Apps: Hacking on Lyft
(Conrad Kramer) - realm](https://realm.io/news/conrad-kramer-reverse-engineering-ios-apps-lyft/)