【アプリ開発/トラブルシューティング】Swiftで使える便利な技【25選】








CrashlyticsのdSYMを登録したい


FirebaseのCrashlyticsにて「不足している必須の dSYM をアップロードしてください」と表示される問題の解決方法。

1. オーガナイザーからArchiveしたパッケージをFinderで表示
2. xcarchiveファイルを「Show Package Contents」で中身を覗き、dSYMsフォルダをターミナルに貼り付けるなどして、パス /path/dSYMs を取得する
3. 例えば HogeProj があった場合、プロジェクトのディレクトリへ移動して以下のコマンドを実行する

./Pods/FirebaseCrashlytics/upload-symbols -gsp HogeProj/GoogleService-Info.plist -p ios /path/dSYMs






保存したファイルをファイル.appに表示させたい


何かのファイルを FileManager を使って documentDirectory に保存しても、デフォルトでは ファイル.app に表示されないようになっている。

以下の設定をInfo.plistに追加することで、ファイル.app に表示されるようになる。
UIFileSharingEnabled (Application supports iTunes file sharing)LSSupportsOpeningDocumentsInPlace (Supports opening documents in place) をそれぞれ YES に設定する。









UIBarButtonItemの画像サイズが大きくなってしまう




次のようなプログラムで UIBarButtonItem を作ってしまうと、上の画像のようにボタンのイメージが大きくなり崩れてしまうことがある。





少し面倒だが、この問題を修正するには customViewUIButton を入れて、AutoLayout を設定することで解決できる。




このようにキレイにボタンをおさめることができた。






キーボードを表示した時、Viewが隠れないようにしたい


IBOutletNSLayoutConstraint を下の図のように、特定のViewのボトムラインに結びつける。



IBOutlet で結び付けられた NSLayoutConstraint は、コードで簡単に値を変えることができるようになった。

下のプログラムでは、キーボードの高さと、表示アニメーションのdurationを取得して、UIView.animate でキーボードと同じ動きでViewが移動するようにアニメーションをかけている。




このプログラムではオブザーバーを削除していないため、注意しておく。



Safe Area のマージンを取得したい


iOS11から利用できる self.safeAreaInsets を使って取得できる。
次のようにViewにextensionを定義しておくと便利。
使う時は self.view.csSafeAreaInsets.top のようにできる。





画面の回転を検知したい


画面回転時のイベントをフックするには UIDevice.orientationDidChangeNotification をオブザーバー登録する必要がある。
向きが変わった時だけ処理をさせたい場合は、下のプログラムのように lastOrientation などで以前の状態を保持しておく工夫が必要である。





UIViewControllerのクラス名を取得したい


次のように UIViewController を拡張しておくことで、他のクラスで UIViewController が渡された時にクラス名で条件分岐できるようになる。






同じクラスタイプのViewを一括で操作したい


例えば、UISegmentedControlがself.viewの中に沢山あったとして、それらをまとめて処理したい場合は次のように書くことができる。





UIImageViewやUIButtonをtintColorで色を変えたい


通常、UIImageView や UIButtonの画像の色は、tintColor を指定しても変えることができない。
画像をα値だけでレンダリングするように設定してあげれば UIImage.RenderingMode.alwaysTemplate tintColorが効くようになる。





ナビゲーションバーの色を変えたい


ナビゲーションバーの色は、それぞれ次のように定義されている。


文字の色は、NSAttributedString を使って設定する。


ちなみに UIBarButtonItemtintColor でも変ることができる。
closeItem.tintColor = .white

また、ナビゲーションバーの色が少し薄い場合は、次のようにして対処する。
self.navigationController?.navigationBar.isTranslucent = false



テーブルセルの背景色を変えたい


UITableViewCell の背景色は、次のようにUITableViewのdelegateで変える。





MD5ハッシュ値の生成したい


こちらの記事を参考にさせていただいた。
CommonCrypto モジュールをインポートする必要がある。


Swift4で動作確認済み。

Stringextension しているので、使う時は "hogehoge".md5 のようにして変換することができる。



iOSの設定アプリへアクセスしたい


iOSの設定アプリの中の、自分のアプリの設定画面へショートカットできる。






数秒後に遅らせて実行させたい


DispatchQueue.main.asyncAfter を使えば、次のように遅延処理を簡単に書くことができる。





