UserDefaults に struct のリストを保存する

環境

Xcode 9.4.1, Swift 4.1

UserDefaults に struct を保存する

UserDefaults に sturct を保存する方法として、Dictionary にマッピングする方法がよく紹介されているが、 Swift 4 からは Codable が使える ので、それらを使えばエンコード、デコードすることができる。
また今回はリストを扱いたいため、map を使ってリストの各要素をエンコード、デコードする。

コード

save array of struct to UserDefaults

Instant Word Power を読んでいる

ここ2週間 Instant Word Power という本を読んでいる。 英語のボキャブラリを鍛える本で、通勤の時間や休み時間を使って1日1章ずつ読んでいる。

Instant Word Power とは

Instant Word Powerは 英語のボキャブラリーを増やすための本。よくある単語帳のような本とは趣が違って、英単語の語源と英単語自体の意味と紐づけて説明することで覚えやすくしようとしている。また語源を学ぶことで、未知の単語の意味を類推することも可能にする。ページのブランクを1つずつ埋めていくクイズ形式になっている。同じ単語を何度も繰り返し扱うことで、知識の定着を助ける。

なぜ Instant Word Power か

先日WWDCに行って、自分の英語力が全然足りないことを再発見した。今時点でライティング、リーディング、リスニング(ほぼ全部か)と強化したいものは沢山ある。その中でも根幹になる語彙が圧倒的に不足しているので、取り組んでみることにした。 自分は暗記ものは大の苦手で、記憶を上手に定着させる方法が必要だった。そこで良い本を探していたところ見つけたのが Instant Word Power だった。

実際やってみてどうか

語源が説明されていることと同じ単語が繰り返し練習させるので、記憶への定着はとてもしやすい。また全編英語だが、短くて平易な文章で書かれているので、高校英語まで勉強した人なら普通に読めると思う。

微妙なところ

古い本だからなのか、一般的にあまり使われないであろう単語も含まれている。たとえば podiatrist(足病医) は日本語でも初めて見た言葉だった。

最後に

今のところ毎日1章読む運用でうまく回っているので、1ヶ月かけて最後まで読み進めようと思う。月末に10数年ぶりにTOEICを受ける予定で、実際使えるものなのか楽しみである。

Instant Word Power

Instant Word Power

try! Swift San Joseの作業メモ

WWDC18 に付随して行われた try! Swift San Jose に参加してきた。前半は Swift コミッターによるパネルディスカッション、後半は Open Source Swift にコントリビュートするというワークショップだった。このワークショップを通して apple/swiftPull Request を送ることができた。

最近読んだ id:higepon さんの ログのすすめ をとても良いと感じていて、ワークショップの作業はログを書きながら行ってみた。ログを残すことによって、自分が今取り組んでいる課題は何か、次に行うべき作業は何か、かなり明確にすることができた。特に Swift コンパイラという普段自分が扱っているコードベースとは全く異なる環境ではかなり助けになる実感があった。 せっかくなので、その時の作業メモを残しておく。


バグチケット

https://bugs.swift.org/browse/SR-7844?filter=10451

<stdin>:3:3: error: computed property must have accessors specified
  }
  ^

こうしたい

<stdin>:3:3: error: subscript must have accessors specified
  }
  ^

ゴール

  • [x]subscript の diagnostics が computed property になっているのを修正する
    • [x]どういう時に出るエラーか
      • getter がない時に出る

分からないこと

  • [x] 開発環境
  • [x] デバッグの仕方
    • バグを再現するテストを書いて、直ったことを確認する
    • PRにはテストが必要
    • テストは短ければ短いほどいい
  • [x]テストの書き方

やること

  • [x] issue に自分をアサインする
  • [x] bug をバイナリで reproduce する
    • ビルドした swift を実行する
      • :0: error: Swift does not support the SDK 'MacOSX10.13.sdk
      • xcode-select で Xcode10beta見るようにしたら直った
  • [x] テストを動かす
  • [x] バグを再現するテスト書く
      - test/decl/subscript/subscripting.swift 173行目
    
  • [x] computed property の方のテストが壊れていないことを確認する
      - test/decl/var/properties.swift 379行目
    
  • [x] どこをどうやって修正するか

    • include/swift/AST/DiagnosticsParse.def
      • 251行目、プレースホルダを使うように文言を修正する
      • "%select{variable|subscript}0 must provide either a getter or “ こういうやつ???
    • [x] %select を使って修正する
    • [x] 呼び元で引数を渡す
      • lib/Parse/ParseDecl.cpp
        • computed propertyとsubscriptを区別する
        • bool Parser::parseGetSetImpl 多分ここにisSubscript を渡さないといけない
        • static void diagnoseRedundantAccessors の引数に isSubscript というのがある (lib/Parse/ParseDecl.cpp 4016行目)
  • [x] 自分の環境に fork して clone する

  • [x] 自分がforkした方に修正を入れる
  • [ ] 自分がforkした方でビルドする
  • [ ] 自分がforkした方でテストを通す
    • [x] fork し直すのではなく、git の remote origin を変更した
  • [x] PRを作る

