2015年7月16日木曜日

UIDatePickerと画面制御 [Swift]

日付を設定するため、UIDatePickerを使った実装をしていきます。

仕様は以下のようにします。

  • 日付をテキスト表示したボタンを設置する。
  • そのボタンを選択すると、日付選択用のDatePickerが表示される。
  • DatePickerの値を変更すると、ボタンの日付テキストが更新される。
  • DatePicker以外の場所を選択すると、DatePickerが非表示になる。

日付テキストのボタンを設置

日付テキストボタンを宣言します。
storyboardでNavigationBarの真ん中にボタンを設置して、宣言と繋げます。

ボタン選択時にDatePickerを表示

続いてDatePickerを宣言します。
storyboardで画面下部にDatePickerを設置して、hiddenにします。
そしてボタン選択時に表示するように実装します。
確認してみると問題が、、DatePickerが透明なため背景と同化して見づらい。。。
ということで、DatePicker下に背景色付きで画面サイズのボタンを設置することにしました。
最初はDatePickerに背景色をつけよう。と思ったのですが、DatePicker表示中は画面制御したいことと、非表示にする時のことを考えるとね。
これでDatePickerが見やすくなったし、DatePicker以外の場所をタップすると非表示になりました!
画面構成は下記画像のようになります。

DatePickerの値変更を適用

DatePickerのvalueChangedで、ボタンの日付テキストに値を適用する処理を実装します。
ついでに、NSDateのフォーマット処理をメソッド化します。初期値設定時などにも使いそうなので。
以上で日付が設定処理は終わりです。

おまけ:テキストの編集処理

おまけで、同じ画面にテキスト編集の処理も実装します。
なぜここに書くかというと、DatePickerの非表示処理を使ってキーボードも閉じちゃおうという魂胆だからです。

まずはTextViewを宣言します。
そしてTextViewにフォーカスが当たった時に、画面を制御する例のボタン(背景色付きで画面サイズのボタン)を表示してあげます。
例のボタンをタップするとキーボードも閉じるようにします。
補足ですが、キーボードが出てるとDatePickerが隠れて見えなかったので、日付設定ボタンも制御しました。
これでテキスト編集中の画面制御とキーボード閉じる処理が実装できました。
お疲れ様でしたー。

2015年7月13日月曜日

カスタムセルクラスの作成 [Swift]

今回はTableViewのレイアウトを修正します。
主な作業としては以下になります。
  • カスタムセルクラスの作成
  • Main.storyboardにカスタムセルの適用
  • セルのレイアウト

カスタムセルクラスの作成

まずはファイル作成です。
  1. File を選択
  2. New を選択
  3. File... を選択
  4. iOS Source の Cocoa Touch Class を選択
  5. Class: ArticleTableViewCell と入力
  6. Subclass of: UITableViewCell を選択
  7. Also create XIB file: チェックなしのまま
  8. Language: Swift を選択
  9. Next を選択
  10. 他のクラスファイルと同じディレクトリを選択
  11. Create を選択
これで "ArticleTableViewCell" クラスが作成できました。

次にラベル等の部品用に、IBOutletを定義します。
今回定義したのは3つ。
  • dateLbl: 日付用のLabel
  • textLbl: テキスト用のLabel
  • photoImgView: 写真用のImageView

Main.storyboardにカスタムセルの適用

まずはMain.Storyboardを開きます。

Main.Storyboardの画面サイズ設定
最初は、各画面がiPadのようなサイズになっています。
レイアウトするときにイメージしずらいので、iPhoneサイズにしました。
やり方は、ベースになるSplitViewControllerを選択して、Simulated MetricsのSizeで "iPhone 4.7-inch" を選択すると、画面がiPhoneサイズに変わります。


次に定義した3つの部品を配置していく...が、問題発生。
テンプレートで作成したTableViewCellには、始めからLabelが載っていたのだが、そのLabelの位置変更やサイズ調整が効かない、、削除することもできない。。。テンプレートの呪いですね。

そこで思い切ってTableViewCellごと削除して、新たに自分でTableViewCellを追加することにしました。
Cellを新しくすることで、Identifierと詳細画面の遷移が消えてしまうので、追加後元に戻すことに注意します。

