プログラマ行進曲第二章

主にソフトウェア関連の技術をネタにした記事を執筆するためのブログ

別のことを調べていたらGo言語のx/crypto/sshパッケージがOpenSSH形式のパスフレーズ付き秘密鍵にまだ対応できてないことに気づいたという話

業務中に調べていたら発見したことなのですが、発見した後調べてみたら既にクラスメソッドさんの記事でも触れられていたことだったのでまとめる意味あるかなと思いつつ、自分で調べて突き止めたことなので記録に残しておいた方が自分の実力の証明になるかと思い、久々に技術系の記事を書いてみます。

dev.classmethod.jp

dev.classmethod.jp

TL;DR

この問題に気づいたきっかけ

もともとgolangのアプリを書いて気づいたわけではなく、KubernetesのCI/CD周りのエコシステムを調べている中でArgoCDの調査をしており、ArgoCDにSSH private keyを使ってgithub等のprivate repositoryを登録するのを試していたところ、ArgoCDのCLIがエラーを出したので、まずArgoCDのrepositoryにissue登録をしました。

github.com

issueにも書きましたが、出たエラーはこんな感じです。

$ argocd repo add git@github.com:<my private repository> --ssh-private-key-path ~/.ssh/id_rsa
FATA[0000] ssh: cannot decode encrypted private keys

そしてissue登録をした後にdelveでデバッグをしながらArgoCDのソースコードを見たところ、まずこの箇所で引っかかっていることが分かり、step inしながら調べたところ、ssh.ParsePrivateKey関数にしか対応していないことが分かったので、単にArgoCDの問題かと思って一旦放置していました。

ただ、少し経った後「別に技術調査中なんだから、雑にこの箇所をssh.ParsePrivateKeyWithPassphrase関数を使うように書き換えたCLIをビルドして試すのはありなんじゃないか?」と思ったので、雑に書き直した後ビルドして試したところ、またエラーが出てきて「あれ?」と問題に気づいたという流れです。

x/crypto/sshパッケージ自体に問題があると確信するためにした検証の仕方

上記の流れでArgoCDのCLIの挙動をdelveを使って追ったり、x/crypto/sshパッケージのソースコードを読んだりして、細かい検証をする前にx/crypto/sshパッケージ自体に問題がありそうだと思ってはいたのですが、VSCode経由でArgoCDのCLIをdelveでデバッグしていたときの変数の中身の表示がおかしかったりして、本当にx/crypto/sshパッケージの問題なのか他者に証明しづらかったので、ssh.ParsePrivateKeyWithPassphrase関数の挙動がおかしいことを示すコードをgistに残し、挙動を確かめたところ、やはりssh.ParsePrivateKeyWithPassphrase関数自体が手元のssh private key(パスフレーズ付き)をパース出来ないことが分かりました。

確認するのに使ったコードなどは上記のgistに全て書いているのですが、リンク先に飛ぶのも面倒なので以下に同内容のコードを説明付きで書いていきます。

使用したパスフレーズ付き秘密鍵を生成したOpenSSHのバージョン、秘密鍵の状態、Go言語のバージョンは以下の通りです。

$ ssh -V
OpenSSH_7.9p1, LibreSSL 2.7.3

$ ssh-keygen -l -f ~/.ssh/id_rsa
2048 SHA256:/<masked> taku@altair.local (RSA)

$ go version
go version go1.12.6 darwin/amd64

この環境で以下のGoのコードを実行します。

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "os"

    "golang.org/x/crypto/ssh"
)

func main() {
    sshPrivateKeyPath := os.Args[1]
    keyData, err := ioutil.ReadFile(sshPrivateKeyPath)
    if err != nil {
        log.Fatal(err)
    }
    signer, err := ssh.ParsePrivateKey([]byte(keyData))
    if err == nil {
        fmt.Println(signer)
        os.Exit(0)
    }

    passPhrase := os.Getenv("PASSPHRASE")
    if passPhrase == "" {
        fmt.Println("Please configure `PASSPHRASE` environment variable for your passphrase")
        os.Exit(1)
    }

    signer, err = ssh.ParsePrivateKeyWithPassphrase(keyData, []byte(passPhrase))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Parsed private key with passphrase!!")
    fmt.Println(signer)
}

