Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

Swiftで書いたiOSアプリの再設計方針を考える

iOS8.0以上をサポートするSwiftアプリを作っております。ちゃんと動くけど汚い。色々辛みがある。

というわけで、ノーガードでその辛みを書いていこうと思います。

StoryBoardの辛み

僕の作ったアプリのStoryBoardはこんな状態になっている。Main.storyboardだけを使ってる。

f:id:gothedistance:20150701162919p:plain

  • UITabController
    • UINavigationController
      • ViewController

UITabControllerをメインに使いながらEmbeddedしたUINavigationControllerを、各画面に挟んでいる。で、そのViewControllerで2つほどsegueでPUSHして戻す処理(小画面連携)があるのでそれを定義している。これでも小規模な部類に入るんだろう...画面数は10個弱だし。

AndroidのようにテキストでXMLを書いて画面を作るということができないのが、結構辛い。それ以外にも様々な辛みがここに挙げられている。

qiita.com

Storyboardで作ったUIViewControllerで画面をちまちま書くのではなく、XIBに別に出して読み込むってのが良さげ。Storyboardは画面遷移を書くだけなら簡単だし。でも、もっと簡単にできないのかな。

UIのスタイリングは別クラスに出して、UITabControllerでこんなコードを書いてスタイルの共通化を図っている。androidのようにdrawableとかで設定できれば楽なんだけど。

HTTP通信

Alamofireを使っているけど拡張方法がピンと来ていないせいか、随所にこんなコードを散りばめてしまった。コピペを生み出しており、かなり辛みがある。そのうち無事死亡する。

request(Method.GET, EndPoint.host + "/api/xxx",parameters:param)
    .responseString { (_, _, json_response, _) in
        if(json_response != nil) {
            self.users = Mapper().mapArray(string: json_response!, toType: User.self)
        }
}

これはひどい。可能な限りRetrofitな感じで書き換えたい。

public interface RetroFitApi {
   @GET("/news/new")
    void getNew(@Query("name") String name, Callback<ArticleList> cb);
}
//http://qiita.com/HamaTech/items/5eacdecc29d943ba46f5

そうなると、これができないといけない。合わせ技になるんだろうな。JSONを予めオブジェクトに変換してからコールバックを定義したいんだよね.... それをどうするか問題。これがベストプラクティスやでってのが無い気がする。Androidにおける「Retrofit + RxJava」をiOSで実現する情報が求められる。特にオレにだッ

  • HTTP通信をラップするサービスクラス
  • JSON⇔オブジェクトに変換するアダプタ
  • コールバック及びリスナーの登録

アラート

AndroidだとDialogFragmentがあり、OKボタン並びにキャンセルボタンのコールバックもそこで定義できる。拡張もやりやすい。iOSの場合は、7と8以降でアラートの出し方が変わってしまった。これをハンドリングするのは結構だるい。下記がわかりやすい。

[iOS] iOS7、iOS8互換なアラート・アクションシートをBlocksKitで実装する | Developers.IO

8以降はUIAlertControllerというViewControllerのサブクラスになったので、ViewControllerのコールバックを拾うようになった。困ったもんだ。めんどくさい。サードパーティのライブラリに切り替えてもいいのかもしれない。

画面回転

僕は縦方向限定で縛ることができたけど、画面回転をサポートしているアプリは大変でございます。困ったものであります。

iOS8対応時の問題点、注意点|11. 00100100…

はじめから回転をサポートしないってのも、ひとつの手だと思うんだよね...

AutoLayout

言いたいことはわかるんだけど、相対的にマージンをチマチマ設定するのが辛い。コードもわかりにくいし...setMarginとかsetPaddingとかそんな感じでかけないのかな...

qiita.com

ちなみに、AutoLayout適用後に測定されたFrameのサイズも拾うことは出来る。viewDidLayoutSubviews内で拾える。ここにフレームで描画してaddSubviewが最も楽なんじゃないかという気すら覚える。

よくわからないまとめ

HTTP通信とアラートのコードがとっ散らかると、アプリのコードはどんどん汚くなりまぁす!!

まずはここから整理したい。