これで自由に部品を設置できるようになりました!
引き続きカスタムセルの適用をやっていきます。

今度こそ3つの部品を配置して、画面とクラスを紐付けていきます。

まずは部品をいい感じに配置します。
そしてCellのCustom ClassのClassに、先程作成した "ArticleTableViewCell" を設定します。
そうすると、画面とクラスが紐付きます。

今度はOutletsで、先程定義した3部品を紐付けます。

後は、MasterViewController.swiftに3部品の処理を実装していきます。

実装は UITableViewCell → ArticleTableViewCell に変えていくのと、部品にダミーデータを設定することです。
修正箇所は以下の3メソッドになります。


セルのレイアウト

最後にレイアウトの調整ですね。
Main.Storyboardの部品に、実際にテキストや画像を設定しながらやると調整しやすいです。
実機で確認すると、より雰囲気が掴めて楽しいです。
まあ今の段階ではFixせず、ある程度で良いと思います。
実装している内に変更点がいっぱい出てくるので、今はあまり時間を掛けずに実装の終盤でレイアウトを見直します。

Could not find Developer Disk Image [Xcode7.0 beta]

開発中のプロジェクトを実機で実行しようとしたら、"Could not find Developer Disk Image" とエラーが出て実機確認できず。。。



原因は、テスト端末にiOS8.4を使用しており、その環境がXcode-betaに入っていないからでした。
解決するには、自分のPCに入っているXcodeからiOS8.4の環境をコピーしてきて、Xcode-betaを再起動すると動きました!

Xcodeのパス
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/8.4 (12H141)

Xcode-betaのパス
/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/ここにコピー

※ Xcodeに8.4の環境が入っていない場合は、Xcodeのアップデートをお試し下さい。

2015年7月12日日曜日

続・テンプレートプロジェクトの作成 [Swift]

前回 "Master-Detail Application" のテンプレートプロジェクトを作成して、自動で生成された.swiftファイルの処理を確認することにしました。
AppDelegate.swiftの確認が終わったので次いきます。

MasterViewController.swift

MasterViewController.swiftは、このアプリのトップ画面です。
TableViewに、CoreDataの情報をリスト表示する処理が入っています。


DetailViewController.swift

DetailViewController.swiftは、MasterViewのリストを選択した時に遷移する詳細画面です。
リストから選択された情報を、詳細画面に表示する処理が入っています。

知らなかった構文をチェック

◆ willSet / didSet
(変数宣言 { willSet{ 〜 } didSet{ 〜 } })
プロパティの設定前にwillSet、設定後にdidSetのプロック内が処理されます。
willSetブロック内では、newValueという変数でこれから設定される値を参照できます。
didSetブロック内では、oldValueという変数で設定される前の値を参照できます。
設定する値に手を加えたり、このタイミングで何か処理したい場合に使えそうです。

以上で.swiftの3ファイル全ての確認が終わり、ある程度構成が理解できたのと同時に、swiftコードを読むのに慣れてきました。
.swift以外では、.storyboardで画面構成を、.xcdatamodeldでデータ構成を確認します。

テンプレートの確認はここでおしまいにして、次からは実際に実装していきます。

2015年7月9日木曜日

テンプレートプロジェクトの作成 [Swift2]

前回計画した通り、いいこと日記を実装していきます。
まずはプロジェクトの作成です。

プロジェクトの作成

Xcodeを起動して、以下の手順を実施していきます。(Ver7.0Betaを使用)
  1. Create a new Xcode project を選択
  2. Master-Detail Application を選択
    (SplitViewControllerとNavigationControllerとTableViewで、一覧画面と詳細画面を構成してくれるテンプレート)
  3. Next を選択
  4. Product Name: GoodThingsDiary と入力
  5. Language: Swift を選択
  6. Devices: iPhone を選択
  7. Use Core Data: チェックを入れる
    (CoreDataのテンプレート処理が入る)
  8. Include Unit Tests: チェックを入れる
  9. Include UI Tests: チェックを入れる
  10. Next を選択
