My Favorite Things - Coding or die.

とある技術者の経験記録、的な。

Kotlin で HelloWorld(コマンドライン編)

さて前回に続いて、今度はコマンドラインで Kotlin のHelloWorldをやってみたいと思います。

公式ドキュメントのチュートリアルを見ながら進めていきます.

インストー

まずは念のため既にインストールされていないか確認します。

$ kotlinc
zsh: command not found: kotlinc

IntelliJ IDEA で自動でインストールされてはいないようですね。

SDKMAN! のインストー

brewでインストールするのが手っ取り早いかと思ったのですが、 SDKMAN!という複数バージョンを共存させられるrbenvと似たようなツールがあるようです。

しかもKotlin以外の言語にも対応しているとのことで今後も使えそうなので、これを使ってインストールしてみます。

$ curl -s https://get.sdkman.io | bash
...
All done!


Please open a new terminal, or run the following in the existing one:

    source "/Users/yusuke/.sdkman/bin/sdkman-init.sh"

Then issue the following command:

    sdk help

Enjoy!!!

以下のコマンドを実行して有効にします。

$ source "/Users/yusuke/.sdkman/bin/sdkman-init.sh"

sdk helpと試しに打ってみると。

$ sdk help

Usage: sdk <command> [candidate] [version]
       sdk offline <enable|disable>

   commands:
       install   or i    <candidate> [version]
       uninstall or rm   <candidate> <version>
       list      or ls   [candidate]
       use       or u    <candidate> [version]
       default   or d    <candidate> [version]
       current   or c    [candidate]
       upgrade   or ug   [candidate]
       version   or v
       broadcast or b
       help      or h
       offline           [enable|disable]
       selfupdate        [force]
       flush             <candidates|broadcast|archives|temp>

   candidate  :  the SDK to install: groovy, scala, grails, gradle, kotlin, etc.
                 use list command for comprehensive list of candidates
                 eg: $ sdk list

   version    :  where optional, defaults to latest stable if not provided
                 eg: $ sdk install groovy

sdk listというコマンドを使うとインストール可能なツールや言語の一覧が表示できるっぽいです。

================================================================================
Available Candidates
================================================================================
q-quit                                  /-search down
j-down                                  ?-search up
k-up                                    h-help

--------------------------------------------------------------------------------
Activator (1.3.10)                   http://www.lightbend.com/activator/download

Typesafe is a GUI/CLI tool to help with building reactive applicaions. It uses
sbt (simple build tool) behind the scenes to build, run, and test your project.
It provides a code editing interface, and provides templaes and seeds for you to
clone and use.

                                                         $ sdk install activator
--------------------------------------------------------------------------------
Ant (1.10.1)                                             https://ant.apache.org/

...

Kotlin のインストー

SDKMAN!を使ってインストールをします。

sdk list kotlinコマンドで、一応インストール可能なバージョン一覧を見てみます。

$ sdk list kotlin

================================================================================
Available Kotlin Versions
================================================================================
     1.1.2-2              1.0.3                                                    
     1.1.2                1.0.2                                                    
     1.1.1                1.0.1-2                                                  
     1.1-beta2            1.0.1-1                                                  
     1.1-beta             1.0.1                                                    
     1.1-RC               1.0.0                                                    
     1.1-M04                                                                       
     1.1-M02                                                                       
     1.1-M01                                                                       
     1.1                                                                           
     1.0.7                                                                         
     1.0.6                                                                         
     1.0.5-2                                                                       
     1.0.5                                                                         
     1.0.4                                                                         

================================================================================
+ - local version
* - installed
> - currently in use
================================================================================

なるほど今日時点の最新は1.1.2-2なのですね。

sdk install kotlinで最新版をインストールします。

$ sdk install kotlin

Downloading: kotlin 1.1.2-2

In progress...

######################################################################## 100.0%

Installing: kotlin 1.1.2-2
Done installing!


Setting kotlin 1.1.2-2 as default.

もう一度sdk list kotlinしてみる、最新版がインストールされて有効になっているのが分かります。

$ sdk list kotlin