このようにゴール、分からないこと、やることのアウトラインを先に書いて、作業を進めながら詳細を書き足していった。

swiftc のビルドエラー 'libxml/xmlreader.h' file not found について

swiftc を久しぶりにビルドしたら以下のエラーが出た。

/Users/enomoto/.ghq/github.com/apple/llvm/lib/WindowsManifest/WindowsManifestMerger.cpp:21:10: fatal error: 'libxml/xmlreader.h' file not found
#include <libxml/xmlreader.h>
         ^~~~~~~~~~~~~~~~~~~~

結論を書くと、 libxml 配下のファイルがなくてビルドエラーになる場合、Command Line Tools をインストールできていない。Xcodeのバージョンを上げたので、インストールする必要があった。

Command Line Tools のインストール

$ xcode-select --install

再度ビルド

$ ./swift/utils/build-script -Rt

無事ビルドが通った。

環境

WWDC18に参加した

f:id:enmtknt:20180603131544j:plain

6月4日〜8日にカリフォルニア州サンノゼで開催されたAppleの開発者向けカンファレンス、WWDC18に参加してきた。WWDCは今回が初めての参加で、他では得がたい経験をたくさんすることができた。 今回、渡航準備をするにあたって以前WWDCに参加した方のブログ記事を参考にさせてもらったので、この記事もこれから参加する方に役立つ内容にできたらと思う。

良かった事

WWDCのお祭りのような雰囲気を生で体験できる、最新の情報を現地で得ることができるというのは魅力的だが、以下のような点が現地に行ったからこそできた経験だと感じた。

  • Appleのエンジニアに直接質問できる
  • 他のエンジニアと交流できる
  • 情報収集のアンテナを得た
  • 業務にとらわれない集中した時間

Appleのエンジニアに直接質問できる

会期中はAppleのエンジニアに直接質問できるラボが開催される。仕事で解決できず困っていた事象について相談しに行ったところ、あっさりと解決してしまった。技術的な質問以外にも、アプリのデザインに関するアドバイスを受けられたり、初心者向けのラボもあり、Appleのエンジニアに直接質問できる貴重な機会だった。後述するtry! Swift San JoseでもSwiftコンパイラチームのエンジニアから直接手ほどきを受けることができた。

他のエンジニアと交流できる

現地で沢山のエンジニアと知り合うことができた。技術的な会話をしたり、普段どのように開発をやっているかを話したり、情報交換をした。話を聞いたところ多くのエンジニアが会社負担、業務扱いでWWDCに参加していて、そういう文化がもっと当たり前になればいいと思っている。ちなみに僕も今回の渡航費と参加費は会社に負担してもらった。

情報収集のアンテナを得た

オフィシャルのドキュメントがなんだかんだ一番参考になるということ、WWDCのビデオをちゃんとチェックすれば詳細な情報を得ることができるということを改めて実感した。普段ついQiitaやStack Overflowを見がちなので、一次情報をしっかり確認する癖をつけたい。

業務にとらわれない集中した時間

人によるとは思うが、普段1つの技術について突き詰めて考える長い時間を確保するのは難しいと思う。普段の業務だったり、生活に関するあれこれだったり。そういうものにとらわれずに色々考えを巡らせたり、新しい技術を試す期間を持つことができるというのはとても貴重なのではないか。

f:id:enmtknt:20180604130033j:plain

準備と現地での過ごし方について

航空券

渡航の際の航空券について。当選が決まり次第なるべく早く押さえた方が良い。僕はHISでLA経由のチケットを手配してもらった。またアメリカへの渡航に際してはESTAの登録が必要になる。これは申請から登録まで少し時間がかかるので早めに登録を行っておくと良い。インターネットで簡単に申請できる。

宿

世界中から開発者がサンノゼに集まるので、これも当選が決まり次第なるべく早く押さえた方が良い。当選してから数日後に探し始めたが目ぼしいホテルはほとんど埋まっており、Airbnbで予約した。宿泊した場所は会場から車で10分程度のところだったが、とても綺麗で過ごしやすかった。必ずしもホテルが良いとは言い切れないように思う。会場から近い方が楽なのは間違いない。

移動手段

現地で会った人たちでは、UberLyftを使っている人が大多数だった。僕はレンタカーを手配したが、アメリカで運転するのはとても神経を使うし、借りるにもそれなりのお金がかかる。滞在の後半はUberを何度か使ったが、すぐに来てくれるし料金は安いし、すごい体験だった。
ちなみにレンタカーを運転する場合は国際免許が必要になる。免許センターに行けば、手続きだけで即日発行することができる。