これで "GoodThingsDiary" プロジェクトが出来上がります。
念のため、シミュレータで実行してテンプレートの動きを確認します!

次に、テンプレートにより実装されている処理を.swiftファイルを見て確認していきます。

AppDelegate.swift

AppDelegate.swiftは、どのプロジェクトでも必ず自動で作成されます。
アプリの起動・中断・終了時などに呼ばれるメソッドなどが含まれています。
今回はテンプレートによりCoreDataの処理も入っています。

知らなかった構文をチェック

◆lazy
(lazy 変数宣言)
その値が参照される時まで、インスタンス化されなくなる。
◆guard else
(guard 変数宣言 = 条件 〜 else { return })
else前の条件がnilの場合はelseに入り、そうでない場合は宣言した変数に値が入ります。
else後のブロック内にはreturnが必須。

◆as
(変数宣言 = 変数 as 型)
as前の変数を、as後の型にダウンキャストして、宣言した変数に入れます。
as?の場合、ダウンキャストに失敗した場合はnilが返ります。
as!の場合はエラーになります。

◆is
(Bool 変数 = 変数 is 型)
is前の変数が、is後の型かチェックします。

◆do try catch
(do { try 〜 } catch { 〜 })
doブロック内で、tryをつけてthrowsするメソッドを呼び出します。
throwされた場合には、catchブロック内でエラーハンドリングできます。
※ doブロック内にdeferブロックを記述すると、doブロックの最終処理として実施してくれます。

まだ他にファイルはありますが、今回はここまで。
おつかれにゃんこ。

2015年7月8日水曜日

iOSアプリの企画から設計まで

Swiftの基本的な書き方を学んだので、ここからはアプリを作成しながら必要な技術を学んでいこうと思います。

どんなアプリを作成するか??
まずはサーバを必要としない、アプリ内で完結するシンプルな作りにします。

スマフォのアプリ開発は小規模な場合が多いです。
企画〜設計〜実装〜リリースまで1人でこなせて1人前ですね。
自分の作品が出来上がるのを楽しみに、頑張るぞ。

まずは計画を立ててみました。
これでざっくり全体像を把握することができます。


◆アプリ名(仮)
いいこと日記

◆サービス概要
いいことだけを書く日記アプリ

◆アプリの狙い
  • 毎日の良くないことより、良かったことだけに目を向けて記録したい。
    =ポジティブシンキング!
  • 寝る前に良いことを考えて、体をリラックスさせてよく眠りたい。
  • 気持よく何度でも読み返したくなる日記にしたい。
  • たまには友達に良いことをシェアして、友達とも共感したい。
  • 無理せず自分のタイミングやペースで日記をつけたい。

◆類似アプリとの差別化
  • 日々のいいことだけに焦点を当てる。
  • 明るく軽いイメージのデザイン。(オシャレカフェ風)
  • キラっと輝く演出を入れる。
  • 文字数を制限することで簡易的な日記にする。
  • 1日に何件も書けるようにして、いいことの書き漏れなし。


進め方

  • 機能を考える
  • データ設計
  • 画面設計
  • 実装計画


1. 機能を考える

  • 日記が書ける
  • 日記を見返せる
  • 日記をシェアできる
  • 日記のプライバシーを守る
上記をもっと細かく考えていく...


◆日記が書ける
  • 1日何回でもその日あったいいことを書ける。
  • 最大文字数はTwitterと同じく140文字。気軽に書けるように。
  • あとから日記の編集・削除ができる。
  • 画像を1枚ずつ設定できる。多すぎても見ないし重くなるからベストショットを。
  • 設定する画像サイズはそのままで。
  • 毎日決まった時間に通知できるようにする。デフォルトOFF。

◆日記を見返せる
  • 日記を一覧から参照できる。
  • 日記の編集や削除ができる。
  • 日記一覧をパラパラ流し見できるようにする。
  • 日記一覧は月ごとにまとめる。見たい日記を探しやすくするため。
  • 一覧から画像を見えるようにする。その方が華やかだし楽しそうだから。
  • 一覧から内容も見えるようにする。

