Edited at

【iOS】アプリケーションバンドルのデータを取得する


この記事の概要

iOSアプリに必要なリソースファイル(プロパティリストやJSONファイル)を、プログラムから扱う時の準備及び手続きをいつも忘れてしまうので、基本的な事項ではあるけど記事にまとめておきました。

要は、XcodeプロジェクトにあるファイルをViewControllerクラスのプロパティに格納するまでの作業です。

Swift3になって、データ型の名前やプロパティ名も変更があったようなのでちょうどいい機会かとも思います。


環境

Xcode8 ~

Swift3 ~

iOS10 ~


準備


  1. iOS系テンプレートで適当なプロジェクトを作成。

  2. 「メニュー > File > New > File... > Resource > GeoJSON File」を選択。

  3. ここでは、「data」というファイル名にしてます。


手順

自分でも不思議なくらい毎回のごとく手順があやふやなので、一旦整理。

以下の処理をgetData()->Any?メソッドなんかを定義しておいて、'viewWillAppear(_:)メソッド'なんかで実行したりする。

1. パスを取得

2. URLを生成

3. Dataインスタンスを生成


パスを取得する


パス取得

func getData() -> Data? {

guard let path = Bundle.main.path(forResource: "data", ofType: "geojson") else { return nil }
}


バンドルは、アプリケーションをビルドした後もパッケージ化されているリソースの保存領域のこと。

パスを記述しなくても、ファイル名を指定すればバンドル内を検索してパスを生成してくれる。

生成されたパスはString?型になっている。

Guard-Let構文にしておけば、パスを生成できなかったときに対策できる。


URLに変換する


パス取得>URL生成

func getData() -> Data? {

guard let path = Bundle.main.path(forResource: "data", ofType: "geojson") else { return nil }

let url = URL(fileURLWithPath: path)
}


pathには、ファイルパスがString型の文字列として格納されている。

構造体URL型のイニシャライザを使って、URLを生成してurlに代入。

URL型のurlオブジェクトを得ている。


データのインスタンスを得る


パス取得>URL生成>>データ

func getData() -> Data? {

guard let path = Bundle.main.path(forResource: "data", ofType: "geojson") else { return nil }

let url = URL(fileURLWithPath: path)

guard let data = try? Data(contentsOf: url) else { return nil }

return data
}


構造体Data型のイニシャライザを使って、dataオブジェクトを生成している。

パスが間違っていたりして、生成できなかった時のためにGuard-Let構文を使っている。

dataオブジェクトはAny型になっている。

このdataオブジェクトをJSONSerializationクラスなどを使って、解析することになる。


呼び出し


viewController.swift

override func viewWillAppear(_ animated: Bool) {

super.viewWillAppear(animated)

let data = getData()
print(data)
}


どこでも必要なタイミングで呼び出せばいいかと思います。

今回の内容ではJSONなどに解析はしていないので、解析後のDictionaryなどはメンバワイズプロパティに持っておくと、いろんなところからアクセスできて便利なんだろうと思います。


自分へ

忘れるな。

そして、覚えろ。