インターネット環境

iijmioの海外旅行用のSIMを事前に契約していったが、結果的にはあまり筋が良くなかった。早々に容量が足りなくなり、AT&Tのショップに足を運んでSIMを契約した。国内でT-Mobileのツーリストプランを契約してきていた人もいた。 ちなみにWWDCの会場はWi-Fiが飛んでおり、普通にインターネットができる。作業スペースも大きく確保されていて、そこに行けば有線でネットワークを使うことができる。

持ちもの

発表された新しいOSをインストールするために、以前使っていたiPhone 5s, 6sを持って行った。それ以外は Quoraの記事 を参考に荷造りをした。また会場内はかなり強めに空調が効いていて、夜は冷えるので、春秋に着るぐらいの上着は持っていくとよい。

お金

サンノゼはほとんどの店がクレジットカードに対応しており、現金を使う機会はあまりなかった。クレジットカードがあるならば、不測の事態に備えて幾らか持っておくくらいで問題ないと思う。

日程、レジストレーション

WWDC本編は月曜から金曜までの開催となる。入場のためのレジストレーションは開催前日の日曜から毎日可能だ。月曜は朝からKeynoteがあるため、Keynoteで良い席を確保するために早朝から並ぶなら、日曜日に必ずレジストレーションしておくことを勧める。

周辺イベント

WWDC開催期間中は周辺で様々な技術イベントやミートアップが開催されるので、事前に調べて参加登録しておくと良い。僕は最終日の金曜は try! Swift San Jose に参加した。try! Swift San JoseではSwift open source projectにコントリビュートするというワークショップが行われ、以前からSwiftコンパイラのコードを読んだりしていた自分としてはとても興味が惹かれるイベントだった。AppleのSwiftコンパイラチームの方や日本人のメンターの方に質問しながら、Swiftコンパイラにコントリビュートすることができた。この時の話については別エントリでもう少し細かく振り返ろうと思っている。

またカンファレンス以外に、WWDC渡航した日本人エンジニアのミートアップや、現地で働く日本人エンジニアの飲み会に参加させてもらう機会があった。こういった場で多くの新しい出会いがあったので、積極的に参加すると楽しいと思う。

おわりに

今回、幸運にも当選したことや家族や職場の協力があって初めてWWDCに参加することできた。来年以降ももし機会があればまた参加したい。

f:id:enmtknt:20180605154622j:plain

WWDC18 Keynoteメモ

WWDC18 Keynote

Keynoteの内容を書き下したメモ
https://developer.apple.com/videos/play/wwdc2018/101

tl; dr

  • 新しいハードの発表は無し
  • 今回のリリースは最適化、セキュリティの改善を強調しており、OSの基盤を固めるリリースと言える
  • AR, 機械学習分野の強化がなされた(ARKit 2, Creating ML, Metal 2)

iOS

iOS12

  • 大幅な最適化がなされた
    • iPhone 5Sのような古い端末でも滑らかに動くことを強調していた
    • iOS 11よりも速いとのこと
  • ARアプリ
    • ARKit 2
    • メジャーアプリ
      • カメラを起動して、画面に写ったものを採寸できる
  • 写真アプリ
    • search, suggestion, for you, share
    • 機械学習を基盤にした各種機能が追加される
  • SiriKit Shortcuts
    • キーワードを登録できる
    • Siriからアプリ操作するショートカットを作成できる
  • Shortcuts app
    • IFTTTみたいに複数のアプリをピタゴラスイッチのように連携できる
    • 以前買収したWorkflowが本家に取り込まれた形
  • ニュースアプリ
    • personalized, secure, trusted
  • 株価アプリ
    • ニュースアプリと連携できる
  • ボイスメモアプリ
    • iPadでも使えるようになった
  • iBooks
    • Apple Books になり、アプリが一新
    • ebook, audio book
  • CarPlay
    • 新しいマップアプリがサポートされた
    • google mapなど
  • Do Not Disturb
    • 特定の期間通知をOFFにすることができる
  • Grouped Notification
    • 通知をまとめて表示する
      • アプリ毎
  • Screen Time

    • アプリの起動時間、通知を確認できる、アプリの使用に時間制限をかけられる
    • 子供のアクティビティを監視できる
    • 子供の端末をより安全にセットアップできる
  • Animoji, tongue

    • iMessageで動くアニメを送れるように
  • Memoji
    • Animoji をカスタムして自分の似顔を作れる
  • FaceTime
    • 32人まで同時に使えるようになった

watchOS

