古いXcodeが対応していない新しいバージョンのiOSに対してアプリをRunさせる方法

# はじめに

現在（2019年1月21日）で言えば `Xcode10` が最新である今日この頃、
`Xcode10` は `iOS12` までの動作確認を行うことができます。
古い `Xcode9` は `iOS11` までの動作確認しかできません。

iOSの進化ともにXCodeも新しくしていかなくてはならないのがこの世界の宿命ですが、
諸般の事情で「`古いXcode` で作られたアプリが最新のXcodeでビルドできず `古いXcode` のまま改修する必要がある」ものの、
**『動作確認は `最新のiOS` まで行わなくてはいけない』**という状態の場合に、
`古いXcode` から `最新のiOS` のデバイスでアプリをRunさせて動作確認するための苦肉の（？）方法を書きます。

## ※注意

* すべてのバージョンのXCode、およびiOSに適用できるかどうかはわかりません。
* この記事では、今日現在の環境 `Xcode10, iOS12 が最新の状態` での **Xcode9で、iOS12に対してRunさせる方法** を書きます。
* Xcode.appの中身を操作するので、結果Xcodeが正しく動作しなくなる可能性があります。
* あなたの責任で行なってください。もし本記事を参考にして何かおかしくなったとしても、私は何も責任を持ちません。Xcodeがおかしくなった場合は、Xcodeの再インストールなどをしてください。

## 追記そして結論(2020/07/02)

コメントいただきまして、当初の本文では新しいXcodeから無理やり持ってきている「Device Support」ですが、
昔のから最新まで配布しているGitHubリポジトリがあるようです。
この長々とした記事は、以下の2行で解決です。

>こちらのリポジトリにDeviceSupportファイルが置いてあるので、ダウンロード解凍した後、/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/ に移動すれば良いです。
https://github.com/filsv/iPhoneOSDeviceSupport



故に以下ただの余談です。

---

# 手順

## 1. 最新のXCodeを準備する

現在のXcodeはAppSore経由でのダウンロードになるので、AppStoreからダウンロード＆インストールします。


## 2. 古いXcodeを準備する

AppStoreから最新のXcodeしかダウンロードできないので、Apple Developerのサイトから古いバージョンのXcodeを探してダウンロードします。

### 2-1. Apple Developer Downloadページへ

