しおメモ

雑多な技術系ブログです。ニッチな内容が多いです。

Swift

URLRequestをcurlコマンドに変換する

サーバーサイドエンジニアとやり取りする時など、何かとcurlコマンドが欲しい機会があると思います。 Charlesなどの外部ツールを使っても出来ますが、LLDBで扱えると時短になります。 Swift側のextension HEADリクエストなどを考慮していないため、厳密では…

ARCによるオブジェクトの破棄タイミングをずらす

Swiftの場合、特に意識せずとも各オブジェクトに対してARCによるメモリ管理が行われ、コンパイル時にreference countのincrement/decrementの処理(retain/release)が挿入されます。 ほとんどの場合、retain cycleを避けることなどのわずかなことを意識してお…

Cellに直接addSubviewするコードに警告を出す

ちょっと前のアップデートで、正しくcontentViewに追加していない場合に、セルの挙動がおかしくなるケースが多発したと思います。 この前Xcode13に上げたタイミングでも食らってしまい、 cellに直接addSubviewしたいケースも多分ないと思ったので、作ってみ…

Property wrapperを使ってCodableの一部のプロパティをencodeしないようにする

最近リファクタをしていて、同じオブジェクトを使ってencodeとdecodeをする際に、必要なケースがでてきたので書きました。 状況 Property wrapperを使った解決 Equatableへの応用 サンプルコード 状況 以下のHogeのように一部のパラメーターでdecodeはしたい…

よくある実装でDateComponentsFormatterやRelativeDateTimeFormatterを使う

DateFormatterに関しては古くからあり、おおよそのプロジェクトで使われているイメージですが、DateComponentsFormatterやRelativeDateTimeFormatter(iOS13+なので最近)については体感としてあまり使われておらず、特に歴史のあるプロジェクトでは独自のform…

OSLogを利用したロギング

iOS開発でログを利用する場合、自前のロガーを利用したり、OSSを利用する選択肢が多いですが、標準のOSLogのAPIが新しくなり、iOS14以降で使いやすくなりそうなので、紹介します。 printと比べて何が良いか OSLogを利用した出力 Loggerを用意する ログを出力…

NSObjectを継承したクラスでEquatableの操作をする

