Swift学習・Xcode使い方入門|iOSアプリ開発初心者が最初に知りたかったのはこれ

Pocket

はじめに

iOSアプリの開発をSwiftで行う日々が1ヶ月程経過したので、初めて開発を行う前にこれは誰かに教えてもらいたかった、という内容をまとめます。実際に進める中で躓いた点ばかりなので、同じように新しくiOSアプリ開発を進める方の役に立てれば、と思っています。

対象としている方

僕はもともとweb系の開発の知識は少しはあったので、プログラミング言語やwebサービスの構成、データベースの使い方などは少しは分かってきています。そんな感じの知識レベルの方で、新しくiOSアプリを開発しようという方に有用なまとめになるように書こうと思います。

逆に、
・プログラミングの勉強から初めて
・iOSではなくアンドロイドアプリを作ろうと思っている
・iOSでもアンドロイドアプリでもなくハイブリッドアプリを作ろうと思っている
といった方にはイメージと異なる内容になってしまうと思います。また、
・iOSアプリを作るんだけど言語はObjectiv-Cを使う
という方は、言語は関係の無いXcodeの使い方の部分のみ参考にしてもらえると思います。

iOSアプリ開発の難しい点

iOSアプリを開発する際に新しく理解しないといけない概念がいくつもありました。

Xcodeの使い方

iOSアプリの開発には統合開発基盤であるXcodeというツールが必須です。新しいツールを使うときはまあ使い慣れないのは当たり前ですが、Xcodeは結構開いておくウィジェットというかエリアが多いので、どのエリアを開いておくと楽だ、みたいなものを紹介します。

画面を定義するstoryboard

web系の開発では無い概念として大きいのは、画面にどんな部品(ボタンとか画像とか)を配置するかを、storyboardというファイルで定義するという点です。

スクリーンショット 2016-04-15 00.29.41

このようにページや部品を視覚的に配置することができるのですが、配置するときのルール(制約:constraint)や、部品と操作を紐付けるやり方、storyboard間の移動などはwebの開発とは全然違う考え方でした。

それぞれの部品の特徴

storyboardに配置する部品には、
・ページ
・ボタン
・画像
・ラベル(文字列の貼り付け)
・フォーム(文字列の入力欄)
・枠(webで言うdivみたいな)
・テーブル
などなど色々なものがあり、それぞれの部品の挙動はclassで定義されています。そして、これらそれぞれの部品(つまりclass)の持つ特徴や機能を理解しながら開発を進めます。ただ、この部分は結構枝葉の部分なのでネットで情報を探すと結構出てきますし、なんとなくコピペで動く領域という印象です。

アプリを動かすbuild

さらに、これらを構築する上でXcodeの使い方とiOSアプリの規約は最初は難しく、四苦八苦しました。特にシュミレーター(XcodeにはデフォルトでiPhoneやiPadのシュミレーターがついていて、macの画面上で作ったアプリの操作ができる)でアプリを動かすときの設定(build setting)画面は途方も無く設定項目が多く、アプリ立ち上げ(build)がうまくいかない理由がどこにあるのか、勘所の無い初心者には高すぎる壁でした。1からアプリを作っていく、という時はあまり意識する必要はありませんが、githubから落としてきたソースを動かしたいなど、既存のアプリをスタートにする時は色々な理由からアプリ立ち上げ(build)うまくいかないことが往々にして発生します。

情報が無い

Swiftは新しい言語かつappleがどんどんバージョンアップを進めているため、ネット上に欲しい情報があまりありませんでした。少し突っ込んだ内容になると日本語では見つからなくなってしまうため、英語で探すことになるのですが、英語だとStackOverflowに行き着くことが多いです。その場合、場当たり的な対処はそこにある情報でなんとかなるんですが、全体的な概念みたいなものの理解は徐々に形成していくしか無いように感じます。

Swiftに対し、Objective-Cは伝統的というか昔から使われている言語なのでけっこう情報があります。最初はSwiftとObjective-Cの違いも全くわからなかったので、Objective-Cで書かれたソースコードを貼り付けて、全然動かない、というアホなミスで随分時間をかけたりしてしまいました。印象としては2014年の終わり以降のものならSwiftの情報に行き着くことができるという感じです。