雑なコードですが、PASSPHRASE環境変数が正しく設定されていて、実行時にパスフレーズ付き秘密鍵のパスを指定していればssh.ParsePrivateKeyWithPassphrase関数を実行するようになっていて、signerが表示されるのが期待する動作というコードです。

これで意図通りに動くのか以下のように確かめました。

# ~/.ssh/id_rsa がパスフレーズが無い秘密鍵の時
$ go run main.go ~/.ssh/id_rsa
&{0xc0000ac120 0xc0000ac120}
# 事前にファイルを使って export PASSPHRASE="<~/.ssh/id_rsa のパスフレーズ>" と下準備して、パスフレーズ付き秘密鍵を使用する時
$ go run main.go ~/.ssh/id_rsa
2019/07/11 23:25:03 ssh: cannot decode encrypted private keys
exit status 1

上記のように、パスフレーズ付き秘密鍵の時にはエラーとなり、期待通りに動いていないことが分かりました。

このエラーが「SSH private key側の問題」なのか、「ssh.ParsePrivateKeyWithPassphrase関数の問題」なのかを調べるため、delveを使って上記Goのソースコード実行時の状態を見たところ、以下の箇所でエラーが出ているところまで突き止めました。

詳しくはgistに残したコメントを参照して欲しいのですが、ここまで調べた段階で個人的には「エラーハンドリングが甘い(=ssh.ParsePrivateKeyWithPassphrase関数の問題)のでは?」とほぼ確信はしていたのですが、普段扱っているわけではないgolangの話だったので、社内Slackの #golang チャンネルにgistのコードを添付して質問して他の人にもチェックしてもらったところ、やはりssh.ParsePrivateKeyWithPassphrase関数の問題だと言われました。

自分で調べているときにも見つけてはいましたが、上記Slackチャンネルでも「以下issueに関係ある話なのでは?」と指摘され、ほぼ間違いなくx/crypto/sshパッケージ自体の問題だと判明。

github.com

何が問題だったかというと、OpenSSH 7.8からssh-keygenで生成される秘密鍵のフォーマットがOpenSSH形式になったのに、x/crypto/sshパッケージではまだそのOpenSSH形式のフォーマットのパスフレーズ付き秘密鍵をサポートできていなかったことがこのエラーを引き起こしていたのです。

自分自身ではこのOpenSSHのバージョン違いによる秘密鍵のフォーマットの差には気がつかなかったので、教えてもらえたことで最終的な原因に気がつけてよかったです。

教えてもらったときに参考に貼ってもらった記事は以下のものがありました。

qiita.com

検証後に気づいたことと感想

こういう風に色々調べきった後に改めて調べ直していたら、本記事の頭に書いたように既にクラスメソッドさんの記事でこの問題に言及されていたことに気づきました。

最初の方で見つけられていれば原因特定が早くなったと思いますが、今回自力で大半の原因を特定でき、分からない所は分かりそうな人に質問して特定するといったフローを実際に実行でき、経験が積めたので、今回はこれでよかったのかなと思います。

余談になりますが、このOpenSSH形式の秘密鍵をgolangで扱いたい場合は、x/crypto/sshに関するissueでコメントされているように、ScaleFT/sshkeysという3rd party製パッケージを使えば出来るみたいです。試したことはないので保証は出来ませんが。

golangの場合、delve(+VSCode)によるデバッグが非常に強力だというのも実感しました。またgolangを使ってデバッグをすることになったら今回の経験を活かしたいと思います。

*1:使ったことがないので憶測です

話題になっているSF小説『三体』を読み終えました

表題の通りで、中国のSF小説『三体』を読み終えました。

評判に違わぬ面白さで、「面白い小説を読みたい。でも自分にとって面白い小説見つけるのは難しい」と思っていた私にとっては、評判に釣られて読んでみてよかったと思います。

そもそも『三体』とは何か?

『三体』とは中国で爆発的にヒットし、海外でも人気となったSF小説です。

三体

三体

私がダラダラと書くより、版元の早川書房さんが書いている以下の記事を読んだ方が分かりやすいですね。というか私も購入前に以下の記事を読んで購入するかどうかの参考にしました。

www.hayakawabooks.com

『三体』を読み始めたきっかけ

会社のSlackのチャンネルに読書好きな人向けのチャンネルがあり、そこで話題になっていたというのが一番のきっかけでした。ツイートした時期を見ると7/10には購入して読み始めたようですね。覚えてないですが。