◆日記をシェアできる
  • 日記の参照画面からTwitter・FBに投稿できるようにする。画像も。

◆日記のセキュリティ
  • パスコードを設定できるようにする。スリープ復帰時も。
  • バックグラウンドにある場合はダミー画像を表示。


2. データ設計

Diary
  • article: String
  • photo: String
  • happened_at: Date
  • updated_at: Date

Setting
  • notification: Bool
  • write_time: Date
  • pass_lock: Bool


3. 画面設計

まずは必要な画面と機能を書き出す。
  • 日記一覧画面:Top
    (日記一覧、日記追加ボタン)
  • 日記編集画面:一覧から遷移
    (日付設定、テキスト編集、画像設定、保存ボタン)
  • 日記参照画面:一覧から遷移
    (編集ボタン、削除ボタン、Tweetボタン、FBボタン)
  • 設定画面:一覧から遷移
    (通知設定、パスコード設定)
  • パスコード入力画面:Topにモーダル
    (パスコード入力)
次に上記を踏まえて、ノートに画面をデザインする。


4. 実装計画

  • 日記一覧画面を作成
    日記一覧をダミーデータで作成(TableView)
    日記追加ボタンの設置(Button)
  • 日記編集画面を作成
    一覧の追加ボタンから画面遷移(Segue)
    日付設定(Button, DatePicker)
    テキスト編集(TextView)
    画像設定(Image, ImagePicker)
    保存処理(CoreDataに保存)
    編集キャンセル確認処理の実装(AlertView)
  • 日記一覧画面に保存したデータを表示(CoreDataから読み出し)
  • 日記参照画面を作成
    日記編集画面を参照モードにできるように修正(Segue)
    各部品を参照モード対応(Button, TextView, ImageView)
    編集ボタンの設置と実装(Button, Segue)
    削除ボタンの設置と実装(Button, AlertView)
    Tweetボタンの設置と実装(Button, Twitter)
    FBボタンの設置と実装(Button, Facebook)
  • 設定画面を作成
    各部品配置(Switch, TimePicker)
    設定値を保存(NSUserDefaults)
    通知設定(LocalPushNotification)
  • パスコード入力画面を作成
    TouchID認証
  • その他
    スプラッシュ画面
    アプリのアイコン
    バックグラウンドにある場合のダミー画像表示
    データの暗号化
    保存データが増えた場合の挙動
    端末容量オーバー時の挙動
    オフライン時の挙動
    キラっとした演出の追加
    デザインのブラッシュアップ
    バックグラウンドやアプリを落とした時などの挙動
    テストコード

次回から実装していくぞ。

2015年7月6日月曜日

Swiftでクラスや関数の書き方

Swiftでは、クラスファイルが.swiftの1つになりました。
基本的な書き方は以下のようになります。

別クラスにあるメソッドの呼び出し方

同じプロジェクト内であれば、import定義せずに別クラスのメソッドを気軽に呼び出せます。

関数の書き方

引数や戻り値がある場合の書き方を、様々なバリエーションで紹介していきます。

◆引数あり、戻り値あり
◆引数複数あり、戻り値複数あり
◆引数複数あり(ラベルあり)、戻り値複数あり(ラベルあり)
◆引数あり(デフォルト値あり)、戻り値あり
◆引数複数あり(可変)

どれも分かり易く書けますね。
他にも必要そうなものがあれば追記していきたいと思います。

2015年7月4日土曜日

SwiftのOptional型とは(Optional Value/Optional Type)

Swiftでは、String型などの変数にnilを設定できなくなりました。
Objective-Cから移行してきた人には一見不便に感じますが、nilアクセスによるクラッシュが防げるようになり、プログラムの安全性は上がったと言われています。

とはいえ、nilを設定したい場合もありますよね?
そんな時に使うのがOptional型です。
String型などをOptional型にラップすることで、nilを設定できるようになります。

Optional型の宣言方法

書き方としては、変数の型の後ろに"?"や"!"をつけて宣言します。
String型などをOptional型にラップするので、型指定は必須です。

Optional?はシンタックスシュガーである