================================================================================
Available Kotlin Versions
================================================================================
 > * 1.1.2-2              1.0.3                                                    
     1.1.2                1.0.2                                                    
     1.1.1                1.0.1-2                                                  
     1.1-beta2            1.0.1-1                                                  
     1.1-beta             1.0.1                                                    
     1.1-RC               1.0.0                                                    
     1.1-M04                                                                       
     1.1-M02                                                                       
     1.1-M01                                                                       
     1.1                                                                           
     1.0.7                                                                         
     1.0.6                                                                         
     1.0.5-2                                                                       
     1.0.5                                                                         
     1.0.4                                                                         

================================================================================
+ - local version
* - installed
> - currently in use
================================================================================

下の方に書いてありますが、

  • * がインストール済み
  • > が現在有効になっているバージョン

ということみたいですね。

+はまだ表示されていないので断言できませんが、特定のディレクトリに適用されたバージョンが表示されるのでしょう。

Hello, world!

ソース作成

さてまずはhello.ktを作成します。

$ touch hello.kt
$ vim hello.kt
fun main(args: Array<String>) {
    println("Hello, World!")
}

コンパイル

つぎはコンパイルですね。

kotlincというコマンドを使ってコンパイルするようです。 (ちょっと長いのでktcとかエイリアスを貼ってもいいかもですね)

$ kotlinc hello.kt -include-runtime -d hello.jar

-dが出力を指定するもの、-include-runtime.jarの中にKotlinのランタイムを同梱するオプションのようです。

ちなみに最初に拡張子を.ktではなく.tkとしてしまっていたのですが、そうした場合は以下のようなエラーが出てコンパイルできませんでした。

$ kotlinc hello.tk -include-runtime -d hello.jar
error: source entry is not a Kotlin file: hello.tk

なるほど拡張子は.ktでないとKotlinのソースとしては認識されないのですね。

実行

さてディレクトリの中身を見ると、hello.jarがちゃんと出来ていますね。

$ ls
hello.jar  hello.kt

javaコマンドを使ってjava -jar hello.jarで実行できるようです。

$ java -jar hello.jar 
Hello, World!

ちゃんと実行できましたね。

kotlinc

kotlinc -helpでヘルプが見られるようなので確認しておきます。

$ kotlinc -help
Usage: kotlinc-jvm <options> <source files>
where possible options include:
  -d <directory|jar>         Destination for generated class files
  -classpath (-cp) <path>    Paths where to find user class files
  -include-runtime           Include Kotlin runtime in to resulting .jar
  -jdk-home <path>           Path to JDK home directory to include into classpath, if differs from default JAVA_HOME
  -no-jdk                    Don't include Java runtime into classpath
  -no-stdlib                 Don't include Kotlin runtime into classpath
  -no-reflect                Don't include Kotlin reflection implementation into classpath
  -module <path>             Path to the module file to compile
  -script                    Evaluate the script file
  -script-templates <fully qualified class name[,]>
                             Script definition template classes
  -kotlin-home <path>        Path to Kotlin compiler home directory, used for runtime libraries discovery
  -module-name               Module name
  -jvm-target <version>      Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6
  -java-parameters           Generate metadata for Java 1.8 reflection on method parameters
  -language-version <version> Provide source compatibility with specified language version
  -api-version <version>     Allow to use declarations only from the specified version of bundled libraries
  -nowarn                    Generate no warnings
  -verbose                   Enable verbose logging output
  -version                   Display compiler version
  -help (-h)                 Print a synopsis of standard options
  -X                         Print a synopsis of advanced options
  -P plugin:<pluginId>:<optionName>=<value>
                             Pass an option to a plugin

もっと大量のオプションを予想していたのですが、思ったよりは少ないですね。(swiftc --helpの量が多すぎるのかも分かりませんが)

今後必要な時に見ていくことにします。

最後に

さて無事にコマンドラインでKotlinのHelloWorldを試すことが出来ました。 最近の言語は試すのが導入から試すまでが簡単で良いですね。