この記事では上記のような概念の理解が大変だった点を中心にお伝えしたいと思います。




統合開発ツール:Xcode

ここではiOSアプリ開発に必要なXcodeの使い方について書きます。Xcodeは高機能なのですが、高機能故に最初使い方がわかりにくかったりします。なお、Xcodeのインストールには5時間とか平気でかかるので、新しくXcodeをmacにインストールするという方は今夜就寝時にでもインストール作業を進めることをおすすめします。

基本的なエリア

まずはXcodeの基本的な各エリアの用途と呼び出し方を記載します。Xcodeをいろいろいじっているとパネルが隠れちゃったりするんですが、隠れたエリアを呼び出すのに少し焦りました。それぞれのパネルはこのような感じで表示されます。

xcode

それぞれどのようなエリアなのかは下記の通りで、かっこの中はエリアの呼出し方です。

①ツールバー( View > ShowToolbar )
アプリを実行するボタンやエラーや警告があれば、それがあることを教えてくれます。
ツールバーには右上に各エリアを出したり隠したりするボタンがあります。

スクリーンショット 2016-04-15 01.06.26

こんなやつです。それぞれ下記で説明するエリアの表示非表示ができます。

②ナビゲーターエリア( View > Navigators > Show Project Navigator )
作っているアプリのファイルの構成を示し、ここから選択したファイルが次のエディタエリアに表示されます。

③エディタエリア( デフォルトで表示されています )
選択したファイルを編集するためのエリアです。ここでは選択したファイルの形式に合わせてエディタの種類が変わります。この画像ではstoryboardを選択しているため画面構成を視覚的に編集できるようなエディタが表示されていますが、.Swiftという拡張子がついたSwiftファイルの場合は通常のテキストエディタのような画面になります。

④デバッグエリア( View > Debug Area > Show Debug Area )
①のツールバーで実行ボタンを押すと選択されているTARGETが実行されます。そして、実行時のデバッグメッセージがこちらに表示されます。

⑤ユーティリティエリア( View > Utilities > Show File Inspector)
アプリ開発で使用する部品の設定ができます。基本的にsrotyboardを編集するときに活用するエリアです。

よくやる便利な使い方:検索

段々プログラムが大きくなってくると、あの時書いたあれってどんなのだっけ、と過去の記載を見たくなることが増えてきます。そんな時は②ナビゲーターエリアにあるプロジェクト横断検索の機能が結構使えます。

スクリーンショット 2016-04-16 21.52.12

こんな感じで該当する検索結果が一覧で表示されます。

よくやる便利な使い方:アシスタントエディタ

③エディタエリアを2つに分割出来る機能です。これはそもそもstoryboardを活用する時にはほぼ必須なんですが、Swiftファイルをごりごり書く時なんかにも結構使えます。アシスタントエディタの出し方は View > Assistant Editor > View Assistant Editor です。

スクリーンショット 2016-04-16 21.58.21

よくやる便利な使い方:編集するファイルの選択

ファイルが増えてくると、編集したいファイルをエディタに呼び出すのも段々大変になってきたりします。毎回②ナビゲーターエリアから選択しても良いんですが、いくつか早く呼び出せる方法があります。

エディタには左上に戻るボタンと進むボタン、そして最近開いたファイルから選択するというボタンがあります。ここから選択すると、すぐにお目当てのファイルにたどり着くことができます。

スクリーンショット 2016-04-16 22.01.07




画面を作る:srotyboard

iOSアプリを開発する上で最初特にとっつきにくいのが、スマホ上の画面をつかさどるstoryboardというファイル(というか概念)です。webならボタンやテーブルなど各パーツの配置はhtmlファイル、見た目はcssファイル、動きはjavascriptファイルにそれぞれ記載して全部ひっくるめてサイトが出来上がりますが、iOSアプリでは基本的にこのstoryboardでアプリのページを作っていきます。