上記のSlackチャンネルはあまり活発というわけではないのですが、普段から本を読んでいる人が面白かった本を書き込んだりするので、最近情報収集する手間をかけてない私としては積ん読本の候補選びの参考にしています。

今回の『三体』の場合、1人だけでなく、複数人が読み始めて話題にしていたので、その流れに乗ろうと私もAmazonのKindle版購入ボタンをポチッとして読み始めました。

あと、多分に早川書房さんとか書籍関係者、読者の人がこぞって『三体』に関する投稿をネットに投げ込んでいて話題になっているのを見かけたのもきっかけの一つです。

私のようにネットでの話題に影響された人も多かったためか、発売してから一ヶ月も経たずに10万部を突破していたようです。現時点だとさらにどれくらい売れているのか調べていませんが、SFという枠を超えて日本の市場でベストセラーの仲間入りしているのは間違いないでしょう。

www.hayakawabooks.com

『三体』を読んでの感想

私が『三体』を読み終わったのはつい先日なのですが、その時の感想ツイートがこちらです。

読み始めたのが7/10で、途中時間をかけられなくて読み終えたのが9/4と、読了まで2ヶ月近くかかっていることになりますが、最近の私の小説を読み進めるスピードと勢いを考慮すると、これはかなり速いスピードで読み終えていて、それだけこの『三体』という本が面白かったんだなと改めて思いました。

普段練習もしていないので『三体』の面白さを紹介するにはどうしたらいいかよく分からないですが、もしここまでの文章を読んでみてまだ『三体』を読んでない & 梗概レベルの展開を知っても問題ないという人は、『三体』の翻訳に関わった大森望氏のあとがきを読んでみると、『三体』の面白さとその話題性・立ち位置などが見て取れるので、以下の記事に目を通してみるといいと思います。

www.hayakawabooks.com

上記引用したあとがきで大森望氏が記されているように、日本語版『三体』は翻訳に非常に力が入っていて、どれくらい入っているかというと、「原文が中国語で書かれて翻訳されたとは思えない。最初から日本語で書いてある小説みたい」という感想「しか」出てこないくらい自然な日本語訳になっていて、読みやすさが翻訳物なのに段違いにいいというのが個人的に一番好印象なポイントでした。

学生時代英米文学専攻の学科にいて、英語限定でしたが原文と翻訳をそれなりに嗜んできた経験からすると、だいたい翻訳された作品は文体が自然な日本語であってもどことなく「翻訳しました」という匂いが抜け切れてない箇所が発生し、そこが読書の際に引っかかるということが多かったのですが、この『三体』の場合はそれが全くないのが驚きでした。

これには『三体』がSF小説で、たとえ舞台が中国だったとしても内容が越境的になっていたということと、上記引用した大森望氏のあとがきで触れられているように、大森望氏が「翻訳原稿をもとにして、現代SFらしくリライトするというフィニッシュ・ワーク」するという工程があったことの産物なのだと思います。

個人的な推測を語ると、この翻訳物とは思えない読みやすさが『三体』の爆発的なヒットの下支えになっていたのだと思います。

相当の本好きでも無い限り、普段の生活の忙しさに巻き込まれると、いくら読んでいる本が面白くてもちょっとした障害に引っかかるだけで読み通すのが不可能になると私は思っていて、翻訳物特有の「ここ、翻訳した箇所です」といった読みにくさはそういった障害になって読書を妨げることが私の場合多かったので、その読みにくさがないことは『三体』を最後まで読み通す助力となり、その結果ネットに感想を書きやすくなるといった流れが生まれたのかな?なんて思ったりしました。

とまあ、ここまで読みやすさについて書いてしまいましたが、中身は普通に面白く、私みたいなにわかSF好きな人間でも楽しめる間口の広さはありつつ、(おそらく)本格的なSF(なのだろうと思える)描写がふんだんに話を彩っており、早く続きが読みたくなる。『三体』とはそういう作品でした。

今回翻訳された『三体』は3部作のうちの1部のようで、原語である中国語と翻訳である英語版では既に3部まで出版されているとのこと。日本語訳は第2部が2020年に発売予定とあとがきで書かれていたので、今から楽しみ…というか待ちきれなくて中国語版か英語版で先に読み始めようかなと思うくらいです。

『三体』、オススメです。

『ホモ・デウス』上巻を読み終えました