watchOS 5

  • competition, Awards
    • 友達と競える
  • Walkie-Talkie
    • AppleWatch を使ってメッセージを送れる
  • WatchOSだと "Hey Siri" 言わなくてよくなる
  • WebKitサポート
  • Podcasts アプリがリリースされる
  • 学生向けのID管理機能がリリースされる、6大学に対応

macOS

macOS Mojave (モハべ)

  • Dark Mode を搭載する
  • Dynamic Desktop
    • 壁紙の色が時間帯によって変わる
  • Stacks
    • デスクトップのアイコンをまとめられる
  • Gallery view, Quick Actions
  • Quick Look , macOSのビューアアプリで画像、動画pdfをさくっと編集できる
  • Screenshots , video recording
    • iPhoneMacのスクショをシームレスに扱える
  • ニュース、株価、ボイスメモ、ホームアプリがMacアプリに提供される
  • macOSFaceTimeも 複数人に対応
  • セキュリティの強化
    • ユーザの設定次第でWebサービスからのトラッキングを完全にOFFすることができる
    • 強度の高いパスワードを自動生成し、管理する機能が強化された
  • Mac App Storeがリニューアル

tvOS

Technologies

ReSwiftをためした所感

現在仕事で開発中のiOSアプリにReSwiftを導入できないか検討した。

結論としては今回は導入を見送ったが、良いと感じた部分が沢山あったので雑な作業メモを転記する。

ReSwift とは

Redux は複雑な状態を管理するために生まれたJS発祥の技術

そのRedux をSwiftに移植したものがReSwift

ReSwift/ReSwift: Unidirectional Data Flow in Swift - Inspired by Redux

こちらに大変わかりやすくまとまっている

ReSwiftでアプリの状態管理 / Reactive Swift Meetup // Speaker Deck

モチベーション

  • アプリ全体で共有する状態の管理をうまくしたい
  • グローバルなスコープのシングルトンにアプリの様々な箇所からアクセスするのは不健全な気がした

インストールから簡単に使うところまでの作業メモ

まずは以下のリポジトリをそのままアプリに移植し、それを拡張していった

ReSwift/CounterExample: Demo Application of Unidirectional Data Flow in Swift, Built with ReSwift

ReSwift を Cartfile に追加

$ carthage update --platform iOS --no-use-binaries

ReSwift の設定をプロジェクトに反映

AppState を作成

  • アプリ全体の状態を持つ
  • Action からしか変更できない

CounterReducer を作成した

  • counterの状態を変更する Reducer
  • AppState を返す状態を持たない関数

Actions を作成した

  • Action protocol を実装した struct として定義する

  • subscribe すると、最初に newState が呼ばれて現在の state が降ってくる

  • 最初の state は 特に action をdispatchしていないので、ReSwiftinit 型になっている
  • action を dispatch すると、その結果また newState が呼ばれて状態の更新が通知される
  • subscribe しないで dispatch することもできる

    • 状態は変更できるが、newStateに通知されない
  • ネットワークエラーでアラートを出したいときはどうする?

    • ErrorActionを発行して、subscribeしているViewControllerで新しいstateに応じてエラーを表示する

アプリアーキテクチャに関する考察

  • MVP(Clean Architecture) に適用する場合

    • ビジネスロジックをUseCaseの代わりにActionに書いて、それをPresenterから呼ぶ
    • StateはPresenterでsubscribeする
    • ビジネスロジックは Action にとどめておいて、 Reducerは状態の管理に徹する
    • newState に降ってくるイベントは今まで通りViewControllerにdelegateする
  • Redux にすることで、今までdelegate とかクロージャでばらばらに受け取っていたコールバックを1つのメソッドで、1つの状態として扱えるようになる

引数とメソッド呼び出しについて

  • データを fetch するaction で引数にデータを渡さなくても、クロージャのstate を通じて、欲しい状態を取れるようになる
  • ようするにグローバル変数と変わらないのだが、状態の変更 をAction, Reducer を用いるよう制限することで、データの流れを把握しやすくする

Promise を使った非同期処理の連結

Reducer の分割について

How could i use multiple reducer in Reswift 4.0.0 · Issue #241 · ReSwift/ReSwift いいかんじ

ユニットテスト

まだ書いたことはないが、Action は基本的に状態を持たないのでテストは書きやすそう

デバッグのしやすさ

  • クラッシュした時のStateをキャプチャできるので、再現してデバッグするのが簡単になるのではないか
  • ReSwift Recorderという仕組みもある

やめた理由

  • 今後自分以外の人も保守することを考えると、ReSwiftにロックインされるのはあまり良くない
  • 今開発中のアプリは大量の状態を持っているわけではないので、現状の要件にはそこまでマッチしていない
  • newState の取り回しが若干面倒な気がしている
  • pros が cons を上回るなら導入も吝かではない
    • もう少し練度が上がればスムーズに使っていけるのかもしれない