はじめに
実行環境はmacOS High Sierra (10.13.3)、Xcode 9.2 (9C40b)です。
SwiftでiOSアプリを作るApple公式のチュートリアルをやっていて、アプリがmeals
というファイルにデータを入出力するコードが出てきました。
シミュレータ上でこのアプリを動かしたときに、ふと疑問がわいたのです。
「このmealsファイルをmacOSから直接のぞくことはできないだろうか」と。
チュートリアルでは標準ライブラリのNSKeyedArchiver
でオブジェクトをシリアライズしてファイルに書き込んでいます。
が、これがSQLite.swiftのようなSQLiteラッパーを使ってファイルに書き込むようになったらどうでしょう。
そのファイルをmacOS上のDB Browser for SQLiteで確認したくなることは間違いありません。
と、いうわけで、Stack Overflowのこのやりとりを参考に調べてみたので備忘的にメモっておきます。
Is there any way to see the file system on the iOS simulator?
iOSシミュレータのディレクトリ(Xcode 9.2)
各iOSシミュレータのファイルは以下のディレクトリに配置されています。
~/Library/Developer/CoreSimulator/Devices
ls
コマンドで見てみましょう。
$ pwd
/Users/<ユーザ名>/Library/Developer/CoreSimulator/Devices
$ ls
02AE7C26-627E-4DD5-997F-8C17449FB89B 2BA54912-6280-4DCC-B617-69FD59095EC4 8767140F-31D4-4D02-8A6F-A1BD57277347 C517CC4D-7C16-4C0B-A077-68088C09B8B6
151D1CFA-EAF0-4EF0-A3AE-E679C5640108 323124FB-96CA-4212-AFE6-ECA8DC7636FE 8A12F5C2-F4EA-4EB9-94E4-BF16C22EC013 C6ABCE36-8D1D-4A6E-805A-78997759A4C2
15A1E20D-0009-40CA-ADBD-816820B38E6C 3567DAA2-B426-47B0-A5D1-7B20B88D309C 8B3553F3-A219-4790-BB5E-28C284741E7F D12F2119-0DEF-4292-BB63-B28E225396EF
15CA514C-58DB-46FC-B4B8-678ED7AE30D5 3FE92A72-4D7B-4047-A410-626D3D799600 8CEE1059-DD19-490B-AE48-8512875D388C DD056CC5-3857-41EA-BBBD-D48AA3274502
16F49F71-CF88-4DFA-B3AF-E01240CCA406 3FEAD4E3-22A8-4A9B-AEBD-F4D8AA5FEDA1 980FA015-ACEF-4AE9-8C94-CA0B723B815E DF1584FA-D5E1-4606-A76F-092E28469BC6
1E32ACBD-1F19-482B-AE4E-F60836FDA0E0 4BE94664-0EDA-4F38-8668-78B50B357059 9D9455E1-7363-4AD2-B724-2CF5D6D7C020 E787E0AD-916A-4B14-8A6F-FE668D72A214
1E4E92D1-CE64-482B-AF94-AE2DD41A124D 5675085F-9862-4A96-AAC9-1BEDB694E24B A01EC8B8-F6C6-496D-86D7-BDD8BD5790F0 F7B428F3-E1E1-4D02-9658-92B9F8642F7F
2191D5B1-480C-4E19-9222-DF7C3E67BFA6 76811558-A524-4265-B6BC-616254BCDFB7 A7B4B4AE-3BC2-4AF2-88C8-A04FBE3C1960 F9607C80-6C79-4909-98E7-78164DC1C898
21B70526-175B-4305-9F32-A07644B4F44C 7740D85E-E86B-4B74-89A3-F88815DFCF81 AC508541-4E92-47EF-A2BB-6B39797BE91E FC40A816-6049-446A-A6A2-64820FD8C969
27E26E30-B934-4495-90BF-A325E083DE9A 7B5F54E7-A1A2-418D-A7DE-4FFB98229EC5 B13584B6-EA8D-459C-A41E-82A544F918B0 FF77A96E-FB5F-4A50-A93B-9C55F71F116A
2953E794-8BA3-4358-A035-FFBB5F014C65 7CA53664-45EC-4D12-B985-B78C8B03D62E B16FE335-31D4-4099-9864-9A08E8BA2EE4 device_set.plist
2AEF4BC3-B4B5-4568-B80D-D6E2218117FF 7D409B17-6D0F-4058-BE48-F5E736EDA0D1 C1DB0F87-F47E-4E14-ABA8-F85C1E8FE942
GUIDと思わしき名前のディレクトリがずらーっとあります。
このままだとわけがわかりません。
このディレクトリのdevice_set.plist
ファイルがxmlになっていて、以下のように、iOSバージョンごとに、シミュレータのデバイスとディレクトリ名の対応づけがされています。
<!-- 前略 ... -->
<key>com.apple.CoreSimulator.SimRuntime.iOS-11-2</key>
<dict>
<key>com.apple.CoreSimulator.SimDeviceType.iPad--5th-generation-</key>
<string>980FA015-ACEF-4AE9-8C94-CA0B723B815E</string>
<!-- 途中省略 ... -->
<key>com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus</key>
<string>3FE92A72-4D7B-4047-A410-626D3D799600</string>
</dict>
<!-- 後略 ... -->
今回、チュートリアルのFoodTrackerアプリを動かしたのはiOS11.2のiPhone-8-Plusのシミュレータだったので、3FE92A72-4D7B-4047-A410-626D3D799600
ディレクトリ以下を探せば良いことになります。
アプリの実行ファイルのありか
で、このディレクトリ以下をいろいろ漁ってみたのですが、アプリケーションの実行ファイル自体は以下のディレクトリにあるようです。
~/Library/Developer/CoreSimulator/Devices/3FE92A72-4D7B-4047-A410-626D3D799600/data/Containers/Bundle/Application
つまり、一般化して書くと
~/Library/Developer/CoreSimulator/Devices/<シミュレータのGUID>/data/Containers/Bundle/Application
です。
このディレクトリ以下に、アプリごとのディレクトリが切られているわけですが、これもシミュレータと同様、ディレクトリ名がGUIDです。
そのGUIDのディレクトリ下に、アプリ名.app
が見つかりました。チュートリアルではFoodTracker
という名前のアプリを作っていたので、FoodTracker.app
というファイルが見つかりました。
$ pwd
/Users/<ユーザ名>/Library/Developer/CoreSimulator/Devices/3FE92A72-4D7B-4047-A410-626D3D799600/data/Containers/Bundle/Application
$ ls
3153817A-D8FD-4634-AB35-DA35E6292F04 43328334-CA84-488E-BAF8-C76D9D44B979 56A57B07-F67C-4406-9F5C-1541B53654C3 CF518D8C-DEC0-4220-8CD0-4FACF0D03806
$ cd 56A57B07-F67C-4406-9F5C-1541B53654C3/
$ ls
BundleMetadata.plist FoodTracker.app
アプリが出力するファイルのありか
チュートリアルでは、以下のようなコードでmelas
ファイルの出力先を決めています。
定数ArchiveURL
のpath
プロパティによって得られるパスに対して入出力を行なっています。
static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("meals")
このmeals
ファイルのありかは以下でした。find
コマンドとgrep
コマンドを組み合わせて力技で見つけました。
$ pwd
/Users/<ユーザ名>/Library/Developer/CoreSimulator/Devices/3FE92A72-4D7B-4047-A410-626D3D799600/data/Containers
$ find . | grep meals
./Data/Application/7E408B2A-DB42-4997-B10D-9DBA3357EB79/Documents/meals
つまり、urls(for: .documentDirectory, in: .userDomainMask)
で得られるパスは
~/Library/Developer/CoreSimulator/Devices/3FE92A72-4D7B-4047-A410-626D3D799600/data/Containers/Data/Application/7E408B2A-DB42-4997-B10D-9DBA3357EB79/Documents
と対応していました。Data/Application/
以下のGUID様の文字列7E408B2A-DB42-4997-B10D-9DBA3357EB79
は、先述の.app
ファイルが格納されていたディレクトリ名とは関係がないようです。
まとめ
以上の調査から、iOSシミュレータで動かしたアプリが出力したファイルをmacOS上で閲覧するときには
-
~/Library/Developer/CoreSimulator/Devices/device_set.plist
の中を見て、使用したシミュレータに対応するGUIDを特定する。 -
~/Library/Developer/CoreSimulator/Devices/<シミュレータのGUID>/
ディレクトリ以下で、閲覧したいファイル名をfind . | grep <ファイル名>
で検索をかける。
とするのが手っ取り早そうです。