前回の書評記事から大分期間が経ってしまいましたが、読書自体は細々と続けているので、久し振りに書評記事でも書きたいと思います。技術ネタで書ける記事はたくさんあっても正確に書こうとすると労力が必要で疲れてしまうので。

今回扱う書籍はこちらです。

ホモ・デウス 上: テクノロジーとサピエンスの未来

ホモ・デウス 上: テクノロジーとサピエンスの未来

前回の記事で紹介した『FACTFULNESS(ファクトフルネス)』と同じく、こちらも話題の書籍なので、普段読書を嗜まれている方はもう既に読んだ人も多いかと思います。

私はこの著者、ユヴァル・ノア・ハラリ氏の前作である『サピエンス全史』は読もうと思っていながら読むタイミングを失っていたのですが、今作は良いタイミングだと思って読み始めることが出来ました。あと、「『サピエンス全史』は人間発祥の時代から今までを語った書籍、『ホモ・デウス』は今の時代からこれから先のことを語った書籍」という話を聞いていたので、「どうせ読む時間もそんなに捻出できないのなら、過去のことを学ぶよりもこれから先の話を知る方を優先してみるか」と思い、『ホモ・デウス』を読み始めました。

読んでみての感想

内容が大分骨太なので読み進めるのに苦労しましたが、ビジネス書ではない教養的な書籍でこんなにワクワクする書籍はここ数年無かったので、面白く読めましたし、下巻も楽しく読んでます。

私の理解する限り、『ホモ・デウス』上巻に書かれていることの骨子を箇条書きにすると以下のようになります。

  • 人類は有史以来、3つの問題に悩まされてきた。その3つとは飢饉と疫病と戦争である。
  • 人類は有史以来、この3つの問題を解決することが出来ていなかったが、現在に到達し、ようやくこの3つの問題を克服しつつある。
  • 人類の歴史において、飢饉と疫病と戦争が取り組むべき問題のリスト上位にいたが、これらを克服しつつあるということになると、次は何に取り組めばいいのか?

まず最初にこの切り口から入っていく書籍なのですが、筆致の巧みさなのか、それとも論理的な筋書きのなせる技なのか、とにかく筆者が主張する流れが理解しやすいように書かれていて、著者のユヴァル・ノア・ハラリ氏はすごい頭のいい人物なんだなと思いながら読んでました。

極論してしまえば『ホモ・デウス』は著者のユヴァル・ノア・ハラリ氏が考える未来予測にしか過ぎないのですが、彼が出す主張をサポートするデータなり歴史を踏まえて提出される主張を見ると、「この未来予測は本当にそうなりそうな予測だ」という強い予感を感じさせるものが多く、ついつい納得してしまいます。

上記の切り口から語られるにつれ、「老化と死を克服した人類は、次に神性を求めるようになり、自身をホモ・サピエンスからホモ・デウスに変えることを目指すだろう」といった、一見すると突飛に見える内容も思わず納得させられてしまうくらいに説得的ですし、個人的には刺激的な内容が溢れていて読んでいて面白いです。

下巻も早いところ読了して、記事にしたいと思ってます。

Ansibleの変数の優先順位を理解してなくて詰まってしまったという話

TL;DR

基本的に以下の記事の方と同じハマり方をした、という話しです。

qiita.com

詰まった箇所

具体的に言うと、既存のansible roleを使ったplaybookを修正する必要があり、その際デフォルトで以下のようなフラグ変数を用意して、JenkinsのLTSを通常使用するようにしようとしました。

jenkins_lts_use: true

そして、LTSを使用しないサイトでは jenkins_lts_use: false とやって、この変数の値に応じて別の変数(yum repositoryのURLなど)を分岐させるという作りにして動作検証していたところ、 jenkins_lts_use: false とhost_varsに書いたのに上書きされない状態で「何故だ!?」と時間を消費することに。

ちゃんとdebugモジュールを使って変数の値が変わったかどうか確認したところ、私の意図とは違い、 jenkins_lts_use: true という値のままでした。

原因

「これはすっかり忘れてたけど、多分ansibleの変数が使われる優先順位の問題だろうな」と思ったのでインターネットでググったとこ ろ、この記事冒頭で紹介した記事を見つけ、ビンゴでした。

公式ドキュメントでは以下の箇所にあたります。

docs.ansible.com