直感的に部品を配置したりページとページとひも付けたり(segueという線みたいなものでひも付けます)という作業を進めるので、慣れると直感的に出来るようになるので良いんですが、はじめのうちは複雑なもんであんまりうまく行きません。そのあたりの概念や具体的な操作方法をご紹介しようと思います。

『storyboard > 画面 > 部品』という関係

まず、storyboardは複数の画面をまとめたものなので一つのstoryboardファイルの中にはいくつも画面を配置することができます。画面同士はsegueという線を引くことで、遷移先の画面を当てはめたり、遷移の時のアニメーション(横からニュッと出すとかモーダルで出すとか)を指定することができます。ちなみにこの線(segue)は、右クリックを押したままドラッグで引くことができます。そして、それら画面の中にさらに部品を配置する、という構造になっています。

しかし、作業が進み画面が増えてくると、その分storyboardも肥大化していき、編集するのが大変になっていきます。イメージ的には下記の画像のような感じになります。

スクリーンショット 2016-04-17 01.19.46

そのような場合は、storyboardを分けることができます。例えば画像投稿型のアプリなら、
・写真を見るような画面は全て一つのstoryboardに
・写真を撮ったり投稿したり、確認する画面は全て一つのstoryboardに
・設定画面は全て一つのstoryboardに
という風に機能で画面を小分けにすることで、規模が大きくなっても構造的に進められるようになっています。

ただ、その場合に他のstoryboardにある画面に遷移したいことが出てきます。そういった時に意識して頂きたい点をご紹介します。

storyboard間の画面遷移

storyboard間の画面遷移は、プログラムで挙動を規定する必要があります。後述しますが、storyboardに配置した画面にはcontrollerという種類のクラスが割り当てられ、そのクラスの中に『このページの次はこのstoryboarのこのページに遷移する』といった内容のことを記述します。遷移の仕方は次の画面のオブジェクトを生成して、そこに飛ばすというイメージです。同じ/異なるStoryboardでの画面遷移このサイトなどを見て頂ければわかると思いますが、次のページをどう指定するかが意外と複雑です。

まず、storyboardにはデフォルトで一番最初に表示する画面が指定されています。画面にはIs Initial View Controllerという属性があり、これをオンにすることで、その画面が、所属するstoryboardで最初に出てくる画面ですということを明示する事ができます。この属性の設定方法が難しいので、画像を貼っておきます。

IsInitial

こんな感じです。

Initialに設定されていない画面を選択する場合は、StoryboardIDという属性に任意のIDを与え、プログラム中でそのIDを指定することで対象の画面に遷移することができます。このStoryboardIDはこのような感じで選びます。

Storyboard

これらの設定やらID指定やらは全てユーティリティエリアで行っています。このエリアはそういったページや部品それぞれの様々な設定をするところなのですが、ユーティリティエリアも勘所みたいなものがあるので、ご少し紹介します。

ユーティリティエリアの勘所

ユーティリティエリアで部品の設定を施すものは6つの要素で成り立っていますが、このうち使うのは基本的に下記の4つです。

①アイデンティティーインスペクター

スクリーンショット 2016-04-17 02.07.54

ここでは、クラス(その画面や部品の挙動を定義したもの)をひも付けたり、先ほどのStoryboardIDを指定します。

②アトリビューツインスペクター

スクリーンショット 2016-04-17 02.08.17

ここは基本的に部品の見た目を変えるときにいじるエリアです。色や背景・文字の大きさ・フォント・画像などを変えたいと思ったらとりあえずここをいろいろ変えてみます。

③サイズインスペクター

スクリーンショット 2016-04-17 02.09.07

これはstoryboardを編集するときにのみ反映される画面の大きさです。buildしてシミュレーターなどで実行してもここの数字は反映されません。ここの数字を実際のスマホやタブレットと同じ大きさに指定してあげると、画面を作る作業がとても楽になります。

④コネクションズインスペクター

スクリーンショット 2016-04-17 02.09.31