メインスレッドで実行したい


非同期処理の後にViewなどのUIを操作しようとするとクラッシュする。UIはメインスレッドで実行しなければならないからだ。
DispatchQueue.main.async を使ってメインスレッド内で実行するようにしよう。





クロージャでコールバック処理したい


ネットワーク越しに非同期でデータを取ってきて、その後にViewなどにデータを反映したい場合によく使うワザ。
completion(Int) -> Void のようなクロージャで定義する。ネットワーク処理などを書いて、成功したら completion(rank) で呼び出す。



使う側はこんな感じ。
fetchYourRank(leaderboardId: leaderboardId, completion: { rank in
    self.yourLankLabel.text = "あなたの順位は\(rank)位です"
})

引数にクロージャを定義することで分かりやすいコールバック処理を書くことができる。





画面の向きが変わったらイベントを検知したい



UIDeviceOrientation には isFlatisValidInterfaceOrientation などもあることに注意。



端末がiPadかどうか判定したい


UIDevice.current.userInterfaceIdiomで判別できる。三項演算子と合わせるとスマートに書ける。





デバッグ時とリリース時で動作を変えたい


次のようにして実現できる。



ただしこのDEBUGの定義を使えるようにするためには、Builid SettingsOther Swift FlagsでDebugの項目のみに-D DEBUGと指定する必要がある。

大事なことなのでもう一度言うが、必ずDebugの項目のみにパラメータを入れるように。





シングルトンを実装したい


次のように static を使って宣言する。
使う時は Hoge.shared.doSomething() のように shared を経由して関数を呼び出すこと。
init をオーバーライドして private にしておくと shared 忘れがなくてよい。





UIColorに独自カラーを追加したい


こんな感じでUIColorを拡張する。


ポイントは関数ではなく変数として定義してclassを指定すること。すると次のようにシステムカラーと同じような扱いで簡単に指定することができる。

textLabel.textColor = .textLightColor






UITalbeViewの最下部にスクロールしたい


最下部にスクロールするにはscrollToRowを使うが、tableView.reloadData() 後すぐに実行すると正しくスクロールできない。
タイマーでタイミングを少しずらすことでうまくいった。





メソッドを一度だけ実行したい


viewDidLayoutSubviewsなど何度も呼び出されてしまうメソッド内で、一度だけ実行したい処理があった場合に以下のような書き方をしていた。
これだと毎回フラグを宣言、条件分岐するのは面倒だし、可読性がよくないなと思っていた。



クロージャーとlazyを使ったスマートな書き方を見つけたので、参考にさせていただいた。
» UIView などでインスタンス単位で一度だけ実行したい初期化コードの考察 - Qiita



こちらの方が可読性が上がる。

他にもいろいろな書き方がいろいろあるようだ。

クロージャー(Closures)は名前のない関数で変数として扱われる。
lazy(lazy stored property)は、参照されるときに初めて初期値が設定されるプロパティ。



UILongPressGestureRecognizerは二回呼ばれてしまう


let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longPressedButton))
button.addGestureRecognizer(longPressRecognizer)


こんな感じで登録したlongPressedButton関数は二回呼ばれる。
アラートなど呼び出す時は二度呼ばれてしまうので注意が必要。
UIGestureRecognizerのstateで下記のように切り分ける。






メソッドチェーンの返り値を使わない時のwarningを消したい


メソッドチェーンを実装しようとした時に、返り値を使わない場合が多々ある。
Xcodeは関数の返り値を使わないと丁寧にwarningを出してくれるが、warningだらけになってしまうので対処したかった。
結論としては、@discardableResult アノテーションを付ければよいだけだった。



Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 WEB+DB PRESS plus

本書は、Swiftの言語仕様と実践的な利用方法を解説した入門書です。Swiftは簡潔な言語ですが、その言語仕様を理解し、正しく使うことはけっして容易ではありません。Appleの公式ドキュメントをはじめとして、どんな言語仕様があり、それらをどのように使うかに関しては豊富な情報源があります。しかし、それらがなぜ存在し、いつ使うべきかについてまとまった情報があるとは言えません。本書は、読者のみなさんの「なぜ」や「いつ」を解消することにも主眼を置いています。今回の改訂で、新バージョンのSwift 5に対応しました。

KindleAmazon

あなたにおすすめ