xib や Storyboard をロックする

# xib や Storyboard ファイルを開いただけで勝手に変更される件

Xcode の Interface Builder は xib や Storyboard ファイルをただ開いただけで勝手にどこかを変更してくれることがあります。余計なお節介です。

ちょっと UI 構成を確認したいというだけなのに開いたらいちいち変更を取り消すというのは面倒ですし、そうでないにしても、更新するつもりのない xib を誤ってコミットしてしまいコミットログを汚し、結果いらぬ誤解を生んでしまうというのも嫌なものです。

対策として以下3案を考えてみました。

# 「ロック」したらいいんじゃないか

既に確定したレイアウトは後から見ることはあっても変更はしません。であればロックしてしまいましょう。少々面倒ではありますが、もし後から変更が必要になったら一旦ロックを外し、済んだら再度ロックする運用にしてみます。

## 1. IB のプロパティロック機能を活用する

いずれかの部品（ViewController, View など）を選択したら、右ペインの Identity Inspector タブを開きましょう。

![lockib.png](https://qiita-image-store.s3.amazonaws.com/0/3603/f4b84681-7448-9bc4-8537-fc4db50bb767.png)

"Document" セクションの中に "**Lock**" というポップアップボタンが見えます。初期値は Inherited (Nothing) となっているので、これを "**All Properties**" に変更します。
これで選択した部品以下は変更を受け付けなくなりました。不意にドラッグなどをしてしまっても frame の変更は受け付けなくなります。
xib / Storyboard ファイルはこの状態で保存するようにしましょう。

![lock.png](https://qiita-image-store.s3.amazonaws.com/0/3603/72b09d00-edee-e6ca-e7f9-489a63d83069.png)
*ビューをドラッグしても変更が反映されず、錠前アイコンで知らせてくれるので安心。*

これで各要素の変更は防ぐことが出来ました。とりあえずはこれで良さげな気もしますが、XMLファイルとしてみればまだ変更は可能な状態に思えます。これには次の策を考えてみます。

## 2. パーミッションを readonly にしてみる

```
-rw-r--r--   1 USER  staff  3712  3  4 03:28 LaunchScreen.xib
-rw-r--r--   1 USER  staff  2007  3  4 02:45 Main.storyboard
```

xib / Storyboard ファイルのパーミッションを readonly に変えてみます。

```
$ chmod 444 LaunchScreen.xib
```
```
-r--r--r--   1 USER  staff  3712  3  4 03:28 LaunchScreen.xib
-rw-r--r--   1 USER  staff  2007  3  4 02:45 Main.storyboard
```

この状態で変更を加えようとすると、ロックされている旨のダイアログが表示されます。
![sheet2.png](https://qiita-image-store.s3.amazonaws.com/0/3603/2f446c0f-efdd-545a-54af-88514f43fab2.png)
*Unlock を実行するとパーミッションが "644" に戻ります。*


## 3. ファイルをロックしてみる

Finder にはファイルの「ロック」という機能が存在します。これを試してみます。

![lockfinder.jpg](https://qiita-image-store.s3.amazonaws.com/0/3603/b9e2f002-1610-557b-07f6-2b5df0b16b42.jpeg)

Finder で xib / Storyboard ファイルを選択したらすかさず *⌘ I*。ウインドウ内 "**一般情報**" の下に "**ロック**" というチェックが見えるので、これを有効にします。これで鍵付きアイコンに出来ます。
もし大量のファイルを一度にロックしたい・外したいというのであれば、複数選択して *⌃ ⌘ I* とすると一つの情報ウインドウにまとめられるので便利です。

![sheet.png](https://qiita-image-store.s3.amazonaws.com/0/3603/31b554c1-b633-c91f-3d76-6331d0a3647b.png)
*ロックされた状態でファイルに変更を加えようとすると、このようなシートダイアログが表示されます。*


### そもそも Finder の「ロック」とは何か

このロック属性、いったいどこに保存されるのかが気になります。結論から言うとこれは BSD 系に共通するファイルフラグというもので、 `chflags` で変更できるフラグだそうです。
> [chflags ファイルのフラグを変更する](http://x68000.q-e-d.net/~68user/unix/pickup?chflags)

実際にコマンドから確認してみます。

![flag1.png](https://qiita-image-store.s3.amazonaws.com/0/3603/86bb5aea-08eb-0e87-e479-a6a4784ab54e.png)
*"file" というファイルをロックしていない状態で `ls -lO`*

![flag2.png](https://qiita-image-store.s3.amazonaws.com/0/3603/002f28a3-43bc-3afb-6194-4188c34af8b0.png)
*"file" を Finder でロックしてから再度 `ls -lO`。*

Finder でロックすると `uchg` フラグが立つということが分かりました。

こちらの記事でも詳しく検証されていました。

> [[chflags]Finder上での『鍵』マークの仕組み](http://force4u.cocolog-nifty.com/skywalker/2010/10/chflagsfinder-5.html)

> [ファイルの属性情報を探る 権限編](http://d.hatena.ne.jp/zariganitosh/20130411/attribute_permission)

## Git リポジトリではどう運用するか

ここが割と肝心だったりします。

### IB のロック機能

ロック属性は xib / Storyboard ファイルに書き込まれるので、ロックを変更するとファイルの変更という扱いになります。（保存するとMマークが付きます。）
![m.png](https://qiita-image-store.s3.amazonaws.com/0/3603/bf086e02-7c97-b432-8bfb-77a79360cf98.png)

### パーミッションの変更を反映

filemode=true／未設定 であればファイルのパーミッションが反映されるようです。

> [Git でファイルパーミッションの変更（chmod）を無視する - git config core.filemode false](http://tetsuwo.tumblr.com/post/36066698390/git-chmod-git-config)

### ファイルフラグの変更を反映

Xcode/Git 上では変更扱いにはなりませんでした。Git 側に何か設定があるのでしょうか。

リポジトリに反映できないのであれば、これを逆手にとって作業コピー環境下のみでファイルをロックしておく（コミット／プッシュしても変更の心配無し）、という運用も考えられそうです。

# おわりに

結論といえる程ではありませんが、策1を講じておけばほぼ問題はないと思います。それでも不安ということであれば策2との合わせ技でしょうか。いずれにしてもロック運用にするということをチーム内で共通認識としておくことが大切だと思います。

もしこの他にも良いソリューションがありましたら教えていただけると幸いです。

# 関連記事

コンフリクトした xib ファイルを上手にマージする
http://qiita.com/uasi/items/a20ea86fa11484ccd1db

Don’t Modify My Nibs
http://theappcanuck.com/dont-modify-my-nibs/

XCode 5 Interface Builder Storyboard locked
https://pragmapilot.wordpress.com/2013/09/25/xcode-5-interface-builder-storyboard-locked/