Swiftで他のサービスやアプリとつながるiOSアプリを作成しながら、「アプリの考え方」が習得できる本連載。2回にわたって、ネットワーク上のデータをアプリに読み込んで扱う方法について解説します。実際には、ネットワークのデータを、
- アプリにダウンロード
- ダウンロードしたデータをアプリで使える形に解析
して扱います。
今回は、「アプリにダウンロード」する方法です。
※本連載では、2015年4月時点で最新のXcode 6.3、Swift 1.2で解説します。
データをダウンロードする方式は、大きく分けて2種類あります。「同期ダウンロード」と「非同期ダウンロード」です。
1)同期ダウンロード
同期ダウンロードはデータのダウンロード開始から完了、ダウンロードしたデータの解析と1つのスレッドで順次処理をする方法で、処理中は他の処理はできません。
シンプルな方法で初心者にはわかりやすいのですが、処理完了を待っている間に他の処理ができないため、時間をかけて大量のデータをダウンロードする場合には、効率の悪い方法です。
2)非同期ダウンロード
非同期ダウンロードは、データのダウンロード完了を待たずに別のスレッドで他の処理が可能です。データのダウンロード完了後、完了の合図を受け取り、データを解析します。外部データのダウンロードでは一般的な方法です。
データは「量」があるので、一瞬では送れませんから、分割して送られてきます。受け取り側は「1行目が来た」「2行目が来た」「3行目が来た」「終わりが来た」と順番に送られてくるデータをため込む処理を実行していて、その間を待つのが同期ダウンロード、読み込みは別スレッドに任せて、待たずに次へ進むのが非同期ダウンロードです。
Swiftで試してみよう
データをダウンロードする2つの方式の特徴がわかったところで実際にネット上にあるテキストデータをアプリにダウンロードして、データを表示するプログラムを作ってみましょう。
1.同期ダウンロード
同期ダウンロードは読み込みが完了するまで次の処理へ進めませんが、小さいデータをダウンロードする場合は、非同期ダウンロードのような複雑な処理をするよりも簡単に記述できる利点があります。同期ダウンロードには、Swiftの命令「sendSynchronousRequest」を使います。
1)Xcodeのメニュー「File」→「New」→「Project」から「Single View Application」を選択して、新規プロジェクトを作成しましょう。
2)ダウンロード用のテキストデータ(UTF8)を、Webにアップします。テキストの中身はなんでも構いません。
※サンプルファイル http://editors.ascii.jp/c-minamoto/swift/swift-4-data.txt で代用できます。
3)画面に[Button]と[textView]を配置して、アプリ画面を作ります。
「Main.storyboard」を選択し、右下のライブラリから[Button]と[textView]をドラッグ&ドロップして配置します。 右下の「|△|」ボタンを押して、「Reset to Suggested Constraints(自動レイアウト設定)」を選択します。
「Main.storyboard」の仮画面の中央にボタンを配置しただけでは、縦長のiPhone画面で見るとボタンが端に表示されてしまいます。自動レイアウト設定をすることで、縦長の画面でも中央に表示されます。
4)[textView]に名前をつけてコントロールします。
メニュー「View」→「Assitant Editor」→「Show Assistant Editor」を選択して、「アシスタントエディター」を表示し、キーボードのcontrolを押しながら、[textView]をViewController.swiftへドラッグして、名前を「myTextView」とします。
ViewControll.swiftにコード、
@IBOutlet weak var myTextView: UITextView!
が追加されます。
5)ボタンが押されたときに実行される関数を作ります。
キーボードのcontrolを押しながら「Button」をViewController.swiftへドラッグし、「Connection」を「Action」に切り換えてボタンを押したとき実行する関数を作ります。関数名は「tapBtn」にします。
6)ViewController.swiftに、プログラムを記述します。
ボタンが押されたときにサーバーのデータを同期ダウンロードするプログラムを記述します。
テキストデータのURLを用意して、「sendSynchronousRequest」で同期ダウンロードを実行します。データの読み込み完了の合図が来たら文字データに変換して、「myTextView」に表示します。また、処理の順番を確認するために、「読み込み後の処理」と「次の処理」を実行するところで「println文」を使ってデバッグエリアへテキストを出力します。
記述したプログラムは以下の通りです。
//(中略)
@IBAction func tapBtn(sender: AnyObject) {
// URLリクエストを作る (URLは適宜変更してください)
let url = NSURL(string: "http://editors.ascii.jp/c-minamoto/swift/swift-4-data.txt")!
let request = NSURLRequest(URL : url)
var error: NSError?
// 同期通信を開始
if let resData:NSData = NSURLConnection.sendSynchronousRequest(request,
returningResponse: nil, error: &error){
// データが返ってきたら、文字に変換して表示
let myData = NSString(data:resData, encoding: NSUTF8StringEncoding) as! String
myTextView.text = myData
println("読み込み後の処理")
}
println("次の処理")
}
//(中略)
ボタンを押すと、データが読み込まれ、[textView]にテキストデータが表示されます。
Xcodeの下に表示されているデバッグエリアを確認してみましょう。「読み込み後の処理」が先に表示されて、その後「次の処理」が実行されたことがわかります。
同期ダウンロードは、順次処理を実行していることがわかります。