ちなみにチュートリアルのページには、ライブラリの作成方法やREPL、スクリプトとしての実行などが含まれているのですが、続きは別の記事にしたいと思います。

Kotlin で HelloWorld(IntelliJ IDEA編)

世の中はKotlin一色ですね。(言い過ぎ?)

そんなわけで私もKotlin始めてみようと思います。
まずは IntelliJ IDEA(Community Edition)をつかってサクッと。

IntelliJ IDEAのダウンロード

公式サイトからCE版をダウンロード。 www.jetbrains.com

無償のCE版でもKotlinが使えるってのはありがたいですね。
(JetBrainsからしたらそりゃ使ってほしいでしょうが)

プロジェクト作成

Create Project から作成します。 f:id:yu_dotnet2004:20170527195615p:plain

Kotlinの中に「Kotlin (JVM)」ってのがあるのでそれを選択します。
(というかJavaScript版?があるのに驚きました) f:id:yu_dotnet2004:20170527195641p:plain

Project name は「HelloKotlin」にしてみます。 f:id:yu_dotnet2004:20170527195847p:plain

ウィンドウが表示されたものの殆ど表示されないので戸惑いましたが処理中のようです。 画面下の方にインジケータが表示されています。 f:id:yu_dotnet2004:20170527195951p:plain

Kotlinファイル作成

まだ良くわかっていませんが、srcディレクトリを右クリックして「New > Kotlin File/Class」を選んでみます。 f:id:yu_dotnet2004:20170527200103p:plain

ダイアログが表示されるので Name に「HelloWorld」と入れてみます。 f:id:yu_dotnet2004:20170527200149p:plain

コードを書く

エディタが表示されるので早速コードを書いてみます。

fun main(args: Array<String>) {
    println("Hello, world!")
}

main関数の行に Kotlin のアイコンが表示されました。 f:id:yu_dotnet2004:20170527200314p:plain

実行

Kotlinアイコンをクリックしてみると、どうやらここから実行できるようです。(便利) f:id:yu_dotnet2004:20170527200405p:plain

画面下の方に実行結果が出力されました。なにやらエラーっぽいものも表示されていますが、とりあえず実行はできているようです。 f:id:yu_dotnet2004:20170527200459p:plain

ディレクトリ構成

ちなみにサイドバーを見るとコンパイル後の結果は out ディレクトリ配下に格納されるようです。 f:id:yu_dotnet2004:20170527200543p:plain

最後に

とりあえず覚え書きとしてスクリーンショット多めで記事を書いてみました。

次回はコマンドラインでHelloWorldしてみたいと思います。

potatotips #40 に参加してきました。

はじめに

(2017/05/27追記) 新たに公開された発表資料を追加しました。

以下のイベントに参加してきました。 potatotips.connpass.com

実は当日まで参加予定ではなかったのですが、 偶然にもAndroidのブログまとめ枠が一人空いたとのことで急遽参加させていただきました。 (ちなみに「ブログまとめ枠」での参加は初めてです)

ちなみにここ数年はiOSエンジニアとしての活動が多いので、ポテチには一度は参加したいと思っていました。 本当は発表者として登壇したいという欲望もあったのですがそれは別の話。

Androidのブログまとめ枠での参加でしましたが、iOSも含めて記事にしちゃいたいと思います。 (大丈夫ですよね?)

箇条書きはリアルタイムで頑張って書いたものなので、間違いとかあるかもです・・・ご容赦を。 またスライドとかは後日公開とかもあると思うので、アップされしだいリンク追加していきます。

乾杯

まずは乾杯、というかもう飲んでる人多数。 Swift愛好会といい最近の勉強会は最初に乾杯ってパターンが多いんですかね?

事前説明

Rettyの中川さんより会場説明。

CMタイム、スポンサーだから当然許されます。 engineer.retty.me

iOSDCやPyConなどのスポンサーもやっているらしいです。 イベントスペースなどもレンタルもやっているとのこと。

Retty Android もくもく回?なるものもやっている、 勉強会などのコミュニティ活動もサポートしてくれる、とのこと。ふむふむ。

では、各発表のまとめです。

