面白きことは良きことなり

拙く未熟なiOSエンジニアの備忘録と戯言

didSetの挙動

didSetの挙動

Swiftでは、Propertyに対してdidSetで処理を書いてあげることが多く、この時呼ばれるの?呼ばれないの?と疑問に思うことがしばしばあって、テストしていたのでまとめておく。

値型と参照型で異なる点は言わずもがな気をつけなければいけない。

呼ばれない

  • init()内で代入した時
  • 配列(NSArray型)で、addingを呼んだ時

呼ばれる

  • 値を入れた時
  • nilを入れた時
  • 配列(Array型)でappendremoveを呼んだ時

UIButtonが青色一色のベタで表示された時の対処

初歩的ミス

IBOutletで紐づけていたUIButtonにコードでimageをセットしてあげるも、青色一色でベタ塗りされた表示になっていた。

理由としては、UIButtonのTypeがSystemだったために画像をセットしても青色で表示されていた。

Customに変えて正常に表示されたので、解決。

tak-lab.net

URLComponentsは、`+`をPercent Encodingしてくれない

経緯

APIを叩く際にランダムに生成しな内容をBASE64化してQueryにつけて送信しようとしていたが、5割ぐらいのエラーになっていた。
調査した結果、+がPercent Encodingされていないためだったが、なぜこんなことが起きたのか…。

便利なURLComponentsの罠

qiita.com

この記事でURLComponentsという便利なものがある!自前でPercent EncodingしてQuery作らなくていいんだ!とうっきうきで使っていたわけだが、+はPercent Encodingしてくれない。(ちなみに+をPercent Encodingすると%2Bになる)

stackoverflow.com

なぜ起こったか

今回のようなことが何故起こったのか。

URLComponentsは、説明にRFC 3986に準拠していると記載されている。サーバ側がRFC 3986に準拠していない作りが理由とも言えるし、自分がそこを確認怠り、URLComponentsを使用したのが理由とも言える。

URLComponents - Foundation | Apple Developer Documentation

サーバの作り次第で、このあたりはいくらでも変わるので、気をつけたいところ。

今回は、時間やコードの手戻りが厳しいこともありURLComponentsでQueryを付けた後、+%2Bに置換する力技で解決した。

URLComponentsに頼らない自作URLComponentsのようなものを作ってもいいかもしれないと思った。

WebView実装してリロードしまくったら出るNSURLErrorDomain エラー -999

前説

業務が忙しかったこともあり、色々ネタはありつつも書いてなかったので、落ち着いてきた今日あたりから徐々にまた書いていく。軽めにね。

NSURLErrorDomain エラー -999

WKWebViewを実装して特に制御せず、back, forward, reloadボタンと処理を紐づけていたがため、reload連打したらエラーなんか出たというバグ報告が上がった。

エラー内容は、 操作を完了できませんでした。(NSURLErrorDomain エラー -999。)

特にパッとなんでこのエラーが出たのか説明できなかったので、改めて調べた。

これは、発行したリクエストをキャンセルした際に返るエラーとのことで、reload連打によりリクエストがキャンセルされてエラーとして返ってきてるために出ているものと判明。

captainshadow.hatenablog.com

ちなみにerror codeは、NSURLErrorCanceledとして定義されている。

NSURLErrorCancelled - Foundation | Apple Developer Documentation

UIBarButtonItemで画像の見たを変えずに使用するやり方

UIBarButtonItem

UIBarButtonItemは、UINavigationControllerとかと併せてよく使うButtonですが、そのまま使用すると下記のように透過じゃない部分は単色でTint Colorによって塗りつぶされます。

f:id:aryzae:20180211211616p:plain
この画像を使用すると…

f:id:aryzae:20180211211808p:plain
こうなる

これを画像を加工せずそのまま表示したいと思ったので、いいやり方ないか調べた際のメモです。

init(customView:)を使う

UIBarButtonIteminit(customView:)という初期化方法にUIButtonを設定することで簡単に実現できる。

流れとしては、

  1. Storyboardで、UIButtonを用意する
  2. IBOutletで紐づける
  3. そのButtonを使用してコードでUIBarButtonItemを作成する
  4. UIBarButtonItemをセットする

f:id:aryzae:20180211212238p:plain

そうすると、このようになる、

f:id:aryzae:20180211212353p:plain

このやり方のメリットとして、StoryboardのUIButtonからIBActionを設定できるのでaddTargetとかを使って#selectorで押下時の挙動を設定してあげる必要がない。

Storyboardを使わない場合

この場合、コードでUIButtonを生成して同じようにUIBarButtonIteminit(customView:)でセットしてあげればよい。