技術用語メモ
新しく知った技術用語とかをダンプするようの記事。
Capistrano
Rubyによる構成管理ツール。AnsibleのRuby版っぽいイメージ?
用語を知った場所:
Capistranoを使ってS3等からpull型デプロイするgemを書いた、ほか — Mobage Developers Blog
GCP
Google Cloud Platform。 いわゆるGoogleが提供してるクラウドサービス。
Kubernetes
複数のDockerコンテナを管理するツールで、Googleが開発を始めたもの。
Docker単体では実現できない以下のような機能を提供する。
(オーケストレーション)
- 関連するコンテナのグルーピング
- コンテナに振られるIPアドレスの管理
- コンテナ間のネットワークルーティング
などなど
関連記事:
knowledge.sakura.ad.jp
GKE
Google Container Engine。
複数のDockerコンテナをKubernetesで管理するクラウドサービス。
GCPだとGoogle Cloud Platformと被るので、KubernetesのKを取ってGKEとなったらしい。
関連記事:
ブログをGKEでの運用に移行した | tsub's blog
セキュリティ
ソルト
憶測されるデータからハッシュ値を衝突させて元データを特定する、といった攻撃に対処するもの。
例えば、ハッシュ値が連番であると予想された場合、連番からハッシュ値を生成して一致するか確認することで総当りで元データが特定できてしまう。
それを避けるために元データに何らかの文字列を付与しておくことを「ソルト」という。 例えば、99xxyyzzとか元データ(今回は99)に対して特定の文字列(今回はxxyyzz)を付与する。
ソルトも当然ながら憶測されにくい文字列である必要がある。
関連記事:
speakerdeck.com
RubyでConsリスト
試しに書いてみた。 もうちょっと良い書き方ありそう。
ちなみに三項演算子を使おうとも思ったけれど、 xxx.nil? ? ...
という感じで?
が連続して違和感抜群だったので使わなかった。
メタプログラミングRuby第二版::一章 - 頭文字M
メタプログラミングRubyを読んで、理解のために自分なりにまとめていく。
基本的にテストコードをRSpecで記述していく。
メタプログラミングとは?
コードを記述するコードを書くこと。
Rubyは実行時にクラスやメソッド、インスタンス変数など、様々な情報を読み書きできるのでメタプログラミングに適している。
C/C++などの言語では、実行時には変数やメソッドなどの実体は消えてなくなってしまうので、プログラム実行中にそれらの情報にアクセスして何かすることは出来ない。
Javaについては、リフレクションを利用してクラスやメソッドの情報にアクセスすることが出来るが、Rubyほどに変更を加えることは出来ない。
Rubyはコンパイル時・実行時などの明確な区別がなく、あらゆる言語要素が常にそこにあり、操作できるといえる。(これはLispと同じ思想といえる)
ちなみにObjective-Cも(Rubyほどではないかもしれないが)動的にメソッドを追加したり、差し替えたり(Method Swizzling)、解決できなかったメソッド呼び出しを自分で解決する手段を用意しており、ここまで上げた言語のなかではメタプログラミングが得意と言える。
魔術
Rubyにおいてメタプログラミングを使った技法は「魔術」と言われる。
魔術には良いものと悪いもの、すなわち「白魔術」と「黒魔術」が存在する。
Rubyは全面的にプログラマを信用し、言語側で安全のためにブロックしたりするという考えは持っていない。”プログラマはミスを犯す”という視点に立って、安全性を重視しているJavaとは対照的と言える。
イントロスペクション
実行時に言語要素にアクセスすること。 JavaではリフレクションAPIを利用してアクセスする。
プロダクションコード:
class Greeting def initialize(text) @text = text end def welcome @text end end
テストコード:
require 'spec_helper' require 'introspection' describe 'introspection' do let(:greeting) { Greeting.new('hello') } it 'クラス名が取得できること' do expect(greeting.class.to_s).to eq 'Greeting' end it 'インスタンスメソッドの一覧が取得できること' do # 引数の`false`は継承したメソッドは対象にしないという意味 expect(greeting.class.instance_methods(false)).to eq [:welcome] end it 'インスタンス変数の一覧が取得できること' do expect(greeting.instance_variables).to eq [:@text] end end
テストコードにあるように、以下の情報がgreeting
インスタンスから取得できている。
ActiveRecordの例
ActiveRecordは Ruby on Rails で使用されているORMapperである。
以下はmovies
テーブルのレコードに対応するEntityクラスを定義した例である。
class Movie < ActiveRecord::Base end
このように特定のクラスを継承するだけで実現できる。
テーブル名はクラス名Movie
から取得し、カラムに対応するアクセサメソッドはDBのスキーマから取得し、実行時に動的にクラスに対してメソッドを追加することで実現できている。
実行時に情報が消えてしまうC/C++のような言語ではこのようなことは出来ず、ボイラープレートが増えてしまう。もちろんコードジェネレータを使用した「静的メタプログラミング」も可能だが、それは言語の外で行われるもので、プログラム実行時に行える「動的メタプログラミング」ほどスマートではない。(ジェネレータを実行する手間もあるだろうし、コード上からボイラープレートコードは消えない)
Rubyにおけるメタプログラミングは特殊ではない
MongoDBメモ(その1)
dot install のレッスン動画を見ながら勉強。
http://dotinstall.com/lessons/basic_mongodb_v3/35001
この記事の範囲。 - 01 MongoDBとはなにか? - 02 MongoDBをインストールしよう - 03 用語を理解しておこう - 04 データベースを操作してみよう - 05 コレクションを操作してみよう
概要
インストール
yumリポジトリを登録
リポジトリファイル作成
$ sudo vi /etc/yum.repos.d/mongodb-org-3.4.repo
記述内容
[mongodb-org-3.4] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
yumでインストール
$ sudo yum install -y mongodb-org
起動
以下のコマンドで起動。
$ sudo service mongod start
次回以降も自動的に立ち上がるように設定。
$ sudo chkconfig mongod on
バージョン確認:
$ mongo --version
用語
階層構造
- Database
- Collection
- Document
- Collection
RDBに対応させると
- Database = データベース
- Collection = テーブル
- Document = レコード
データ格納
JSON形式で格納される。
{field: val, field: val ...}
MongoDBではキーのことをfield
と呼ばれることもある。
スキーマレスなのでDocumentの項目があったりなかったりしても大丈夫。
{name: "yusuke", score: 30} {name: "hosonuma", score: 58, team: 3}
データベース操作
アクセス:
$ mongo
データベースの一覧を表示
> show dbs; admin 0.000GB local 0.000GB
データベースの作成・切り替え
> db.createCollection("users"); { "ok" : 1 }
コレクションが存在しないとshow dbs;
では表示されないので注意。
> show dbs admin 0.000GB local 0.000GB
コレクションの作成
db.createCollection()
で作成。
> db.createCollection("users"); { "ok" : 1 }
コレクションが作成されればshow dbs;
で表示される。
> show dbs; admin 0.000GB local 0.000GB mydb 0.000GB
状態を確認する
db.stats()
で確認出来る。
> db.stats(); { "db" : "mydb", "collections" : 1, "views" : 0, "objects" : 0, "avgObjSize" : 0, "dataSize" : 0, "storageSize" : 4096, "numExtents" : 0, "indexes" : 1, "indexSize" : 4096, "ok" : 1 }
DBの削除
db.dropDatabase()
で現在のデータベースを削除する。
> db.dropDatabase(); { "dropped" : "mydb", "ok" : 1 }
mydb
が削除されている。
> show dbs; admin 0.000GB local 0.000GB
コレクションの操作
作成
db.createCollection()
で。
> db.createCollection("users"); { "ok" : 1 }
一覧表示
show collections;
を使う。
> show collections; users
リネーム
データベース名.Collection名.renameCollection("新しい名前");
。
オブジェクト指向っぽいAPI。
> db.users.renameCollection("customers"); { "ok" : 1 }
ドキュメントの操作
挿入
ドキュメントを挿入すれば、コレクションは自動的に作られる。
格納するデータはJSON形式で記述する。
> db.users.insert( ... { ... name: "taguchi", ... score: 30 ... } ... ); WriteResult({ "nInserted" : 1 }) > show collections; users
スキーマレスなのでデータ構造が違っても大丈夫。
> db.users.insert({ ... name: "fkoji", ... score: 50, ... tags: ["web", "mobile"] ... }); WriteResult({ "nInserted" : 1 })
JavaScriptを使う
JavaScriptを使って処理を記述できる。
> for (var i = 0; i < 10; i++) { ... db.users.insert({ ... score: Math.random() ... }); ... } WriteResult({ "nInserted" : 1 })
件数表示
> db.users.count(); 12
一覧表示
_id
は MogoDB が自動的に振る一意なID。
> db.users.find(); { "_id" : ObjectId("58c5458ca48b064d97084189"), "name" : "taguchi", "score" : 30 } { "_id" : ObjectId("58c545baa48b064d9708418a"), "name" : "fkoji", "score" : 50, "tags" : [ "web", "mobile" ] } { "_id" : ObjectId("58c545d2a48b064d9708418b"), "score" : 0.30322503633107833 } { "_id" : ObjectId("58c545d2a48b064d9708418c"), "score" : 0.5613546607214355 } { "_id" : ObjectId("58c545d2a48b064d9708418d"), "score" : 0.2844040596878158 } { "_id" : ObjectId("58c545d2a48b064d9708418e"), "score" : 0.9263121937224452 } { "_id" : ObjectId("58c545d2a48b064d9708418f"), "score" : 0.5939208256213909 } { "_id" : ObjectId("58c545d2a48b064d97084190"), "score" : 0.5308342673704005 } { "_id" : ObjectId("58c545d2a48b064d97084191"), "score" : 0.8924712820338384 } { "_id" : ObjectId("58c545d2a48b064d97084192"), "score" : 0.9430223426794738 } { "_id" : ObjectId("58c545d2a48b064d97084193"), "score" : 0.6797531592023286 } { "_id" : ObjectId("58c545d2a48b064d97084194"), "score" : 0.9737296169048628 }
削除
条件を指定しない場合は、以下のように空のJSONを渡す。
> db.users.remove({}); WriteResult({ "nRemoved" : 12 }) > db.users.find();
try! Swift 2017 Tokyo に参加してきた - 2日目:午前
さて2日目です。
https://www.tryswift.co/tokyo/jp
1日目と同様にその場でのメモと感想を書いていきますが、ちょっとボリュームが大きいので午前・午後の2つに記事を分割したいと思います。(個人的に見返しやすくもあるので)
テスト可能なコードを書くということの2つの側面
メモ
- 冒頭
- なぜテストをするか?
- テストできるコードだけテストする
- 関数型で書くのは良い
- テストをドキュメント化する
- エッジケースも十分に考慮する
- compute(file:) -> Int
- 単純に見えてもいろんな値を参照している
- Bundle
- String(contentsOfFile:)
- 副作用がある
- Consoleへ出力
- なぜテストしづらいか?
- ハードドライブという外部の状態に依存する
- コンソールへの出力を確認する必要がある(外部に影響を与えていないか)
- 2つの世界
- インプット
- アウトプット
- 単純に見えてもいろんな値を参照している
- 副作用
- OUTPUT
- 我々は慣れているので考えやすい
- 影響がないか確認する必要がある(それ単体ではなく連鎖的に反応していないか)
- 副作用のあるコードを境界部分にのみ持ってくる
- 戻り値をIntの代わりに(Int, String)にしてコンソール出力を無くす
- INPUT
- Co-effects - 共作用
- INPUTは共作用のテスト
- 他のグローバルな関数を参照している
- Co-effects = アウトプットを出すための前提条件
- 言い換えると、それがないと結果を出せないようなもの
- やりかた
- すべてをstructに入れ込む
- apiService: ServiceProtocol
- cookieStorage: HTTPCookieStorageProtocol
- currentUser: User?
- dateType: DateProtocol.Type
- language: Language
- mainBundle: BundleProtocol
- reachability: SignalProducer<Reachability, NoError>
- scheduler:
- userDefaults: UserDefaultsProtocol
- 日付を取るのはCo-effectsのわかり易い例
- 日付を参照すると副作用がある
- バンドルも当然Co-effects
- 通信状態も
- Rxにおけるスケジューラも
- 当然UserDefaultsも
- すべてをstructに入れ込む
- リファクタリング
- バンドル
- 成功 or 失敗
- 全部引数に持ってくる
- 宣言が複雑にみえるけれど副作用が宣言部分に集約されている
- セルフドキュメンテーションに繋がる
- バンドル
- Co-effects - 共作用
- OUTPUT
- 結論
- なぜテストが難しいかというとCo-effectsがある
- グローバルに自由に参照しないように、strutctを用意して、それを利用するようにする
- そこに副作用をすべて集約する
- FAQ
- 1
- バグレポート = 失敗したテスト
- テスト駆動をよくやっている?
- 2
- ReaderMonad / StateMonad
- あまり意識していない
- プロパティベースのテストを行うのか
- やりたいとは思っているが、まだ行っていない
- ReaderMonad / StateMonad
- 1
断片メモコード
ファイル名を受け取って、その行数を返す関数
file: String = "number.txt" -> compute(file:) -> Int (12345)
感想
どうやって品質の良いテストコードを書くか、という話。
テストするための2つの要素「インプット」「アウトプット」について非常に詳しい説明がありました。もっとも一般的な入出力の話ではなく、副作用についての話でした。
発表者も言われてましたが「アウトプット」、例えばDatabaseやファイルを書き換えたり、iOSであればUserDefaultsを書き換えたり、という副作用は考え慣れているので簡単だけれど、「インプット」についてはあまり考えなかったりする、とのこと。
その前提条件となる「インプット」のことを「Co-effects(共作用)」というらしいが、それは最近の研究で話に上がってきたものらしく、あまり広まっている用語ではない模様。具体的には「現在時刻」などがわかり易い例で、アウトプットを出すための前提条件となるものが「共作用」と呼ばれるようです。グローバル関数もその例に当たる、と。
ではどうやって解決するかというと、インターフェースをプロトコルとして宣言して、そのプロトコルを引数として全部渡せば良い、とのこと。
たしかに関数の宣言は複雑になってしまうけれど、副作用がその一箇所に集約されるので、結果的に品質が安定するとのこと。(副作用のあるコードを境界部分のみに集約する)
そしてテストではなく実際の値を返すプロトコルの実装群は、グローバルなStructにまとめておくと良いとのこと。
などなど、私にとっては得るものが大変多いセッションでした。
ちなみに質問でReaderMonadを使わないのか、プロパティベースのテストは行っているのか、といった、非常にレベルの高い質問がされていました。
誰もが知りたいSequenceとCollectionのすべて
メモ
- 構造
- BidirectionalCollection
- Collection
- Sequence
- Sequence
- Collection
- 要件
- Sequenceを引き継ぐ
- 有限
- 何回もIterateできる(Sequenceは1回)
- 実装
- Indexを持つ
- start / end
- APIErrorCollection
- privateだとアクセス出来ないので?
- 要件
- BidirectionalCollection
- 要件
- Collectionを引き継ぐ
- 前にも戻れる
- 実装
- afterに加えてbeforeが追加される
- 要件
- 他
- RandomeAccessCollection
- その値に直接
- RangeReplaceableCollection
- 中間値を変換?
- Appleのドキュメントを見ればいろいろ分かる
- RandomeAccessCollection
- FAQ
感想
Swift の Iterator、Sequence、Collection、BidirectionalCollection について、どんな感じになっているのか詳しく見ていこう、という話。
微妙に理解が怪しい部分だったのだけれど、順を追った分かりやすい説明だったので、頭が整理されたような気がします。
個人的には xs.filter(predicate).count
ではなく、 xs.count(predicate)
という書き方が勉強になりました。もしかしたら Advanced Swift あたりで一度見ていたかもしれないけれど。
あとは EachPair の実装方法も面白かったです。
簡単にまとめると、以下のような感じでしょうか。 - Iterator:任意の値列を返す - Sequence:1回だけIterateできる - Collection:複数回操作できる - BidirectionalCollection:前にも戻れる
もう一度自分でコードを書いて、理解を深めておきたいところです。
様々な場面でSwiftを使う
メモ
- Apple以外のプラットフォームの話
- サーバサイドSwift / ライブラリ
- OSS
- Apple以外のプラットフォーム
- Web
- マイクロサービス
- Deamon、Utility、Tool
- なぜ?
- 型付けされている
- サーバサイドSwift
- 個人プロジェクト
- ポイント
- SPM
- Node.jsのnpmに似ている
- シェバンで使うと簡単なスクリプトとしても使える
- まとめ
- 安全で効率的
- OSS
- Cベースのライブラリ使える
- FAQ
感想
Swiftをサーバサイド(Mac、Linux)やボードコンピュータ(ラズパイ)とかで動かす、という話。既存のPythonのAPIの設計がイケてなくてパフォーマンスも改善したかったので、せっかくだからSwiftを使ってみた、とのこと。
他のセッションでもあったけれど、C言語のABIが安定していて、かつSwiftがLLVMを利用しているので、既存のC言語の資産を使えるとのこと。
実際にSwiftで開発したことで、いろいろと面倒なこともあったのではないかと思うけれど、そのあたりの話があまりなかったので、実際のところはどうなのだろうとは思います。
ただ実績として20日間動いているとのことなので、サーバサイドSwiftはもう実プロダクトとして利用できるレベルには達したのかな、と感じます。
⚡️🎤 VRの革新と新たなユーザー体験
メモ
- VRをゲーム以外でも
- 360°のVRが重要になってきている
- ティム・クックはARは重要だと発言している
- 事例
- ショッピング(Alibaba)
- VRショッピング(自宅にいながら有名なショップで買物)
- 不動産
- 360°の写真を取って、それを見られるようにする
- 自動車
- デザインやアクセサリの変更
- 美しい形式でのドライブ
- 店舗のスペース削減にも
- ニュース・メディア
- 360°の放送
- 自らが実際に居るような体験ができる
- NewYork Times
- 運動
- スケートのイメージトレーニング
- 実際に効果があるとのこと
- ショッピング(Alibaba)
感想
VR(AR)が実際にどのような箇所で効果的に利用されているか、という実績紹介。
個人的にあまり強い興味は持っていない分野だったのだけれど、かなり身近になってきたし、うまく活用すれば良いサービスが提供できるのだと感じた。
iOSにおけるDocument IndexingとApp Search
メモ
- 検索をアプリ内で
- App Search → ほとんど使っている人がいない
- App Search API
- Core Spotlight API
- private
- 大量のデータの時に便利
- 重要な属性
- expirationDate(有効期限)
- attributeSet(SpotLightで可視化)
- uniqueIdentifier(まとめて管理が便利?)
- プラクティス
- 非同期でバッチ処理をする
- コンテンツを常に最新にしていく
- Search Continuation(from iOS10)
- アイテムを探す時に便利?
- 注意
- beginBatch()はバックグラウンドスレッドで動く
- beginBatchするまえにendBatchしないとクラッシュ
- どうやってテストするか?
- 開発者設定 > すべてのアイテム?
- シミュレータでは機能しない(ので実機でテスト)
- NSUserActivity
- 見えるものだけが対象になる
- SearchebleItem
- Universal Link
- Webページからアプリへ直接遷移
- Core Spotlight API
- 統合する理由
- コンテンツへのアクセスが速くなる
感想
iOS9からのAppSearchについて、実装方法とかの話。
個人的にはAppSearchはそれほど良い使われ方をしているように感じないので、まぁ効果的だと感じる人もいるのだなぁ、というくらいの感想でした。
ただ実践でのノウハウが共有されたのはありがたいと感じました。
スタートアップのSwift
メモ
- Swiftの現場での経験(初心者からはじめて1年間)
- スタートアップ
- スタートアップは0から新しいものを作る、それもすぐに
- 製品の様々な面を自分たちでカバーする必要がある
- どうやって作るか?
- Parse + Swift = Fast (To write)
- CocoaPodsでいろんなOSSがあったので活用できた
- リリース
- 最初の2週間で10万人
- 予想外の人数
- 問題
- 秒間リクエスト数を超えてしまった
- リクエストを絞込
- お金を払っても解決しなかった
- 地域も絞る
- Slackとテストフライトでフィードバックを得られるように
- CEOがSlaskでクラッシュ解決を募集(再現している人)
- 一人来てくれたのでiPhoneを繋いで調査した
- ユーザ名が入っていなかった
- 他に問題
- 強制アンラップを使用しないように
- switchのデフォルトシンタックス
- 最初だから知らなかった
- Extension
- コードベースの改善に便利だった(丸くする、とか)
- 最初に書いたコードは捨てる時期にもなってきている
- Parseが閉じるアナウンス!
- Swiftのバージョン移行は大変だった
- Swiftの学習カーブは低い(短期間で習得しやすい)
- 秒間リクエスト数を超えてしまった
感想
スタートアップで Swift + Parse を利用した結果、サービスがどのように成長し、どのようなトラブルに巻き込まれかというリアルな話。
使いたいからではなく早く作るために Swift + Parse を採用し、その結果としてスケールしない問題に出くわしたり、それを解消するためにどのような対策を取ったのか。クラッシュの原因が分からない問題に対して、Slackでユーザを募集したり、そこからのフィードバックをいかに反映したか。そして Parse が閉じる事になった時に、どのようにデータ移行を行ったか。
などなど、非常に貴重な話を聞くことが出来ました。
外部サービスに依存した場合のリスクという話は以前からも聞いていましたが、今回の発表を聞いてそういったことが実際にあるのだという実感がわきました。
またクラッシュを解消するためにSlackでユーザを募集するというのは衝撃を受けました。日本でそんなことはまず出来ないと感じたからです。
try! Swift でスタートアップのリアルな話が聞けるとは思わなかったので、思わぬ誤算という感じのセッションでした。
try! Swift 2017 Tokyo に参加してきた - 2. 1日目
1日目の内容を感想を混ぜつつまとめていきます。
https://www.tryswift.co/tokyo/jp
通訳で聞いた内容で、ちゃんと聞き取れなかった箇所もあったと思うので間違っている箇所もあると思います。
なお迷ったのですが、箇条書きについては発表の場で書いたものをそのまま載せています。なのでたぶん講演を聞いていないと、あるいは聞いていても分からないような表現もあるかもしれませんがご了承ください。(まぁそこは自分用のブログなので、ということで)
一見して不要な情報に思えても、あとから見るとそうではないこともあると思うので。
Swift開発者が知りたかったけど聞きにくい機械学習のすべて
メモ
- 機械学習、最新の技術をキャッチアップしていくのは大変。
- データを集めて、関数を定義。
- 誤差 → エラー
- 線形回帰?
- 驚くような結果を出すので、みんな熱中してる
- Swiftの開発者にどんな関係があるか?
- AVFoundation、CoreImage
- 遅延実行モデル?
- UIと同じように正確ではない(ユーザに見せてみるまで分からない)
- どこから始めればよいのか?
- 誰も専門家ではない
- まとめ
- 単なる流行りではない
感想
最近のビッグワードではある「機械学習」について、Swift開発者にとっても今後、あるいは既に関係してきている、という話。
そこまで目新しい内容があったわけではないけれど、機械学習というものが一般化してきているということをあらためて感じた。
今まであまり強い興味を持ってはいなかったけれど、勉強してみようと思った。
Swift on Android
- なぜ?
- クロスプラットフォーム
- SDL(最近のゲームでは使われてる)
- 新しいものはない
- C言語のABIは安定している
- Android NDK は中途半端
- Bionic(libcは使ってない)
- いろんなプラットフォームから取ってきた寄せ集め
- Lua→組み込み向けのスクリプト言語(AnsiCに互換)
- 様々なNDKバージョンがある
- バイナリを公開してもNG
- libICU
- staticにリンクすれば良いけれど、DLLにしないとだめ?
- JNI
- Cに見えるけれどSwiftのコードになっている
- Swiftの関数に対して、C向けの設定をできる(@_cdecl)
- イベントループをブロックしてはいけない
- ObjcRuntimeはAndroid上ではない
- グローバル変数の扱いには注意(DLLがメモリ読み込み済みだと前回の値が残る)
- 再初期化用のAPIを用意する
- 3つのテクニック
- SwiftPM
- 使えない
- 自分でやる
- 超大変
- CMake
- Android Studio でサポートすることを表明
- Xcodeのプロジェクトを生成できる
- SwiftPM
- IUP
- まとめ
- クロスプラットフォームにマジックはない
- Blurrr SDK
- 背後でCMake
- プリビルドのライブラリが出来る
感想
AndroidとかWindows上でSwiftのコードを動かす、という話。 なんというかハッキリ言って大変難しい内容でした(笑)
Swiftの関数宣言に@_cdecl
という属性をつけることで、C言語から呼び出せるインターフェースにできるというのは知らなかったので、そんな機能が備わっていたのか、と思いました。
おそらくこれらのテクニックを自分で使うことはないと思いますが、クロスプラットフォームについていろいろ聞けて面白かったです。機会があればクロスプラットフォームとまでは行かないにしても、SwiftでModelコードを書いて、それをAndroid(Java)のJNIから呼び出せるようなことが出来たら面白いと感じます。
SwiftのPointy Bits
メモ
- Safe / Unsafe
- ExeBadInstruction
- off by one
- 未定義動作
- unsafe API を使えばメモリ操作が出来る
- 8byte=ワード(64bit)
- メモリアドレスは最小単位が8byte
- なぜ4つのタイプがあるのか?
- 型あり
- 中途半端な位置にアクセスすることはない
- Intなどの具体的な値がpointeeで返ってくる
- UnsafePointer
- UnsafeMutablePointer
- 型なし
- UnsafeRawPointer
- UnsafeMutableRawPointer
- インスタンスではなくタイプでMutabilityを制御
- 型あり
- どういったときに使うのか?
- ポインタの誤用(2つ)
- ポインタをエスケープしない
- FAQ
- rawPointerを使うと未定義動作に繋がる(エスケープに注意)
感想
Swiftでポインタ操作とかをやる、という話。
安全性と引き換えにスピードが必要な場合、あるいは本当にローレベルのプログラミングが必要な場合に使えるテクニックだと感じました。
個人的にポイント型がいろいろあってあまり理解できていなかった部分が整理できて良かったです。
ポインタのエスケープがマズイという話が最後にあったのですが、そのあたりは微妙に理解できませんでした。
アプリを新次元に導く3D Touch
メモ
- iPhone6+ 以降で導入
- 5年かかった
- 早く機能にたどり着ける
- 3D Touch 対応だとストアでも目立つ
- APIとして使いやすい
- 最大4つ
- static / dynamic
- static
- コンパイル時に決定
- info.plistに書く
- 必須が2つ、他はオプショナル
- dynamic
- コードで生成
- ユーザが使ったことがないと表示されない?
- 直近で使ったメニューを表示とか(カフェ)
- Widget
- compact / expanded
- Peek / Pop
- プレビューとか(画面に遷移せずに見れるというメリット)
- 確認すべきこと:ユーザが使えるか(自分でOFFにも出来る)
- viewDidLoadでチェックすると良い
- アプリを使っている最中でもOFFにされる可能性がある
- 互換性
- UIGestureRecognizer(Long)
- 実装
- UIViewControllerPreviewingDelegate
- showだけでコミットできる
- UIPreviewInteraction
- 0〜1で生の値を取れる(例:スピード調整)
- ソースとなるViewを設定する
- 通知にも利用できる
- ユーザの目を引く
- 実装
- UNNotification framework #別プロセス
- FAQ
- テストできるか?
- ラッパーはあるのか?
感想
3Dタッチは簡単に導入できて、ユーザビリティを改善できるからみんなも導入してみては、というお話。AppleStoreでも目立つので、そういった意味でも良いとのこと。
3Dタッチの知識が不足していたので、いろいろと技術的な説明もあってありがたかったです。そしてAppleがこれを開発するのに5年を要したというのは驚きでした。
3Dタッチを利用して、画面に遷移させずにプレビューさせる、という使い方を初めて知ったのですが、個人的にはユーザにどうやって気付かせるか、というのが課題だと感じました。
まだ3DタッチはUIとして新しいものなので、今後広く使われるようになったタイミングで真価が発揮されるのかな、とも思います。
Pixcels、プロセスと情熱
メモ
- 暴露療法
- モチベーションを維持するのは大変
- 実験とフィードバックを繰り返しながら(小刻みに)
- 解決ではなく課題に注目するようになった
- プロダクトではなく人々が大変
- 自分や周囲を含めて幸せを目指す(自分のモチベーションを保つの大変)
- コネクションを大切にする
- 快適なゾーンを抜けてみる
- 最低でも何かを学ぶことが出来る
感想
プロダクトを開発する過程についてのお話。
このような発表の場で「モチベーションを維持するのは大変」という事実を話してくださって、個人的には勇気づけられました。
そして「解決ではなく課題に注目する」というのは面白い視点だと思いました。
毎日リアクティブ
メモ
- リアクティブ楽しい
- パラダイムをmixして使っている
- 非同期に変更されるデータに対して反応する
- ポイント
- Stateを減らす
- 宣言型のコード(How -> What)
- FW
- RxSwift
- RxCocoa
- SwiftBond
- 背後にあるアイディア(コンセプト)は一緒
- 1回学べば潰しが効く
- いつ使うべきか?
- 複雑なアプリケーション
- MVVM
- async ops
- 解決を目指す
- トレードオフ
- デバッグが辛い(コールスタックは使えなくなる)
- 怪しいストリームをロギングする
- 命令形のコードを混ぜるとリアクティブの意味が無くなる
- bindを使う
- Hot/Cold
- 副作用は本当に必要な場合だけにする
- カオスを避ける
- 別スレッドから呼ばれるケースを考える
- 値を変更せずに新しい値を生成するとか
- デバッグが辛い(コールスタックは使えなくなる)
- リアクティブプログラミングの展望
感想
特定のFW(RxSwift)とかではなく、リアクティブプログラミング一般についての話。発表でもいろいろなFWのコードが混ぜて説明されていました。
個人的には「デバッグが辛い」というのが利用者にとっての共通の課題だということを知って安心しました。
そしてアンチパターンについてもきちんと言及されていたのも良かったです。頭でわかっていてもこうやって講演で実際に聞けると自信が持てるものです。
リアクティブプログラミングという考え方はやはり有用だと思うので、適材適所をよく考えて適用していきたいと感じました。
⚡️🎤 Unsafe Swiftの安全性
メモ
- 未定義動作は辛いよ
- Swiftではいろいろ考えている
- 非初期化されていない値へのアクセスは許可しない
- Set/Dictionary
感想
ハッシュ値の計算をメモリ内容からやったら良いんじゃないか、という話。 コード内容を覚えていないのですが、あとでスライドが公開されていたら試してみたいと思いました。
ちなみに文字列連結によるハッシュ値計算はよく使っていたのですが、ヒープアロケーションが増えるというのは本当なのかな、と思いました。SwiftのString型は構造体なのでスタックに確保されると思ったので。そのあたりも含めて理解したいところ。
クックパッドアプリのテストを味わう
メモ
- UIの刷新を何回かしている
- そのタイミングでリファクタリングもしている
- 10万行
- リリース
- 1ヶ月単位
- 5000 -> 100,000Loc
- 品質
- Must-be(最低限の品質)
- クラッシュしないこと
- Must-be(最低限の品質)
- ユニットテストを先に書く、はやらない
- 内部から
- UI Tests
- re-write / re-factor
- Unit Tests
- 外部から
- UIテスト
- 非常に重要
- 時間もすごくかかる
- テストピラミッド(上に行くほど小さい)
- UI Test
- Integration Test
- Unit Test
- 汚いコードで自動化するのはやめろ
- 8割くらいUITestサポートしてる
- ターニップ?
- アンチパターン
- XPathはView階層に依存するので良くない
- ラベルを使う
- バリデーションとかはUIではなくメソッドでテストする
- Image diff
- ネットワークリクエストの回数とかも記録してる
- 余計なリクエストとかが増えてないか、とか
- 怖がることなく変更できる
- アールグレイとかも検討(Appiumは使い続ける予定)
- UIテストは re-enginering をサポートする
- FAQ
- XCUITestだとシステムアラートが出ない
- 遅いけれども毎回クリーンな状態で実行できる Appium を選択している
感想
クックパッドさん定番?のテストについての話。
UIを刷新するタイミングで大規模なリファクタリングが行えているのは、素直にすごいなと思いました。それだけ回帰テストがうまく回さているのだと思います。
個人的にはAppiumでのテストでキャプチャを取って、それを前回のキャプチャとdiffを取る、というテクニックがクールだなと思いました。個人的にもUIテストを導入するのであればぜひやりたいと思っていたテクニックなので、UIテストを今後やることがあれば是非取り入れたいと思いました。
テストについてのいろいろな知見が得られたので、勉強になったセッションです。
⚡️🎤 データレイヤを分離する
メモ
- 階層がきちんと分離されていれば良い
- 最小限のアーキテクチャ
- 層の詳細な実装が隠されるべき
- DTO、translatorを用意する
- 複数のチームでも機能する(実装の詳細が隠されるから)
- 変換コードを書くのは時間かかるけど、スレッド間の問題を負うほうがよっぽど時間かかる
- チームごとに必要なことだけを知る
感想
データレイヤを分離して、複数チームでも円滑に実装できるようにしよう、そのために昔ながらのDTOを使ったら良いんじゃないか、という話。
個人的にはシンプルだけれど良いアイディアだなと思いました。アーキテクチャがどうのというよりは、複数チーム間で機能させるように考えた、というところがです。
こういう話を聞くと、正解のアーキテクチャなんて無くて、プロジェクトやチームに応じた最適なアーキテクチャがあるだけなのだということを再認識させられます。(これも何度となく言われていることではありますが)
UIをSwiftyに書く
メモ
- 事前に決めておくこともある
- けれどコーディング中にパターンが見えてくることもある
- UIは冗長なコードになりがち
- 4つのパターン
- シュレディンガーのコード
- layoutSubviews
- 大きくなると辛い
- Storyboard
- チームだとコンフリクト解決が辛い
- 色などが定数で書けない
- 文字列ベースになってしまう -> Swiftの型安全性がない
- Outlet接続が間違っているとクラッシュしちゃう
- AutoLayoutは使わない
- コードで書く
- レイアウトが分からない(たった5行であっても)
- Cartography
- 宣言的なコードで記述できる
- 線形方程式を書いている
- ステート
- 取得中
- 成功
- 失敗
- 単純にフラグ変数で用意すると不必要な状態も持ち合わせてしまう
- enumを使う
- .loading
- .loaded(item: [MovieItem])
- .error(message: String)
- didSetだけで状態を更新する
- viewのロジックを一元化できる
- protocolを使って複数画面でも共通化する?
- デフォルト実装を使う
感想
StoryboardがSwiftの型安全とマッチしないという点と、プロトコルを使った共通的なパターン(取得中、成功、失敗)の実装方法が面白かったセクション。
個人的にはわりとStoryboard派ではあったのですけれど、ちょっと考え方を変えてみても良いかなと感じました。そしてプロトコルの使い方はとてもおもしろかったので、今度サンプルコードとか書いてみたいと思いました。
SwiftのWeb APIとアプリをともに構築する
メモ
- 良いAPIとは?
- ページネーションで重複するのを解決する
- 最後の項目のidを渡す(before)
- 変更をどうやって管理するか?
- バージョニング(原始的なアイディア)
- REST
- APIの結果にURLとかDOMの情報を含める
- クライアントが変更不要になる
- APIの結果にURLとかDOMの情報を含める
- Frank
- ちっちゃな感じ?
- Kitura
- フルスタック
- Vapor
- Web FW
- Heroku
- Procfile
- web: Hello
- BluemixはHerokuの拡張?
- Papertrail
- まとめ
感想
良いAPIの設計指針としてバージョニングではなく、レスポンス自体に画面描画や次のリクエストを含めるという話。あとはSwift製のWebFWについての紹介。
APIの設計指針については微妙に理解が怪しい感じではありますが、なんとなくコンセプトは理解できたような気がします。
WebFWについては個人的にVaporとKituraは触っていたのですが、それぞれの特徴がしれて良かったです。そしてHerokuへ簡単にデプロイ出来ることもわかったのも収穫でした。
⚡️🎤 楽しく便利なSwiftチャット
メモ
- 良いUIを作ればボットはまだまだ可能性がある
- たくさんのインターフェースを詰め込みすぎないようにする
- manページが必要になる
- Heroku + Vapor
- Bot用のインターフェースはいっぱいある
- 文字
- 画像
- 音
- ロケーション
感想
ボットはUIやアイディア次第でまだまだ可能性はあるよ、という話。
ボットというと地味なイメージがあったのですが、デモを見たらわりと面白いと感じました。個人的にもなにかボットを作ってみたいなという思いもしました。
Realmを使ってコラボレーションアプリを作る
メモ
- Realmとは
- オブジェクトデータベースではない
- モバイル機器のためにゼロから開発
- SQLiteはモバイル向けに設計されたわけではない
- 特別な記法は必要ない
- データベースの同期
- デバイス間の同期
- 共同編集
- コンフリクトした場合は自動的に解決してくれる
- オフラインでも大丈夫
- Realmの通知機能
- プロパティの変更監視
- オブジェクトの変更
- コレクションの変更
- ファイル全体の変更通知
- すべてのRealmを同期
感想
ちょっとRealmの宣伝的なセクションだったような気がします。(まぁスポンサーだし仕方ないね!)
まぁしかしRealmでデータベースの同期がシンプルに実現できるというのは勉強になりました。まぁFirebaseでも出来るようですが :-)
独自のツールを構築する
メモ
- DANGER(コードレビューを楽にする)
- 問題
- ReactNative
- デメリット
- 依存性は593 -> 理解するのはほとんど不可能
- 若い
- 変更される
- 万能薬ではない(当然ながら)
- JavaScriptのテストはネイティブよりずっと進んでいる
- TypeScript(現代のJavaScriptは楽しい)
- デメリット
- React
- View階層をマスクしようという試み
- ネイティブ階層を作る
- JavaScriptをネイティブコードに変換するようなことはしていない
- Relay便利
- Appleの主要なアプリでネットワークを使っているのは2つくらい?
- まずはApple向け、次に外の開発者向け
- だから良い企業になった
- Appleは超安全なリリースが重要
- 我々はそこまで必要でないこともある
- Xcodeの外に目を向けてみるのも手
感想
開発速度を改善するためにあえてReactNativeを使った、という話。
Swiftは型安全ですし、個人的にも結構気に入っている言語ではありますが、如何せんコンパイル速度は遅いです。そうした現実を受けて、あえて型安全がない代わりにコンパイル速度(開発サイクル)が高速なJavaScriptを選択した、というのは非常に勉強になりました。
Swiftという言語がApple社内向けに作られた言語であり、その次に外の開発者向けである、という洞察にも舌を巻きました。なるほどその考え方は無かったです。
⚡️🎤リアルタイム物体検出アプリでよりよいフィードバックを提供する
メモ
感想
リアルタイム物体検出で、トラッキングしたりしてユーザにフィードバックするとより良いUIが提供できるよ、という話。
Wantedlyさんのアプリだったと思うのですが、なかなか良い感じのUIが出来上がっていて、とても良いと感じました。
⚡️🎤 UXエンジニアという働き方
メモ
- 使ってもらえるから意味がある
- UXを良くするためにやっていること
- ユーザテスト
- デザイン思考
- 優秀なデザイナーが行っていること
- 「共感」がポイント
- まとめ
- ユーザを忘れない
- 小さなことでも出来ることから
感想
エンジニアでもUIとかUX大切ですよ、という話。
個人的に「デザイン思考」という優秀なデザイナー日々行っているという言葉を初めて知って勉強になりました。
1日目の終わりに
慣れない通訳でのプレゼンに戸惑いながらも、すごくいろいろな事が聞けて、とても刺激的な一日でした。(あらためてメモをみると、最初はなかなか苦労していましたね・・・やはり)
いやはや、なんというか1日で咀嚼できるボリュームではとてもありません。
Swiftのカンファレンスでありながら、それ以外の発表も多くあったりして、最初はちょっと戸惑ったのですが、結果的にはいろいろな知識を吸収できてよかったような気がします。
try! Swift 2017 Tokyo に参加してきた - 1.全体を通して振り返る
はじめに
参加してきました。
https://www.tryswift.co/tokyo/jp
家に帰ってから記事を書くまでがカンファレンスです、という名言を最初に聞いたのはXP祭りだったでしょうか? そんなわけで今回も個人的な感想を書いていきたいと思います。
おそらく長くなるので記事は以下のように分割したいと思います。
- 全体を通して振り返る(この記事)
- 1日目
- 2日目
- 3日目(ハッカソン)
要約
とてもハイレベルなイベントで、参加してすごく良かったと思えるイベントでした。
正直なところ早割で$250、通常だと$350する参加費は高いと感じました。 (もちろん開催にあたってかなりの経費がかかることはわかりますが)
しかしながら他ではなかなか聞くことが出来ない"リアル"な話が聞けて、 個人的には参加費として$350払う価値は十分にあったかと思います。
ちなみに外国人の登壇者が多かったですが、同じく外国人の参加者も多かったです。 日本で開催されるIT系のイベントでここまで外国人率が多いイベントも少ないように感じます。
開催場所
1日目と2日目が新宿、3日目が神田で開催されました。
1日目と2日目(新宿)
新宿の会場へはJR新宿駅から会場に向かったのですが、いやはや思ったより遠かったです(笑)
会場は広く、前半分くらいはテーブルがあって、後ろ半分はテーブルなしでした。 幸いにもテーブルがある席が確保できてメモが捗りました。
ちなみに会場の電源は使用することが出来ず、Macのバッテリーはギリギリでした。
3日目(神田)
神田駅からわりと近い位置でした。
1日目と2日目が平日、しかも早い時間帯ということもあって、満員電車で揺られた後、そこそこの距離を歩いて会場に到着、という感じだったのでありがたかったです。
同時通訳について
同時通訳があるイベントに参加したのは恐らく初めてだったのですが、 技術ワードについてもきちんと通訳できており、非常にレベルの高い通訳だったと思います。
わたしはかろうじて英語が少し読める程度の力なので、今回のカンファレンスでの同時通訳は無くてはならないものでした。 通訳してくださった皆様方には大変感謝です。
発表について
発表内容はそれぞれ違うのですが、以下のような共通項があったように感じます。
銀の弾丸は無い
「銀の弾丸は無い」というのは(多くの発表者も言われてましたが)古くからあるもので新しいものではありません。 しかし、これほど何度も繰り返し言われるということは、それだけ人がその存在を信じやすい、ということでしょう。
最近について言えば「リアクティブプログラミング」がその良い例だったように感じます。あの騒ぎは何だったのでしょうか?
もちろん優れた技術ですし、私自身も勉強会を開催するくらいには気に入った技術です。 しかし、それを「銀の弾丸」だと信じて採用した開発チームの末路はどこも一緒なのではないかとも思います。
可読性の重要さ
これも多くの発表に共通しているものだったように感じます。
プログラミング言語というのは半分は技術の進歩で、もう半分は(数学のような)記法の進化である、という言葉はハッカーと画家に書いてありましたが、つまりそういったことではないでしょうか?
可読性、言い換えるとコード上でのコミュニケーションの重要さを軽視すべきではない、ということかと思います。
Protocol Oriented Programming(プロトコル指向を使ったテクニック)
これもSwiftを使った実践的なテクニックの面では多用されていました。 プロトコル指向の原型はHaskellの型クラスにあると思うのですが、やはり関数型のテクニックはSwiftのコードにおいても有用、ということかと思います。
個人的にProtocolを大げさに感じていた面もあった(これはJavaのインターフェースの時代からですが)のですが、これを気に考え直したいと思いました。
型を意識したコード
Interface Builder が必ずしも最適解ではないという理由に、Swiftの良さである型安全が保たれない、という説明がありました。 他にも型を重要と(明示的あるいは暗黙的に)捉えた発表が多くあったように感じます。
発表テーマ
1日目
2日目に比べると「Swiftにかぎらず」「詳細よりもコンセプトを」という発表が多かった気がします。 もちろんそれだけに限っているわけではありませんが。
個人的には「Orta Therox」さんの「独自のツールを構築する」が面白かったです。
2日目
1日目に比べて「具体的なSwiftコード」という側面での発表が多かったです。 まさにSwiftカンファレンスという感じで、個人的には2日目の方が楽しめました。
個人的には「Jon Reid」さんの「モックオブジェクトをより便利にする」が面白かったです。 今までの人生で聞いた発表の中で一番かもしれません。
3日目
わたしは友人と一緒に2人チームでハッカソンに参加しました。
合計48組の中で、審査員の選考を通過した10組が壇上でプレゼンし、うち上位3組が商品をもらえるという形式でした。
残念ながら入賞はできなかったのですが、10組には選出されて壇上でプレゼンすることができました。
swift-heredoc
https://devpost.com/software/swift-heredoc
朝食・昼食・パーティーについて
朝食
タイムテーブルにある”朝食”という文言で、ホテルの朝食のようなビュッフェを想像してしまったのですが、実際には菓子パン1つでした(笑)
これは勝手に期待してしまった私が悪かったのですが。 ただ3日間を通じてコーヒーが自由に飲めたのは大変ありがたかったです。
昼食
これ系のイベントにしてはわりと豪華なお弁当だったように感じます。 ただし人気のあるメニューはわりとすぐになくなったような気がします。
パーティー
IT系のイベントに限らず、これほど豪華なパーティーに参加したのはわたしは初めてでした。 美味しい料理を開発者たちで飲み食いできるのは楽しかったです。
わたしはシャイなので自分からは話しかけられないタイプなのですが、話しかけてくださった方には大変感謝です。ありがとう。
まとめ
この一言で片付いてしまうのですが、本当に参加してよかったと思えるイベントでした。
もしSwiftに興味がある技術者は、多少無理をしてでも来年参加されてみることをおすすめします。
業務が忙しい人も多いと思いますが、何倍ものリターンが得られるかと思いますし、その知見を日々の業務にフィードバックすることで、より生産的な仕事が出来る様になると思います。