画面や部品がほかのどの画面や部品と紐付いているか、もしくはどのクラスファイルのどこで挙動が定義されているか、などを見ることができます。ここはけっこうやっかいな部分なので、後の部分でご紹介します。

以上の4つのインスペクターの役割をイメージしながら作業をすすめると、壁にぶつかったときになんとか打開しやすくなります。

制約(constraint)とは

iOSアプリには制約(constraint)という、画面上での部品感の距離感や関係性を決めることができる機構があります。storyboardにはAutoLayoutという属性があり、これをOnにすると、制約に基づいて画面が作られます。iPhoneには色々な画面サイズの機種がありますが、制約をうまく使うことでこういったマルチデバイスに対応したり、画面が横向きになっても見た目を崩さないといったことができるのです。

制約には色々あり、例えば
・部品の高さや長さを固定のものにする
・部品の縦と横の長さの比を固定する
・部品Aと部品Bの距離を固定にする
・部品Aと部品Bの一番上のラインを同じ座標にする
といったことを指定できます。

ですがこの制約、慣れないうちかなり使うのが難しいです。

制約を付けられる範囲

まず制約は同じ階層にある部品同士もしくは自分がいる階層に対してしかつけることはできません。といっても文字だけだと伝わりにくいと思うので、こんなイメージで説明します。

screen

画面にViewが2つあり、2つめのViewにはButtonとLabelが配置されているとすると、それぞれの部品が制約を追加出来る相手はそれぞれ下記です。
View①:画面とView②
View②:画面とView①
Button:View②とLabel
Label:View②とButton
このような形で、制約を追加する部品は、同じ階層、つまり部品を囲むViewもしくは同じ階層にある部品に対してしか制約をつけることができません。この場合、ButtonやLabelがView①や画面に対して制約を指定できないのです。(自分自身の高さや横の長さを固定することは可能です)

制約の付け方

実際に制約を付ける作業はエディタエリアの右下にあるボタンから行います。

スクリーンショット 2016-04-17 03.36.16

こちらは、Alignment Constraintsといって、画面や他の部品との関係性を規定するもので、画面と中心を合わせたり、他の部品の一番上のラインと合わせたりします。

スクリーンショット 2016-04-17 03.36.37

続いてが(通常の)Constraintsで、各辺の長さや部品間の距離を数値で指定するものです。
ここで、対象となる部品の候補が幾つもある場合の選択の方法がとてもわかりにくいのですが、

スクリーンショット 2016-04-17 03.42.49

このように数字の横にある小さな三角を押すと候補が出てきます。
これは本当最初全然やり方が分からず、途方にくれましたとほほ。。

制約の考え方

制約はいくつかつけてみるとすぐに分かりますが、完全なものでないとすぐにエラーを吐き出します。一つ欠けるだけでもダメなので、結構努力して作り上げた画面イメージを少し修正するだけでも、例えば制約を一つ削除するとまたたくまにエラーが大量発生します。

制約をつける上で僕が意識しているのは、部品の4つの要素が明確になっているか?ということです。その4つの要素とは、
・x座標
・y座標
・縦の長さ
・横の長さ
です。もし部品のどれかひとつでもこの要素の『どれかが欠けている』もしくは『矛盾してしまっている』場合にはエラーになります。

よくあるのは、同じ部品の同じ要素(縦の高さなど)に複数の矛盾する制約をつけてしまう、もしくは複数の部品毎の距離を制約で指定して、その一つが欠けてそれ以外の制約が効果を失ってしまう、といった原因で発生するエラーです。4つの要素のどれかが無いと、部品はどこに存在すればいいかわからなくなってしまうので、画面では変な所に飛ばされてしまったりします。




画面や部品をプログラムで制御する:class

さて、画面が出来上がると、次は細かな処理をプログラムで書いていく事になります。ここでは画面や部品に対してclassを割当て、そのクラスの中に挙動を定義します。classを割り当ててたりその中の部品に挙動を与える方法の流れをご紹介します。

クラスのひも付け方

ちなみに、ここでサンプルとして作った画面は先程のView①、View②、Button、Labelを使って説明した例をstoryboardで作った形になってます。

