iOSアプリ開発から遠ざかっていて(言語もObjective-Cだった)iOS、Xcode、Swiftの進化の具合が半端ないこともあり、いろいろ勝手も違うのでイチから勉強するつもりで、手始めに下記のチュートリアルを見ながらToDoアプリを作ってみた。
チュートリアルの元記事が2015/6でXcode,Swiftのバージョンも古いので動かなかったり、つまづいたところ挙げていく。swiftの基礎知識が無く、とにかくつまづいたらググって解決した。
— 動作検証の環境 —
Mac OS X El Capitan 10.11.4
Xcode 7.3.1
Swift 2.2
1.pod install で止まる
OSやXcodeをアップデートしたのが原因だと思うが、CocoaPodsを使ってMagicalRecordのインストールした時にpod installが終わらない。
$ pod install
Updating local specs repositories
↓のようにしたらできた。
$ pod repo remove master
$ pod setup
$ pod install
2. CoreData+MagicalRecord.h file not found
コンパイルエラー
MagicalRecordのファイル名が変わったらしいので、importするファイル名を変更
#import "CoreData+MagicalRecord.h"
↓
#import "MagicalRecord.h"
参考:[Swift]Swiftの勉強のためにToDoアプリを作ってみた
上記リンクの記事でも同じチュートリアルでつまづいた所が挙げられている(当記事も一部内容が重複してる)ソースもGitHubにUPされていて大変参考になった。
3.Downcast from 'UITableViewCell?' to 'UITableViewCell' only unwraps optionals; did you mean to use '!'?
コンパイルエラー
Xcode7からdequeueReusableCellWithIdentifierは常に非オプショナル型を返すようになったらしい
let cell = tableView.dequeueReusableCellWithIdentifier("TodoListItem") as! UITableViewCell
↓
let cell = tableView.dequeueReusableCellWithIdentifier("TodoListItem")
参考:[Swift]Swiftの勉強のためにToDoアプリを作ってみた
4.Value of optional type 'UITableViewCell?' not unwrapped; did you mean to use '!' or '?'?
3.の修正をしたら、新たなコンパイルエラーが出た。
let cell = tableView.dequeueReusableCellWithIdentifier("TodoListItem")
cell.textLabel!.text = todoEntities[indexPath.row].item
return cell
↓ 変数cellに!をつける
let cell = tableView.dequeueReusableCellWithIdentifier("TodoListItem")
cell!.textLabel!.text = todoEntities[indexPath.row].item
return cell!
参考:[Swift]Swiftの勉強のためにToDoアプリを作ってみた:GitHub
5.CoreData: warning: Unable to load class named 'TodoApp.Todo' for entity 'Todo'. Class not found, using default NSManagedObject instead.
実行時にエラー
EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP,subcode=0x0)
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return todoEntities.count // ここでEXC_BAD_INSTRUCTION...
}
todoEntitiesがnilになっているためEXC_BAD_INSTRUCTION..
で落ちている。コンソールにはCoreData: warning: Unable to load class named 'TodoApp.Todo' for entity 'Todo'. Class not found, using default NSManagedObject instead.
とエラーが出ていてCoreDataのエラーぽい。
解決方法
CoreDataのEntityの設定で、TodoApp.xcdatamodeld を選択し、Data Model inspector で Module をデフォルト値"Current Product Module"を削除
↓ Moduleの"Current Product Module"を削除
これで動いた。
参考:CoreData: warning: Unable to load class named
Swift・Xcode雑感
- 記述が簡潔。if条件を()でくくらなくてよい。行末に;いらない
- .hと.mがなくなり.swiftだけになってスッキリ
- オプショナル型の挙動がわからん。as やら ? やら !
- Xcodeのコード補完がかなり進化してる。アバウトな入力でも候補を出してくれる
- ストリーボードのViewControllerの形が正方形になってでかくなっている(以前のiPhoneの縦長の形状の方がよかった)