[Swift]QiitaのAPIを叩いて記事を取得して表示するサンプルアプリを書いてみたシリーズの続き。
概要
[Swift]QiitaのAPIを叩いて記事を取得して表示するサンプルアプリを書いてみた その2を書いてからSwift3.0が公開されて、サンプルが動かなくなっていました。
いまでもストックされることがあるので、メンテナンスもふまえて、記事にしました。
ついでに、ソースコードもリポジトリを独立させました。
あ、記事は私が失敗した手順で書いていくので、同じ手順でやると失敗します。
正しい手順は
- CocoaPodsのアップデート(--pre忘れずに)
- Podsを更新
- Xcodeのプロジェクトファイルを開いて、Swift3.0にコンバート
- エラーを修正する
です。
Podsを更新
CocoaPodsでインストールしたライブラリもSwift3.0対応されているので、まずはライブラリの更新から。
PodFileを更新。
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
swift_version = '3.0'
use_frameworks!
target 'QiitaAPISample' do
pod 'Alamofire', '~> 4.0'
pod 'ObjectMapper', '~> 2.2.0'
end
target 'QiitaAPISampleTests' do
end
target 'QiitaAPISampleUITests' do
end
Xcodeのプロジェクトファイルを開いて、Swift3.0にコンバート
QiitaAPISample.xcworkspaceをXcode8.1で開くと、「コンバートするかい?」と聞かれるので、CocoaPodsで入れたライブラリのチェックを外してコンバートを実行する。
なんかこの時点でエラーになってるけど、そんなもんだと思って、気にしないことにする。
Swift3.0移行に伴って、Deployment TargetのバージョンもiOS9.0に変更。
サンプルなので好き放題。
エラーを修正する
さて、ここまでくれば表示されているエラーを修正すれば、移行は完了!
と思ったのだが、おかしなことに気づく。
ライブラリのSwiftのバージョンが古いというエラーが出ている。
Use Legacy Swift Language Version (略)
そんなことはないはずなんだけど…
模索してみた
ひとまずおかしくなったことは確実なので、最初からやり直す。
下記のissueを参考に模索してみた。
https://github.com/Alamofire/Alamofire/issues/1526
CocoaPodsのアップデート
sudo gem install -n /usr/local/bin cocoapods --pre
インストールされたバージョンは、1.2.0.beta.1。
念のため、podのリポジトリを新しくしておく。
pod setup
PodFileを修正
Podsディレクトリを削除して、pod install
したら、入れたいバージョンより前の物が入ってしまったので、バージョン指定した。
上に書いたものはバージョン指定済のものを記載。
DerivedDataの中身を削除
/Users/(name)/Library/Developer/Xcode/DerivedDataの中身を削除
Xcode8.1で開き直す
コンバートするかい?と聞かれるので、コンバート。
Deployment Targetのバージョンがおかしいよと言われるので、PodsのDeployment TargetもiOS9.0に変更。
CocoaPods絡みのエラーが解消
一安心。
たくさん英語を読みました。
Swift3.0に移行したことによるエラーを修正
コンバートしたことによるエラーもちらほらあったけど、Xcodeの言うとおり直せばOKでした。
一番悩んだことだけ紹介。
import Alamofire
import ObjectMapper
class APIClient {
func getAllItems(_ success: @escaping (([Item]) -> Void)) {
let urlString: String = "https://qiita.com/api/v2/items"
Alamofire.request(urlString).responseJSON { response in
switch response.result {
case .success(let value):
if let items = value as? [[String : Any]] {
var resultItems: [Item] = []
for item in items {
// ここ!
resultItems.append(Mapper<Item>().map(JSON: item)!)
}
success(resultItems)
}
case .failure(let error):
print(error)
}
}
}
}
map(JSON: item)
というように、ラベルをいれなければいけないことになかなか気づけなかった。
ソースコード
Githubにあげました。
https://github.com/macneko-ayu/QiitaAPISample
まとめ
簡単にできるだろうとたかをくくっていた結果、痛い目を見ました。
Swift詳しい人ならさくっとできるのだろうか。