with tech blog に書いた記事でしたが、 Qiita に移ることになったので転載しました。
こんにちは! with で iOS エンジニアをしている中村です。
iOS エンジニアを名乗っているものの、 iOS 開発経験はまだ半年足らずで、それまでは with の Android エンジニアをしていました。
2022/10 に iOS チームに異動させてもらったものの、ほぼゼロからのスタートだったので成長を目に見える形に残したく TIL を続けていました。
TIL とは、 Today I Learned の頭文字を取ったもので、その日学んだことを Github などに記録していくことらしいです。
今回は職場の Slack の iOS チームのチャンネルで、 TIL を放流していくことにしました。
以下のような形で [TIL] のタグを付け、些細なことでも良いので基本毎日その日学んだことを投稿していました。
チームのチャンネルでやるとチャンネルが汚れてしまうかな、とも思いましたが、私の承認欲求(モチベ継続)のためにこのチャンネルでやらせてもらうことにしました。
実際始めてみると、チームメンバーがスタンプでリアクションしてくれたり、スレッドで意見をくれたり、補足してくれたり、訂正してくれたりと、やっていて良かったなと思いました。
チームメンバーからの意見をもらえると、より理解が深まりますし、記録を残していくことで自分の知識の定着にも役立ったと感じました。
そんな TIL ですが、 2022/11/28 から始めて、 2023/03/10 現在 90 個を超えました!
出勤日が約 60 日くらいだったので、 1 日に約 1.5 個の投稿ペースだったようです。
この 3 ヶ月で日々どんなことを学んだのか、一部ではありますが、以下カテゴリ別に紹介しようと思います。
ぜひ見ていってください。
Swift 言語
構造体 struct
関連の TIL
Swift の struct
はイニシャライザを定義しなくても、初期化できるんですよね。
struct Hoge {
var a: Int
var b: Int
// init (a: Int, b: Int) を書かなくても…
}
var hoge = Hoge(a: 100, b: 200) // 初期化できる!
チームメンバーから「デフォルトのイニシャライザは internal
なので、別のターゲットからアクセスするためには、結局イニシャライザを定義しなければいけない」という話も聞けました。
public struct Hoge { // 構造体を public にするなら…
var a: Int
var b: Int
public init (a: Int, b: Int) { // public なイニシャライザを書こう!
// ...
}
}
似たような話で private なメンバ変数を定義すると、イニシャライザは自動的に private になるんですね。メンバ変数に外側からアクセスできないので、考えてみれば確かに…という感じ。
構造体は値型なので、コピーコストの心配をしていたら、 Swift にはコスト削減の仕組みがあるよという話も聞きました。 Swift すごいですね。
struct は値型だということは理解していたつもりですが、長い間 Android アプリ開発をしてきたのでなかなかその癖は抜けません。配列の中の一要素を更新しようとして失敗しました。
struct Hoge {
var number: Int
}
var list = [
Hoge(number: 100),
Hoge(number: 101),
Hoge(number: 102),
]
if var target = list.first(where: { $0.number == 101 }) { // ここの target はコピー
target.number = 1000 // ← なので、 list の Hoge(number: 101) は更新されていない
}
参照型の言語からの考え方の切り替えが必要だな、と思いました。
見慣れない記述方法の TIL
Swift には他の言語では見慣れない書き方がありますよね。
(私が他の言語をあまり知らないだけかもしれません)
if case .success(_) = result { ... }
このような書き方は、 if 文の中に、単体の =
があるので、最初は記述ミスかと思いました。こんな書き方があるんですね。 TIL に上げたもののまだちゃんとわかっていません 😂
また ~=
というパターンマッチング演算子というものもあるようですね。
TIL に自分で返信しましたが、次にこのコードを見たときに覚えていられる自信がありません。でも、覚えているうちはつい使いたくなります。
空の配列の作り方も「え?そんな風に書くの?」と驚きました。
変数側で型が決まっていれば []
で済むのですが、そのときは何故か生成する側で型を書こうとしていたんですよね。 String
の空配列なら [String]()
って、ちょっと思いつきませんでした。わかって見れば、型の後に ()
がついていてインスタンスを作ってるんだな、というのも理解できます。
Kotlin では Collection に色々と便利なメソッドがたくさん生えているのですが、 Swift はよく使われるようなメソッドでも代替できるならそっちを使ってネ、という感じのようです。
sum()
すらないのは驚きました。でも引数として +
を渡しているのがなんかおしゃれですね。
let sum = [1, 2, 3, 4, 5].reduce(0, +)
UIKit
Swift 言語は Kotlin と似ている部分も多く、最初からそれなりに読み書きできましたが、 iOS のフレームワークとなるとそうはいきません。
知っていれば簡単なことでも、なかなか気づくのは大変です。
この TIL はほぼ愚痴ですね。
Interface Builder で UILabel を設置すると、Lines の初期値が 1 になっています。
設定される文字列によって自動で行数が増えて欲しいと考えたので Xcode のインスペクタにそのような設定項目がないかと探したのですが見つかりませんでした。
まさか Lines に 0 を設定すると自動改行になるなんて思わないじゃないですか。
Android では ListView
は RecyclerView
が出てほぼ置き換えられていきました。
同じように考えていたので、 iOS でも UITableView
は古い UI で、新しく開発するものはすべて UICollectionView
を使うものだと思っていました。しかし、 iOS ではそこは臨機応変に使い分けているようですね。
View の影について。
Android も最近は困ることがなくなったと思いますが、UIKit では昔から気軽に影を落とせるのがすごいですよね。
RSwift について
リソースを Android のように使える RSwift については、 Android よりも便利だと感じることがありました。
R
の中にメソッドが定義されるので、変数を文字列に展開するのも簡単でした。
Android の R.string.hoge
はただの Int
だったので、R
だけではどうしようもなかったんですよね。
// Localizable.strings
"hoge" = "ほげ%d";
label.text = R.string.hoge(100) // "ほげ100"
また、 RSwift はファイルも扱ってくれるのが良かったです。
さいごに
学んだことは他にも些細なことから、ちょっと難しいことまで色々とあるのですが、さすがにブログには書ききれませんでした。
こうして改めて見返してみると、覚えたと思っていてもすでに忘れてしまっているものもありますね…。一度では覚えられれないので、何度も繰り返し学んで身につけていくしかありません。
この TIL をやってみて、自身の成長の記録として見返すことができることも良かったのですが、何よりチームメンバーとのコミュニケーションのハードルが下がったのではないかな、と感じられたことがとても良かったです。
with の開発はほぼリモートワークなので、チームメンバーとの接点は主に Slack になります。自分の仕事に集中していると、特に発言することもなく 1 日が終わってしまうということもありますが、 TIL を始めたことで気軽にスタンプやコメントを通じた交流が増えたと感じています。
また、この TIL は個人的に始めたことでしたが、時々チームメンバーもマネて投稿してくれたのも嬉しかったです。
やはり他の人からのリアクションが継続の力になりますね。
私は「心理的安全性が〜」とか「チームビルディングが〜」とかはあまり考えていなくて、どうしたら自分が楽しく開発できるかということを考えて TIL を始めました。
新しいことを覚えたら楽しい!誰かに話したい!そんな感じでした。
自分の知識の定着に役立ち、コミュニケーションも活発になる(こともあるかもしれない)。
そんな TIL を、これをお読みのエンジニアの皆さんも始めてみてはいかがでしょうか!