Here is the order of precedence from least to greatest (the last listed variables winning prioritization):

  • command line values (eg “-u user”)
  • role defaults [1]
  • inventory file or script group vars [2]
  • inventory group_vars/all [3]
  • playbook group_vars/all [3]
  • inventory group_vars/* [3]
  • playbook group_vars/* [3]
  • inventory file or script host vars [2]
  • inventory host_vars/* [3]
  • playbook host_vars/* [3]
  • host facts / cached set_facts [4]
  • play vars
  • play vars_prompt
  • play vars_files
  • role vars (defined in role/vars/main.yml)
  • block vars (only for tasks in block)
  • task vars (only for the task)
  • include_vars
  • set_facts / registered vars
  • role (and include_role) params
  • include params
  • extra vars (always win precedence)

冒頭の記事とこの公式ドキュメントの記述を見た後、私が追加したデフォルト変数はどこに追加したものか確認したところ、role defaults ではなく role vars (defined in role/vars/main.yml) でした。

jenkins_lts_use: false を追加したのは playbook host_vars/* だったので role vars (defined in role/vars/main.yml) より優先順位が低く、この影響で変数が上書きされない状態だったと言うことが分かりました。

jenkins_lts_use: truerole defaults に書くようにして問題解決。

一応対処出来てよかったです。

Ansibleのwhen節で複数行に複数の条件を書くやり方に迷ったので調べた

結論から書くと、以下のように書ける。

when: >
  ('redhat-stable' in repo_url) or
  ('redhat-stable' in repo_key_url) or
  ('redhat-stable' in package_url)

ポイントは以下の通り。以下の説明は細かい検証はしていない or メモしていないので細かい部分で間違っているかもしれないです。

> とか | を使って複数行に書けるようになる

上記のwhenの場合、条件をそれぞれカッコでくくる

そうしないとエラーになった。原因までは調べてない。

when内では変数はそのまま、文字列はクオートでくくる

repo_url がansibleの変数(中身は文字列)の時、 'redhat-stable' in repo_url は問題ないが、 redhat-stable in repo_url はエラーになるということ。

Ansible難しいなと思ったところ

yamlファイル内に書くとき、「こう書きたい」と思った表現が書けるかどうか、以下の知識を持っていないと完全に判断が付けられないところ。

  • Ansible固有の知識
    • when節に書ける法則 etc.
  • Jinja2の知識
  • YAMLの仕様・知識

『FACTFULNESS(ファクトフルネス)』をだいぶ前に読み終えました

平成と令和にかけたゴールデンウィークに突入してるのに「時間が無くて今まで下書き・構想のままのブログ記事書けませんでした」とか流石に言いづらいので、久し振りに書評(というか読書感想)記事を書きます。

題材は、1月の以下の記事を書いたときに読み終えた『FACTFULNESS(ファクトフルネス)』(以下『ファクトフルネス』)です。

FACTFULNESS(ファクトフルネス) 10の思い込みを乗り越え、データを基に世界を正しく見る習慣

FACTFULNESS(ファクトフルネス) 10の思い込みを乗り越え、データを基に世界を正しく見る習慣

  • 作者: ハンス・ロスリング,オーラ・ロスリング,アンナ・ロスリング・ロンランド,上杉周作,関美和
  • 出版社/メーカー: 日経BP社
  • 発売日: 2019/01/11
  • メディア: 単行本
  • この商品を含むブログ (1件) を見る

読み終えたのは以下の記事によると2019/01/19ですね。

takuan-osho.hatenablog.com

早めに読書感想のブログ記事を書きたいと思ってます。

こんなふうに書いてから3ヶ月以上経過してしまっていますね。死です。

読んでみての感想

『ビル・ゲイツやバラク・オバマ推薦!』のような宣伝のされ方をしていた書籍ですが、その人たちが推したくなるのも分かる、良い内容の書籍だと思いました。

正直読んだのが3ヶ月前で復習もしていないので細かいことは忘れてしまっているのですが、だいたい以下のようなことが書いてあったかと思います。

  • 世の中にはデータに基づいていない間違った思い込み・言説に溢れている
  • そういった思い込み・言説は大概刺激的で扇情的な内容が含まれていて、ドラマチックすぎる世界の見方を植え付けてしまっている
  • 一般市民だけでなく、世界をリードする指導者や有識者といった高い教育を受けているはずの人ですらそういった思い込み・言説・世界の見方を信じているという現状が今までの(著者の)講演内での質問により明らかになっている
  • このドラマチックすぎる世界の見方は大抵、「世の中はどんどん悪くなっているか、もしくは以前と同じく悪いままで改善されていない」という世界観に満ちているが、データに基づいて見てみれば、そんなことはなく、世界は段々よくなっていることが分かる
  • こういった世界の見方をしてしまうのは10個の人間の本能による影響が強い(ので、これらの本能に自覚的になる必要がある)

…だいたいこんな感じだったと思います。

少し前にあった統計学ブームや、昨今のフェイクニュースといった背景を頭の中に入れて読んでみると尚面白くな感じる書籍でした。

本の内容の多くは事例が多いので人によっては退屈に感じてしまうかもしれません。

個人的には翻訳された日本語の文章が自然すぎて、読んでいて引っかかりを覚えるところがなかったので非常に読みやすかったです。

読んだ後に感じた疑問

本の内容はとてもいい!という前提で、読書後に以下のような疑問が生まれました。

「政府統計とか公式統計の値自体が信用おけない場合はどうしたらいいんですかね?」という疑問です。

こんなの答えが出ないだろうし、そもそもファクトフルネスの大元のサイトでは答えが出ている話なのかもしれないけれど、やはり気になってしまいます。

というのも、最近日本のニュースでは統計不正や廃棄といった問題が度々報道されているのを目にしているからです。

この記事を書いた直近のニュースだと以下のものが挙げられるでしょうか。

www.tokyo-np.co.jp

本業の研究者でもなければ、データを追うだけでも大変なのに、そのデータ自体が本当に信用できるかどうかを検証する必要もあるなんて状態になっていたら、この書籍に書いてある「事実に基づく世界の見方」を実践するのは事実上無理なのでは?と思わずにはいられませんでした。

あと、これとは別件(?)で、よくある批判に対して翻訳者の方が誠実に答えているエントリもまだしっかり読めていないので、これを読むところから始めた方がいいのかもしれません。

jp.chibicode.com

まとめ

各所で絶賛されているので、逆に今更読まない方がいいかもと思う人はいるでしょうし、私もその考えに同調してしまいたくなる部分はあるのですが、まあ一度読んで損はないと思います。いい本です。

ただ、これを実践するのはかなり大変な類いの本なので、怠け癖の強い私のような人間は「もう日々のデータをアップデートして改訂された版が定期的に欲しい」という、この本で主張されている態度と真逆の態度を取りたくなってしまいますね。

データに基づいて議論したり決定するのは大変だなあと思いました。

何度目か分からないiOSプログラミングへの再入門をまた始めたという話

前回の記事で、前職の同僚にiOSプログラミングを教え始めたという話をしました。

takuan-osho.hatenablog.com

今のところゆるゆると続いていて、私もiOSプログラミングはそこまで深くやったことはないので、教えるついでに自分も再入門しなおし始めました。

以前にもこのブログで何回か言及した記憶はあるのですが、私、iOSプログラミングに入門しては挫折するということを繰り返していて、「今だと10回は超えないが、両手で数えるくらいは入門しては挫折している」という状態です。

今度の再入門がどれくらい続くかは不透明ですが、仕事とは全く関係ない分野だからこそ飽きが来にくいということと、今回は前職の同僚と一緒に勉強しているということもあり、以前よりかは続けられるのではないかと目論んでいます。

前職の同僚に教える際に教材として使っている書籍はこちらです。

本気ではじめるiPhoneアプリ作り Xcode 10.x対応 (Informatics&IDEA)

本気ではじめるiPhoneアプリ作り Xcode 10.x対応 (Informatics&IDEA)

以前iOSプログラミングに入門したときに使っていた書籍の最新バージョンです。

前に使った時に分かりやすいと思ったことと、応用を見据えた事項を抜き出して構成している書籍だったので好印象だったことから選びました。特にWeb APIを利用したアプリ作りを入れているのが好印象でした。

他人にプログラミングを教えていると「ここで詰まると思っていたのに、別のこの場所の方が分かりづらくて詰まるものなのか」とか意外な発見があって、自分も勉強になってます。

次回はこの教えた経験をもとに、(iOS)プログラミング初心者が詰まった事項をコードを交えて少し紹介する記事を書ければいいなと思ってます。