どうしたらログがちゃんと管理できるのか?(kosako)

speakerdeck.com

  • アプリの分析
    • GA
    • DB
    • 自前(TD?, BigQuery)
      • 今回はこれのお話
  • よくあるパターン
    • ここの数字をみたい
    • ボタンのタップ数ってどっちが多いの?
  • よくあるパターン
    • 都度埋め込まれるログ
    • 取りたいデータが取れない
    • 後始末がされにくい
    • etc
  • アプローチ
    • ログを送るメソッドを1つに
    • コールする場所ではどこに送るか指定しない
    • 送信設定ファイルを用意して集約
  • イメージ
    • ボタンタップ
    • 送信メソッド(ここで設定ファイルを見る)
    • 送信
  • 設定ファイル(log.json
    • ログの設定を集約する
  • ポイント
    • JSONファイルを用意すれば
    • ログの意味が分かりやすい
    • ログ同士の対応表がそこにある
    • 設定ファイルを変更すればOK
  • 今後の野望

「ログをどう管理するか?」という課題に対して、1つの設定ファイル(JSON)に集約するというアプローチ。 個人的にはコード上に値が分散するよりも断然良いと感じたので、良いアプローチだと感じました。

Modern Java Libraries with Kotlin(Keisuke Kobayashi)

  • 無料送金アプリ(Kyash)
  • 今日
    • JavaライブラリをKotlinでも
    • 特別に対応が必要なケース
  • Dagger2 + Orma
    • kaptで自動生成されるクラスはDaggerでprovideできない
    • OrmaDatabase
  • OrmaDatabaseをラップすればOK
  • Dagger Module
    • ラップしたクラスを返す
  • Data binding
    • dependenciesにkaptを追加する
    • Androidバージョンに依存するのでバージョン番号も書く
  • Parceler
    • Parcelableのボイラープレートを自動生成
    • Kotlinのデータクラスで使いたい
  • data class
    • toString, hashCodeの実装が不要
  • @Parcelをつけるだけでは動かない
    • Kotlinのプロパティはフィールドではない
  • @Parcel(Parcel.Serialization.BEAN)ってやつ
  • おまけ
    • サンプル作ったよ(2ヶ月くらい)

JavaライブラリをKotlinで使う際に特別な対応が必要になるケースの紹介でした。 私はAnrdoid初学者でDaggerくらいしかライブラリを知らなかったのですが、なんとなくイメージは伝わってきました。

個人的に、Kotlinのプロパティはフィールドではない、というのは勉強になりました。

ゲームアプリの「ドット絵」をディープラーニングで自動生成(shu223)

qiita.com

  • 結論:失敗したorz
  • DCGAN
    • アイドルの顔画像を大量にあつめて自動生成
    • スライドに写されたのは元データではなく実際に生成された画像!!
  • DCGAN-tensorflow
    • サンプルデータだとセレブっぽい顔の画像をせいせい
  • 自前のデータを食わせてみたい
  • スーパークエス
    • ドット絵モンスターを自動生成できないか?
  • やってみた
    • 基本的にフォルダに置いて動かすだけ
  • epoch
    • 学習の進み具合
    • 途中経過が面白い
  • 学習は順調に見えた
  • 過学習
    • 学習データを元にしちゃってる?
  • 何が違っていたのか?
    • セレブは20万枚
    • 目も鼻もある、だいたい似てる
    • アイドルデータも似てる
    • 学習データの量も変化も違う
  • まとめ
    • ダメだった
    • 問題設定が悪かった&データ量が少なかった
  • QA
    • もう一度チャレンジしますか?
      • しません。(ドット絵の題材はもうやらない)
    • 解析にかかった時間
      • MacBookProでまる1日くらい

ドット絵ディープラーニングで自動生成しようとしたけれどダメだったというお話。 結果はさておき、失敗要因の分析がとても良いと思いました。

ちなみに epoch の過程を見るのは確かに楽しそうだと思いました。

Kotlin Reflection(hikaru_satoh)

  • 自己紹介
  • リフレクションのKotlinバージョン
    • KClass、KPropertyを利用する
  • プロジェクト設定
    • app/build.gradleに追加する
    • 書かなくてもビルドエラーにはならなかったが、エラーログとか
  • 4.8kb多くなった
  • Class References
    • KClass型
    • User::classで取得
  • member.properties
  • private
    • privateなプロパティがあると例外スロー
    • isAccesible = trueってやれば見られるようになる
  • Property References
    • kProperty型
    • User::firstName.get(user)みたいな感じで使える
    • privateメソッドは見られないのでコンパイルエラーになる
  • KProperty1
    • p:KProperty1<User, *>
  • KPropertyの種類
    • 0: static変数を取得
    • 1: メンバーのプロパティ取得
    • 2: (聴き逃した)
  • まとめ
    • Javaと同じような感じでアクセスできそう
    • 他にもリフレクション機能はいろいろ使えそう
  • QA
    • リフレクションの具体的な利用事例は?
      • デバッグ出力を簡単にしたり、ホットパッチ?

Kotlinでのリフレクションの使い方についての説明。 Java8におけるメソッド参照みたいなことが出来る分、Kotlinのリフレクションは安全なのだなと感じました。

シークバーサムネイル作成Tips共有(satoshi0212)

  • AbemaTVの人
  • 何を作ったのか?
    • シークバーのサムネイル表示機能
  • アトラス画像表示
    • サムネイル画像をまとめたもの
    • APIを用意してもらって、番組ID、サイズ、時間
    • 1枚で600秒分
    • シークバーを初めて触った時に取得
    • 再生時間を元に特定
  • デザインの作り込み
    • デザイナさんが思い入れ
  • DEMO
  • まとめ
    • アトラス画像方式はわりと軽めで実装できた
    • 画像取得タイミングを遅らせてみた
  • 蛇足
    • 作り込みたいけれど締切はあるね
    • そういう部分を作る担当になる
  • QA
    • 画像の切り出しタイミングって?
      • 実際に表示しようというタイミングで切り出してUIImageを生成している
      • けれど質問されて、UIImageで切り出す必要はないかもと思った

動画再生においてシークバーをスライドするとサムネイルが表示される例のアレ。 アトラス画像といった考え方や、データ取得を遅延させるといったテクニックなどが聞けて面白かったです。

ちなみに、そういう部分を作れる担当になれるかが重要、というのはまさにだと思いました。

Android Instant App(Sam)

www.slideshare.net

  • 自己紹介
  • Android Instant Appとは
    • インストール不要のAndroidネイティブアプリ
    • URLの起動に応答してインストール不要でアプリ起動
    • PlayStoreとは全然別
  • 仕組み
    • 機能ごとにダウンロードしてくる
    • URLからの要求に対して必要な機能だけをダウンロード
  • 2つのAPK
    • Base Feature APK
      • 2回目以降のダウンロードは不要
    • 機能のAPK
  • 機能ごとにモジュール化させる
    • 1つのモジュールは4MBまで
  • 制限されている機能
    • フアグラウンドは実行できる
    • 外部ストレージアクセス
    • 明示的インテント
    • ブロードキャスト
  • 使えない機能
    • コンテンツプロバイダ使えない・・・
  • コンテンツプロバイダ
    • DAO使えない
    • Realmは3MB
    • Firebase Realtime Database
      • Googleが使っていいよ、と。
      • データベースの時代はクラウドになったんだぜ、と。
  • 現状
    • 50個以上のアプリが対応済み
  • ぶっちゃけ?
    • 情報が少なすぎる。。。
    • 導入する場合はユースケースを決める必要がある
      • どんな体験を?どこの機能を?

Android Instant App についての紹介。 今まで噂に聞いたことがあるレベルだったので、具体的な内容が知れて良かったです。

ユーザにとっての利点は納得できるものの、これだけ制限が多い中、開発者的にはそんなに美味しいかしら、とも思いました。 日本のブロードバンド事情を考えると、Instant App を開発して公開するメリットを感じるアプリは少ない印象を受けました。

ちなみに私も暴君ハバネロは大好きで、箱買いしたこともあるレベルなので懇親会で話そうと思いつつ、 まとめに疲れてすっかり忘れてしまいました・・・またの機会に。

Universal Links 対応した話(Ridwy)

www.slideshare.net

  • 自己紹介
    • 音声処理技術が好き
  • モチベーション
    • iOS9以降の機能
    • iOS10が普及したので
    • 実際に対応して得られた知見
  • Universal Linksとは
    • ユーザから見て
      • Webのリンクをタップした時に、ドメインに対応するアプリが起動する
    • ステータスバー
      • 左:遷移元へ
      • 右:Safariで開く、ってやれば今後もSafariで開かれる
      • 正直ユーザにはわかりづらい印象
  • アプリが起動する条件
    • Safariで開くことを選択していない
    • iOS9以降
    • アプリがインストールされている
      • インストールされていないとそのまま遷移(ストアは立ち上がらない)
    • 同一ドメイン内の遷移ではない
  • おさらい
    • Entitlementにドメイン追加
    • アプリが開かれた時に呼ばれるメソッドを実装
    • 扱えないURLはopenで開きなおす
      • でも見た目はいまいち
  • サーバ側の対応
    • AASAファイルを配置
      • ルートまたは.well-knownサブディレクトリ配下に
      • HTTPSで直接アクセスできるようにする
      • HTTPはNG、リダイレクトもNG
      • アプリのインストール時に取得される
  • AppIDのプリフィックス
  • SKIP
  • iOSが何をしているか?
  • QA
    • AASAファイルの更新が必須

iOS9から導入された「Universal Links」についての詳細な発表。 UI/UXに関わる意見や、内部的な実装がどうなっているかの予測など、なかなか深いところまで突っ込んだ内容でした。

発表者の方も言っていましたが、UIはもうちょっとどうにかならないかと感じました。

フル Kotlin で Mastodon クライアントを作ってみて(tomoya0x00)

qiita.com

  • 自己紹介
    • 組込系がメイン
    • 最近アプリとかも
  • Mastodonクライアント
    • MVVM x フルKotlin
  • なぜ?
    • SwiftやってたらJava辛くなった
  • どういったところが嬉しい?
    • Realmとの親和性良いよ
      • プロパティ名が取得できる
      • lazyで遅延取得が出来る
    • 拡張関数でUtilityクラス乱立防止
    • coroutineで簡単非同期処理
  • ハマリポイント
    • 無名くらいのインスタンス
    • DataBinding方法
      • @get:Bindableみたいな
    • 例外処理
      • 普通に囲めばOK
    • UIスレッド実行
      • coroutineビルダー
      • launchUI()を使う
    • coroutineのライフサイクル
      • onDestroyでキャンセルするには
      • async時に取得できる?
  • QA

フルKotlinでMastodonクライアントを作ってみて得られた知見のシェア。 ハマリポイントとかの紹介があって、これからKotlinを使う人には役立つと感じました。

質問の回答でもありましたが、TwitterよりMastodonクライアントの方が作るのが楽、というのはなかなか意外でした。

ちなみに関係ないですが、最近良く聞く「coroutine」を未だに理解していません。 Go言語とかでもよく聞きますし、今度ちゃんと調べねばと思います。(たぶん、Promiseとは違うんですよね?)

いまから使えるSpreadsheetView(pancake)

speakerdeck.com

  • 自己紹介
    • パンケーキの人
    • スプレッドシートは岸川さんが作ったやつ
    • iOSエンジニア
    • 東京にいるわけではないので今日はホテルに帰る
  • OSS
    • 公開後1,500スター
  • 作ったアプリ
  • 機能
    • ヘッダ固定
    • 無限スクロール
    • グリッド線とか枠線とか
    • UICollectionView like
  • サンプル付き
  • UICollectionView likeなAPIなので使いやすいかも?
  • セルのマージ機能
    • 5分刻みのセルを作ってみた
  • ほかのライブラリは?
    • ある
    • セルのマージ機能があるのはスプレッドシートだけ?
    • 標準だとリニアな探索のところ、2分探索が実装されている
  • QA
    • 結合されたセルのタップイベントはどうやって拾う?(インデックスとかどんな感じで?)
      • 現状だと左半分しか反応しない?(実装ミスかも)

岸川さんが開発されたSpreadsheetViewを使ってみたというお話。 github.com

私もiOSエンジニアなので噂は聞いていましたが、具体的にどういうことが出来るのか知らなかったので良かったです。 そしてセルの結合機能があるOSSは(おそらく)唯一なのですね。

しかしスター数1,490とは・・・凄まじいですね。

「Lottie」でお手軽アニメーション実装(shanonim)

speakerdeck.com

  • Lottie
    • 意外と知ってる人が多い
    • アニメーションのライブラリ
    • Adobe After Effectsで作ったJSONをアプリで読み込める
    • そのままアプリに組み込めちゃって楽ちん
    • iOS/Android/ReactNativeすべてに対応
  • AfterEffects
    • 映像分野ではメジャーなソフト
    • CM作成とかでも利用されているらしい
  • アプリに組み込む(Android
    • build.gradle
    • Activityはノータッチ
    • レイアウトXMLJSONを指定する
    • 複雑なアニメーションでもJSONを読み込むだけ
  • 利用ケース
    • ローディングとかアイコンとか
    • 画面全体とかは微妙かも
  • 導入までのハードル
  • LottieFiles.com
    • CCライセンスで公開されている
    • 見てるだけで楽しそう
  • まとめ
    • Lottie楽しい
    • アニメーションでUXをあげよう
  • QA
    • 画面全体には向かない?
      • アニメーションの作成コストが掛かるだけ
    • バイスサイズの対応は?
      • dpで指定すればそれに収まるようになる
      • SVGっぽい感じで、拡大してもぼやけないとのこと

Adobe After Effectsというツールで作成したアニメーションをJSONでエクスポートして、そのままアニメーション出来るLottieについての紹介。 airbnb.design

不勉強なものでAfter Effects自体知らなかったのですが、デザイナさんがそれを利用してアニメーションを作成し、 それを殆どゼロコストで導入できる(デザイナの意図が100%反映される)というのは便利だと思いました。

CCライセンスで公開されているLottiefiles.comは、たしかに見ているだけで楽しいですし、何かアイディアに繋がりそうな気がしました。 www.lottiefiles.com

Lightweight Dependency Injection Tips(Motoki Narita)

speakerdeck.com

  • 放送事故(放送終了)
    • (発表開始直後にディスプレイが消えてしまった)
  • 自己紹介
    • メルカリカウル
    • 本、CDとかに特化した姉妹アプリ
    • クラッシュレート1%を下回る
  • 今回DIを取り入れた
    • AppleでもDIのベストプラクティスをまとめている
    • Qiita記事にもまとめている
  • イケてない気がするところ
    • Segueで依存オブジェクトを渡す必要がある
  • “良い設計は誤った用法をコンパイルエラーにする"(ishikawa)
  • ルール
  • 経緯
    • アッテの開発のなかでそういう話になっった
  • 作り方
  • 作っていく中でリファクタリングを繰り返していった
  • まとめ
    • 良かったこと
      • インスタンス化の方法が統一される
      • 統一されることでDRY
      • 再利用が楽に
    • 良くなかったところ
      • Storyboardを使っているけれど画面遷移が見えない
  • 告知
    • iOSDC(今年は2.5日)

LightweightなDIを使うと良いかもよ、という話。 個人的には今日のLTの中で一番面白く感じた内容でした。

Lightweightというのは誇張ではなく、本当に最低限の仕組みであるにも関わらず、 そこに本質がきれいに表現されていると感じました。

時間の関係上リファクタリングの過程が見られなかったので、発表資料の公開が待ち遠しい限りです。

Protocol Buffers(TakuSemba)

  • 自己紹介
    • 最近ProtocolBufferを使うことがあった
    • CyberAgent, Inc.
  • Protocol Bufferとは
    • Google制のデータ通信の使用
    • JSONではなくバイナリで通信する
  • Quick Start
  • Proto fileの定義
  • スクエア制のツール
    • Javaファイルが書き出される
    • プロジェクトに追加する
  • Let’s 通信
    • dependenciesに追加
    • Retrofit
  • まとめ
    • メリット
      • データ量が少ないので早い
      • Proto fileで共通認識が取れる
    • デメリット

最近何かと話題に上がるProtocol Buffer の話。 やはりデバッグしづらかったり、API変更が面倒だというのは、どこでも共通認識のようです。

Proto fileで共通認識が取れる、という視点は今までなかったので勉強になりました。

LicensePlist(mono)

www.slideshare.net

  • 自己紹介
    • mono
  • LicensePlist
    • ライセンス管理を自動的にやってくれる
  • 今まで決定版がなかった
    • 決定版を目指して作った
    • SPMで管理
    • 手動で入れたものまで検出してくれる
  • 仕組み
    • LICENSEファイルをかき集めている
  • Cocoapods
    • plistを解析すればOK(ローカルにある)
    • Cartfile.resolvedから依存ライブラリのGitHubを見に行く
    • ライセンス取得APIGitHubから
  • plistの生成
    • PropertyListSerializationというものがある
    • 最初は自分で書いてしまったら真っ白になることも
    • YAMLファイルで柔軟性を担保
  • install
    • Homebrewに対応してます
  • 設定
    • Buildのpre-actionに設定するのがおすすめ
  • QA
    • 他の設定を生成したい場合は?
      • 出力形式を変更するだけなので要望があれば対応する(ViewControllerとか)

ライセンス管理自動化の決定版的ライブラリを作ったよ、という話。 その宣伝文句に違わず、CocoaPods、Fastlane、手動など、様々なケースに対応していてとても良さそうでした。

懇親会

窯焼きのピッツァ(!)

最後に

ポテチの参加は初めてだったのですが、多彩な発表が聞けてとても楽しかったです。 会場、飲み物、食べ物を提供してくださったRettyさん、主催者、発表者、の方々、本当にありがとうございました。 (もちろん懇親会で話してくださった方も)

ちなみに勉強会では結構メモるタイプなので、ブログまとめなんて楽勝だと思っていたのですが、 LTはテンポが非常に早くて、メモをしながら発表についていくのは思ったよりもハードでした(笑)

ではまたの機会に参加できることを楽しみにしつつ、締めたいと思います。

技術用語メモ

新しく知った技術用語とかをダンプするようの記事。

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の例

ActiveRecordRuby on Rails で使用されているORMapperである。

以下はmoviesテーブルのレコードに対応するEntityクラスを定義した例である。

class Movie < ActiveRecord::Base
end

このように特定のクラスを継承するだけで実現できる。

テーブル名はクラス名Movieから取得し、カラムに対応するアクセサメソッドはDBのスキーマから取得し、実行時に動的にクラスに対してメソッドを追加することで実現できている。

実行時に情報が消えてしまうC/C++のような言語ではこのようなことは出来ず、ボイラープレートが増えてしまう。もちろんコードジェネレータを使用した「静的メタプログラミング」も可能だが、それは言語の外で行われるもので、プログラム実行時に行える「動的メタプログラミング」ほどスマートではない。(ジェネレータを実行する手間もあるだろうし、コード上からボイラープレートコードは消えない)

Rubyにおけるメタプログラミングは特殊ではない

Rubyにおいてメタプログラミングは特殊なものではなく、「通常」のプログラミングと明確に区別できるものではない。

そういった意味で、 Rubyを使いこなすにはメタプログラミングを理解することが重要である。

MongoDBメモ(その1)

dot install のレッスン動画を見ながら勉強。
http://dotinstall.com/lessons/basic_mongodb_v3/35001

この記事の範囲。 - 01 MongoDBとはなにか? - 02 MongoDBをインストールしよう - 03 用語を理解しておこう - 04 データベースを操作してみよう - 05 コレクションを操作してみよう

概要

  • ドキュメント指向(Not RDB
  • NoSQL(スキーマレス)
    • スキーマ構造を事前に決めない(便利なこともある)

インストール

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

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();