要するにString?は、String型をOptional型にラップした型を読み書きしやすくしたもの。
  • Optional型のString型 = String? = Optional<String>
  • 暗黙的Optional型のString型 = String! = ImplicitlyUnwrappedOptional<String>
  • 非Optional型のString型 = String

Optional型の代入

Optional型の変数を非Optional型の変数に代入する場合は、構文エラーになるので注意。
非Optional型はnilを許容しないという原則のためですね。


Optional型のメソッド呼び出し

上記から分かる通り、String?はString型とは異なりOptional型にラップされている状態なので、そのままString型の関数を使おうとすると構文エラーになってしまいます。
そんな場合は、非Optional型にアンラップしてから関数を使用すれば大丈夫です。
アンラップの方法は以下の4通りあります。

  1. Optional Chaining
    変数の後ろに"?"をつけてアンラップする方法
    戻り値がOptional型のため、nilの場合はnilを返します。
  2. Forced Unwrapping
    変数の後ろに"!"をつけて、強制的にアンラップする方法
    戻り値が非Optional型のため、nilの場合は実行時エラーになります。
  3. Implicitly Unwrapped Optional
    暗黙的にアンラップする宣言方法
    変数の型の後ろに"?"ではなく、"!"をつけて宣言します。
    アンラップは暗黙的に行われるので、代入する場合に"?"や"!"をつける必要がなく、String型の関数もそのまま使えます。
    戻り値が非Optional型のため、nilの場合は実行時エラーになります。
  4. Optional Binding
    if文などの条件式で宣言して、Optional型の変数を代入してアンラップする方法
    代入された値がnilかどうかで処理を分岐できます。

"!"の場合、クラッシュさせないため、従来のようにnilチェック処理が必須になってきます。
そもそも宣言時以外にnilが入る可能性がある変数には、"?"を使用するのが良さそうです。

Nil Coalescing Operator

オプショナル型がnilの時にデフォルト値を入れたい場合は、"??"の演算子を利用すると便利そうです。
"??"の左にoptional型の変数、右にはその値がnilだった時に返したい値を書きます。

冒頭でSwiftは安全性が高いと言いましたが、結局はプログラマ次第なのかな?と思いました。
意味がわかってなくても"!"で書けば、今まで通り変数にnilが入れられるので、乱用すれば今まで通りnilアクセスでクラッシュするような。。
書いてる段階でより明確に意識させられるようになった感じですね。ふむふむ。

2015年7月2日木曜日

Swift入門


これから少しずつSwiftの勉強をしていきたいと思います。

Swiftを選んだ理由は、以前仕事でObjective-Cを使っていたので、その知識の輪を広げたいという気持ちからです。
0から勉強するよりは取っ付き易く、時代に置いていかれないためにもやらないと!と思っていました。


まずはObjectivi-CからSwiftへの変更点をざっくり箇条書き。
  • 実行速度が早くなったらしい。
  • .mと.hファイルではなく、.swiftというファイル1つになった。
  • 行末のセミコロンがいらなくなった。
  • 別クラスにアクセスするのにimportが不要になった。


他にも書き方が色々と変わったようなので、ひと通りご紹介します。

◆変数
Swiftは宣言時の設定された値により型を勝手に決めてくれる
型指定することもできる
◆定数
値の変更ができない
◆型変更
◆文字結合
◆Array
◆Dictionary
◆デバッグ出力
plintはNSLogより早いらしい
plintlnというのもあったが、Swift2でなくなったようだ
◆ジャンプバー
#pragma mark - add comment とか書いてたやつ

まずはこんなもんで。。。

2015年7月1日水曜日

まだまだこれから


はじめましてBenです。

ここ何年か仕事でプログラマをやっていましたが、年齢が上がるにつれて自分の知識の少なさ狭さに、日々危機感を持つようになってきました。やばい。

そんな気持ちを補うために、毎日新しいことを少しずつ学んで、それを書き残していこうと思います。

5年後には、プログラマとしてもっと自信がついてますように、もっと技術を楽しめていますように...と願って、なんとか継続だけはしていこう。