まず、 View > Assistant Editor > View Assistant Editor でアシスタントエディタを表示させて紐付けたいViewControllermクラスを表示させています。クラスのひも付け方は先程もご紹介したユーティリティエリアで選択します。

スクリーンショット 2016-04-17 11.44.08

こんな感じで、ドロップダウンを開くと紐付けられるクラスの一覧が出てきて、そこから選択できるようになっています。ここで画面にクラスを紐付けないと、この次の部品とクラスのひも付けができないので、注意してください。

部品とクラスのひも付けに進みます。ここではButtonをひも付けます(右クリックを押したままドラッグアンドドロップ)

スクリーンショット 2016-04-17 11.46.39

紐付けると、ウィジェットみたいなものが現れ、Outletとして紐付けるか、Actionとして紐付けるかを選択できます。この2つですが、
・Outlet:部品そのものをオブジェクトとして使えるように紐付ける
・Action:その部品が何らかのイベントを起こした時に発動する関数として紐付ける
という意味をそれぞれ持っています。
例えば部品の色とか(ユーティリティエリアで設定しなくてもプログラムで装飾できます)を変える場合はOutletとして、タップされた時に何かしらの処理(何か情報を読み取るとか次のページに遷移するとか)を与えるときにはActionとしてひも付けてあげるのが良いです。

スクリーンショット 2016-04-17 11.47.13

Outletとして紐付ける場合、部品の名前を定義してあげると

スクリーンショット 2016-04-17 11.47.51

このように、クラスのメンバーとしてオブジェクトが出来上がります。

続いてActionとして紐付ける場合ですが、こちらも同様に右クリックで線を引っ張り、

スクリーンショット 2016-04-17 11.48.12

ウィジェットでActionを選択し、

スクリーンショット 2016-04-17 11.48.42

関数名を定義してあげると、

スクリーンショット 2016-04-17 11.49.11

関数が出来上がります。

ひも付け周りで発生しやすいエラー

ひも付けに関係するところでよく出てくるエラーに、’NSUnknownKeyException’というものがあります。これは知らないキーがあるよ、と行っているのですが、ひも付け情報は残っているが、ひも付けた対象がなくなっている時に発生します。試しにさっきのサンプルでひも付けたButtonをクラスファイル内でコメントアウトして実行してみます。すると、

2016-04-17 14:00:03.321 test[40945:3436143] *** Terminating app due to uncaught exception ‘NSUnknownKeyException’, reason: ‘[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key button.’
*** First throw call stack:

というエラーが出てきて、アプリケーションが強制ストップさせられます。
これは、storyboard上のButtonにはクラスに紐付けられた情報があるのに、肝心のクラスには無くなっている(コメントアウトしたので)ため、エラーが出ているということです。

最初のうちはひも付けがうまく行かなくて色々消したりするのですが、その弊害として生まれるこのエラーによく悩まされます。

外部ライブラリをインストール:cocoapods

ここまででiOSアプリを開発するときに困ることは大体ご説明できたと思います。ここではより本格的なアプリを作るための外部ライブラリの使い方のイメージを簡単にご紹介します。

iOSにはcocoapodsというライブラリ管理ツールがあります。JavaでいうMaven、rubyでいうGemみたいなものです。

この使い方の流れは、PodfileというテキストファイルをiOSアプリを開発しているプロジェクトの中に用意し、Podfileの中に使いたいライブラリの名前を書いておきます。そしてターミナルでコマンド打つとあとはこのツールが該当するライブラリを外部からインストールしてくれるという流れです。

具体的な使い方は、他の記事にお任せします。iOSライブラリ管理ツール「CocoaPods」の使用方法詳しくはこちらなどを見てください。

以上、僕がiOSアプリを開発する前に知っておきたかったことのまとめです。各部品の使い方など細かい部分は調べれば結構出てきたので余り問題にはならなかったのですが、Webとはまた別の概念みたいなところは理解するのにそれなりに時間がかかったので、これからXcodeやSwiftを使う方の手助けになれば嬉しい限りです。

Pocket

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>