[More Downloads for Apple Developers](https://developer.apple.com/download/more/)


<img width="1006" alt="古いXcodeを探す.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/f9a54896-4b5f-e29e-eb4c-96f70272545a.png">

左上の検索欄に「Xcode」と入力して検索実行して、目的のバージョンのXcodeを探します。
`xipファイル`なるものがダウンロードできるのでダウンロードします。

### 2-2. xipファイルからXcode.appを取得

ダウンロードした `xipファイル` をダブルクリックなどして開くと、展開されて同ディレクトリに「Xcode.app」が生成されます。
そのままの名称だと最新のXcodeと名前が被ってしまうので、`Xcode_941.app` など適当に名前を変更します。

そしてどこにあってもよいですが、`Applicationディレクトリ` などに必要に応じて移動してください。
ここではApplicationディレクトリに移動したという前提のパスで解説していきます。

<img width="400" alt="ApplicationディレクトリのXcodeたち.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/00386b93-3cbf-bc0b-8a34-8e0284d6bbf7.png">

**うわ、8.3.3 もある** という闇を垣間見ていきます。


## 3. 古いXcodeを改造していく

### 3-1. 古いXcodeで試しに最新のiOSにRunしてみて起動できないことを確認する

`Xcode 9.4.1` を開いて、適当なプロジェクトを開き、適当な iOS12 のデバイスにRun させてみます。
するとXcode9系は iOS11までしか対応していないため以下のようなエラーでRunできません。
> **Could not locate device support files.**
> This {デバイス} is running iOS 12 ~~~, which may not be supported by this version of Xcode.

<img width="435" alt="未対応iOSでRunできない.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/bbcc6b0b-3ae7-0125-e049-fb2091b98c92.png">

*device support files が無いよ* 的なエラー内容に、
ならば **device support files を用意すればイケるのでは？** と推測します。

わかったところで一旦Xcodeを終了します。


### 3-2. 新しいXcodeから古いXcodeに、大事な何かをコピーする

最新のXcode.appを、Finderで右クリックし「パッケージの内容を表示」を選択します。
そして以下のディレクトリにある、必要なiOSのバージョン番号を冠したディレクトリをコピーします。

`/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport`

<img width="1424" alt="Xcode10のコンテンツ内.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/c071005a-2b40-264f-e9c2-185b36f22373.png">


古い `Xcode_941.app` で同様に「パッケージの内容を表示」を選択し、
上記でコピーしたディレクトリを、古いXcode内の同様のディレクトリにペーストします。

`/Applications/Xcode_941.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport`

<img width="1424" alt="Xcode9のコンテンツ内.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/34878778-521b-b744-eefc-a38f8501155b.png">

見るとわかるようにXcode9内`DeviceSupport`には、iOS11.xまでしかありません。
ここに、最新XcodeからコピーしたiOS12郡のディレクトリをペーストします。
（間違って切り取ったりしないように。）

<img width="1428" alt="Xcode10からXcode9にコピー＆ペースト.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/42a1cd13-4bd0-1f9e-ba63-1d038e267e51.png">


## 4. 古いXcodeで対象プロジェクトを編集する

### 4-1. 古いXcodeを起動して、最新のiOSにRunしてみて、まだ起動できないことを確認する

上記までの手順で準備した古いXcodeを起動します。
起動したところで、特に何か変わったことはないと思います。

そのままの状態で、実行したいプロジェクトを開き、適当な iOS12 のデバイスにRun させてみます。

恐らく以下のようなエラーが出て起動に失敗すると思います。
（もし成功したらおめでとうございます。）

> **Could not launch "{アプリ名}"**  
> {デバイス名} has denied the launch request.

<img width="420" alt="起動できない.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/445fd8cf-1428-91fa-1db3-099fb8293e93.png">


### 4-2. 対象プロジェクトのSchemeを編集する

* [Product → Scheme → Edit Scheme] を選択します。

<img width="523" alt="schemeメニュー.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/f02c974a-80ed-1a1f-e1a5-cd4115235013.png">


* [Run]パネルの[info]タブ中にある **【Debug executable】** のチェックを **外します。**
    * お察しの通り、本方法ではデバッガの機能を外す必要があるので、ブレークポイント等のデバッガ機能は利用できません。
    
<img width="900" alt="Edit_Scheme.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/5ccc0052-91d8-0e6a-1c8f-f9547b9caa6a.png">


### 4-3. 古いXcodeで新しいiOS上にRunできることを確認する

上記までの手順を踏んだ上で改めて、適当な iOS12 のデバイスにRun させてみます。

無事に`Xcode 9.4.1`で、対象のプロジェクトを `iOS12` のデバイスに対してインストールすることができ、
Xcode上でコンソールログ等が表示されることを確認します。

これで最新のiOSで動作させるがためだけに、いちいちAd-hocで書き出したり、いちいちデプロイサービスを使う手間が省けます...🤗 🤢 🤮


# トラブルシューティング

## Q. やってみたけど、できなかった！

A. **わかりません。**

## Q. できるようになったけど、数日後できなくなった！

A. たしかなことはわかりませんが、私も幾日かした後か、あるいは何らかの操作がきっかけか、古いXcodeにコピーしたDeviceSupportのディレクトリが元に戻っていることがありました。    
     DeviceSupportディレクトリ内に対象のiOSのディレクトリがあるかどうかを確認してみましょう。 


# 補足

## Q. 途中でオフにした「Debug executable」って何？

Xcodeからアプリを実行した際に、ブレークポイントでの停止や変数の中身を見るような、いわゆるデバッガ機能を有効にするかどうかのチェックボックスです。

アプリを実行する場合のビルド設定は「Debug」ビルドと「Release」ビルドがあり（カスタマイズして増やそうと思えばいくらでも増やせますが）、
通常、
「Debug」ビルドの場合は Debug executable はオンになっており、
「Release」ビルドの場合は Debug executable はオフになっています。

「Debug」ビルドは、Xcodeからシミュレータやケーブルで繋いだデバイスでアプリを実行する場合に選択されるビルド方法なので、デバッグ用途である「Debug executable」をオフにすることはDebugビルドのアイデンティティを奪う行為です。

「Release」ビルドは、App Storeに公開するアプリや、Ad-Hoc配布、In-house配布等のために出力するアプリをビルドする際に選択させるビルド方法です。
Releaseビルドで、デバッグ用途である「Debug executable」をオンにしてしまうと、予期せぬデバッグのための処理がリリース用のアプリで実行されてしまう可能性があります。



# おわりに

iOSのバージョンアップとXcodeのバージョンアップは一蓮托生なので、
基本的にはちゃんと最新の環境でビルドできるように追従してくことが望ましいです。

どうかこんな方法に頼ることなかれ。