NSObjectは自身がEquatableなので、==やEquatableに対するメソッドが呼べたりするのですが、デフォルトの動作はポインタを比較するSwiftでいう===相当なので気をつけましょう。 final class Hoge: NSObject { let value: Int init(_ value: Int) { self.valu…

SwiftにおけるBastard Injectionとは

結構ありがちな書き方なので、書いてみました。 Bastard Injectionとは なぜBastard Injectionが問題となるのか なぜ書いてしまうのか 置き換える方法 見るべき動画 Bastard Injectionとは Bastard Injection(Poor Man's Dependency Injection)は、他の言語…

RxSwiftのmaterialize/dematerialize

他言語含めても、なかなか使われているサンプルも少ないmaterializeですが、 そんなに悪さをするオペレーターでもないので書いてみました。 こんなオペレーターもあるよ的な感じです。 materialize/dematerializeの機能 materialize dematerialize ありえそ…

SourceryでBuilderを自動生成するテンプレート

若干需要があったので、テンプレートファイルを作成して、Sourceryを使ってBuilderを自動生成してみました。 実装は、Lombokの@BuilderのようなシンプルなBuilderのイメージです。 projectlombok.org テンプレートと使い方 作成したテンプレートは、ここに置…

SwiftのOptionalの注意点とmap/flatMap

最初は、OptionalのmapとflatMapの話だけ書いていたのですが、だんだんOptionalそのものの話まで膨らんできたので、一緒に書くことにしました。 今回の話はコードレビューで見つけたら割と指摘したい部分ではあるものの、毎回この内容を書くのも無理があるの…

Swiftのコードにシェルスクリプトでfinalをつける

こんばんは、final警察です👮 既存のコードにfinalをつけるのがめんどくさかったので、シェルスクリプトで一括finalをつけてみました。 Bashスクリプト 解説 git grep class.+:.*[, ]$CLASS_NAME\W while read ~ done < <(expr) なぜfinalをつけるか 締め Bash…

VSCodeでSwift5.1のSourceKit-LSPを動かす

SwiftPMも本格的に使えそうなので、SourceKit-LSPを試してみました。 SourceKit-LSPは外部エディタ向けの、Swiftコードの補完やジャンプなどの機能を提供するLanguage Server Protocolです。 VScodeやVimなどのテキストエディタなどで利用することが出来ます…

DispatchSemaphoreで非同期処理の完了を待つ

Swiftに`async/await`がなかなかこないので書いてみました。 コールバック地獄が嫌いな人向けの記事です。

NimbleのPredicateの自作方法とサンプル

Nimbleでテストを書いていた際に、共通部分を`Predicate`として自作してまとめたいことがあったので、実装の方法と簡単なサンプルを記しておきます。

UIView.animateをメソッドチェーンで書く

UIView.animateは引数が多く、animationとcompletionで2つクロージャーを引数に取り、ネストも深くなりやすいため、メソッドチェーンで書けるように改良してみました。 サンプル 実装 AnimationBuilder AnimationExecutor アニメーション開始用のstaticメソ…

Swiftのassert系メソッドとfatalErrorの使い方

Swiftには、assertと似た役割を持つメソッドとして、preconditionやfatalErrorがあります。 これらのメソッドの使い方について考えてみます。

今さらUIPageViewController詳解

UIPageViewControllerが登場したのが古いこともあり、公式ドキュメントや、ネットに出ているの情報だと、いまいち各メソッドの挙動までは掴みづらかったので、改めてまとめてみました。

Arrayのextensionでサブクラスにダウンキャスト

タイトル通りで、UIViewControllerやUIViewのArrayから特定のサブクラスだけ抜き出す処理はよく書くので、 ただのaliasですが、少しでも楽しようとextensionにしてみる。 extension Array { func `as`<E>(_ type: E.Type) -> [E] { return self.compactMap({ $0</e>…

Swiftで作成したiOS向けframeworkをローカライズする

普通のアプリの場合は、NSLocalizedStringにキーを渡すだけで大丈夫なのですが、frameworkを公開する場合、デフォルトだとアプリ側のBundleを参照してしまうので、そちらも正しく指定しなくてはいけません。 情報が少なかったので、その方法を記載しておきま…

Swift4で範囲の文字列表現をRangeに落とし込む

正確には、RangeExpressionのような、containsで要素を含むかどうかを判定できる適当なクラスに落とし込みます。 今回はRange(0.0...1.0みたいなやつ)だけではなく、RangeExpressionに適合するのすべてのクラスに対応したいと思います。 Swift4.2からRange系…

DispatchQueueによる非同期処理を見直す

他言語から入ると、一見取っつきづらいDispatchQueueですが、だいぶ浸透してきた気がします。 一方で、簡単にマルチスレッドで非同期処理ができるようになった結果、処理フローの制御がしづらくなったり、 知らないうちに、CPUやメモリリソースを異常に消費…

SwiftのARCとクロージャのキャプチャ

Swiftのバージョンが上がる前に、クロージャーに対して各種方法で変数をキャプチャした際の挙動を整理します。 ちなみに、新卒アドベントカレンダーではないです。 ARCについての前提知識 強参照と弱参照の違い 強参照 弱参照 キャプチャの種類 組み込み型の…

Swift用デバッグロガー Linna

一ヶ月ほど前から、ちまちま開発を進めていた、 Swift用のデバッグロガー"Linna"の紹介です。 日本語ドキュメントはこちらです。 github.com 特徴 ロードマップ 特徴 JavaやJavascriptなど、他言語の代表的なロガーの機能を踏襲しつつ、 出来るだけシンプル…

SwiftでRustのようなResult型を実装する

Swiftで従来のthrow~catchでは書きづらい場面も多々あるので、 RustのResult型を参考にした、エラーハンドルを取り入れてみました。 やること 実装 case メソッド その他 使い方 switchで使う Optionalで使う サンプル やること SwiftでRustのResult型のよう…

Obj-Cライブラリ由来のNSExceptionのSwiftでのハンドリング

ずばりこれ。 NSSetUncaughtExceptionHandler(_:) - Foundation | Apple Developer Documentation swiftのcatchで拾えないものもこちらでハンドルできる。 AppDelegate等に入れておく。 func application(_ application: UIApplication, didFinishLaunchingW…

iOS(Swift)プロジェクトにSonarCloudを導入する

今回は、静的解析ツールのSonarQubeのクラウド版、 SonarCloudを導入します。 Travis, fastlane導入までは、前回の記事をご参照ください。 scior.hatenablog.com 環境 SonarQube Continuous Inspection アカウント登録 SonarCloudの設定 sonar-project.prope…

SwiftLint, fastlane, Travis CI導入まで (Xcode 9.4)

iOS開発(Swift)でCIまでを動かす際の手順です。 今回は、Xcode 9.4, Swift 4(3でも可)です。 サンプルリポジトリ: github.com 導入するツール Swiftlint Fastlane Travis CI 今後やること 導入するツール SwiftLint(0.26.0) コーディングスタイルの静的解析…

View Controllerのユニットテスト

View ControllerのUIテストはともかく、ユニットテストはどうするのかわからなかったので調べました。Swift 3です。 class MapViewControllerTests: XCTestCase { var mapViewContoller : MapViewController? override func setUp() { super.setUp() let sto…