おいしい健康 開発者ブログ

株式会社おいしい健康で働くエンジニア・デザイナーが社内の様子をお伝えします。

Apache Solrでサジェスト機能を実装する

こんにちは。おいしい健康に入社して2ヶ月目の44akiです。

今回、おいしい健康のアプリで検索窓の入力サジェスト機能を導入する機会があり、 Apache SolrのSpellCheckComponentを使って実現しました。 おいしい健康のサービス全体でいえば小さな機能ではありますが、前職では検索エンジンベンダーでエンジニアをやっていたので、こういうところには無駄に拘ってしまいます。

この記事の内容は、Apache Solrのバージョン4.10.4で動作確認をしています。

f:id:oishi-kenko:20171107173455p:plain

候補語のデータについて

入力サジェスト機能を実現する場合、その候補語となるデータの取得元は大きく分けて2つあり、それぞれにメリット、デメリットがあります。

  1. 検索対象のデータから形態素解析で取得する
    検索対象のデータをmecab等の形態素解析エンジンで分かち書きして、候補語のデータとして使用する方法です。おいしい健康の場合はレシピ情報がこのデータにあたります。検索対象データを形態素解析して取得した候補語のため、必ず検索にヒットする候補語が取得できるというメリットがありますが、形態素解析エンジンの辞書データをもとに分かち書きされるため、辞書データの精度が低いと、候補語が名詞の途中で途切れたり、意図しない候補語が表示される可能性があります。

  2. 検索ログから取得する
    ユーザが実際に検索したキーワードをログとして保存しておき、候補語のデータとして使用する方法です。検索ログから候補語を取得しているため、ユーザーが実際の入力するようなキーワードをサジェストすることが出来ます。また、過去1ヶ月間の検索ログなど、集計対象の期間を絞ることで、キーワードのトレンドを反映し、秋ならサンマ、冬に近づくとサバを候補語の上位に表示するなどが実現できるようになります。ただし、検索ログベースのため、検索ログを取得する環境を構築する必要がある、検索にヒットしない候補語を除外する必要がある等、実装のコストは増えてしまいます。

今回は2の検索ログベースでサジェスト機能を実装しました。

schema.xml

先ずはApache Solrのスキーマを定義していきます。
候補語の表示用として name フィールドを定義します。

<fields>
    <field name="_version_" type="long" indexed="true" stored="true"/>
    <field name="id" type="string" multiValued="false" stored="true" indexed="true"/>
    <field name="name" type="string" multiValued="false" stored="true" indexed="true"/>
</fields>

また、検索用に text_ja_romaji の型を定義しています。 ローマ字に変換して検索を行うことで、入力途中のキーワードでもサジェストが行えるようにしています。

<fieldType name="text_ja_romaji" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="false">
  <analyzer>
    <tokenizer class="solr.JapaneseTokenizerFactory" mode="normal"/>
    <filter class="solr.CJKWidthFilterFactory"/>
    <filter class="solr.JapaneseReadingFormFilterFactory" useRomaji="true"/>
    <filter class="solr.ShingleFilterFactory" minShingleSize="2" maxShingleSize="99" outputUnigramsIfNoShingles="true" tokenSeparator=""/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

全体的な流れとしては、 JapaneseTokenizerFactory でKuromojiによる形態素解析を行い、 JapaneseReadingFormFilterFactory のオプションでuseRomajiを指定することで形態素解析で取得した読みをローマ字に変換します。最後に ShingleFilterFactory により形態素解析で分割された文字列を連結します。

ローマ字変換のイメージ>
おいしい健康→おいしい 健康→oishi kenko→oishikenko

solrconfig.xml

次にサジェスト用のsearchComponentとrequestHandlerを定義します。

今回はSolrの solr.SpellCheckComponent を使います。

<!-- Auto Complete component -->
<searchComponent class="solr.SpellCheckComponent" name="autocomplete_ja">
    <lst name="spellchecker">
      <str name="name">autocomplete_ja</str>
      <str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
      <str name="lookupImpl">org.apache.solr.spelling.suggest.fst.AnalyzingLookupFactory</str>
      <str name="buildOnCommit">true</str>
      <str name="comparatorClass">score</str>
      <str name="field">name</str>
      <str name="suggestAnalyzerFieldType">text_ja_romaji</str>
      <bool name="exactMatchFirst">true</bool>
    </lst>
    <str name="queryAnalyzerFieldType">text_ja_romaji</str>
</searchComponent>

suggestAnalyzerFieldTypeとqueryAnalyzerFieldTypeに先程定義したtext_ja_romajiを指定することでローマ字での前方一致検索を行っています。

comparatorClassで候補語のソート順を指定します。score、freq、もしくは独自で作成したcomparatorClassが指定可能です。今回のように検索ログベースで、検索回数順にソートする場合は、通常はcomparatorClassを作成する必要がありますが、今回は前述のnameフィールドに「キーワード:検索回数」のようなフォーマットでインデックスし、アプリ側で取得したキーワードと検索回数をもとに検索回数順にソートすることで、簡易的に検索回数順ソートを実装しました。

最後に、上記のsearchComponentを「/autocomplete_ja」のパスで受けられるように、requestHandlerを定義します。

<!-- Auto Complete handler -->
<requestHandler name="/autocomplete_ja" class="org.apache.solr.handler.component.SearchHandler">
    <lst name="defaults">
      <str name="spellcheck">true</str>
      <str name="spellcheck.dictionary">autocomplete_ja</str>
      <str name="spellcheck.collate">true</str>
      <str name="spellcheck.count">100</str>
      <str name="spellcheck.onlyMorePopular">true</str>
    </lst>
    <arr name="components">
      <str>autocomplete_ja</str>
    </arr>
</requestHandler>

終わりに

今回はApache Solrの定義の部分のみの説明でしたが、実際には、Fluentd、BigQueryによる検索ログ取得、検索にヒットしない候補語の削除等も行いました。Apache SolrのSpellCheckComponentを使うことで比較的簡単に入力サジェストの実装を行うことができました。

MySQLにユーザーと権限を設定する

MySQLにユーザーを追加する機会がありましたので、ユーザー作成と権限追加について復習しました。
MySQL 5.6で動作確認しています。

dockerを使い、動作確認用のコンテナを起動します。 簡単に捨てられる環境が使えるのは便利ですね。

$ docker run -e MYSQL_ROOT_PASSWORD=password -p 13306:3306 --rm mysql:5.6

一通りログが流れきったら使えるようになります。 mysqlコマンドで母艦からmysqlにアクセスします。

$ mysql -u root -p -h 127.0.0.1 -P 13306

まずはユーザー一覧を表示します。

mysql> select Host, User from mysql.user;
+-----------+------+
| Host      | User |
+-----------+------+
| %         | root |
| localhost | root |
+-----------+------+

何も設定していないのでrootしかいない状態です。検証用のユーザーを作成します。

mysql> create user writable identified by 'hogehogehoge';

hogehogehogewritableユーザーのパスワードです。ユーザーを作成したので権限を確認してみます。

mysql> show grants for writable;
+---------------------------------------------------------------------------------------------------------+
| Grants for writable@%                                                                                   |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'writable'@'%' IDENTIFIED BY PASSWORD '*E8DD65E018E30F27D962FB9BFA2F4E8206DC3AF8' |
+---------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

USAGEは権限なしを表します。この辺に権限の説明があります。 https://dev.mysql.com/doc/refman/5.6/ja/privileges-provided.html

rootの権限は*.*を対象にALL PRIVILEGESをもっているので、すべての権限をもっています。

mysql> show grants for root;
+--------------------------------------------------------------------------------------------------------------------------------+
| Grants for root@%                                                                                                              |
+--------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' WITH GRANT OPTION |
+--------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

権限を付与するためのデータベースを作成します。

mysql> create database hoge;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hoge               |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)

hogeデータベースが作成されました。

この時点でwritableユーザーでログインしてデータベース一覧を表示してもinformation_schemaしか表示されません。

$ mysql -u writable -p -h 127.0.0.1 -P 13306
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)

writableユーザーにhogeデータベースの全ての権限を付与します。

mysql> grant all privileges on hoge.* to writable@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for writable;
+---------------------------------------------------------------------------------------------------------+
| Grants for writable@%                                                                                   |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'writable'@'%' IDENTIFIED BY PASSWORD '*E8DD65E018E30F27D962FB9BFA2F4E8206DC3AF8' |
| GRANT ALL PRIVILEGES ON `hoge`.* TO 'writable'@'%'                                                      |
+---------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

これでwritableユーザーが自由にhogeデータベースを操作できるようになりました。 再びwritableユーザーでログインしてデータベース一覧を見るとhogeデータベースが表示されます。

$ mysql -u writable -p -h 127.0.0.1 -P 13306
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hoge               |
+--------------------+
2 rows in set (0.00 sec)

テーブルを作り、レコードをいくつか追加します。

mysql> create table users(
    ->   id int auto_increment not null primary key,
    ->   name varchar(32)
    -> );
Query OK, 0 rows affected (0.08 sec)

mysql> insert into users(name) values('Taro'),('Hanako'),('Jiro');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from users;
+----+--------+
| id | name   |
+----+--------+
|  1 | Taro   |
|  2 | Hanako |
|  3 | Jiro   |
+----+--------+
3 rows in set (0.00 sec)

再びrootに戻り、今度はreadonlyユーザーを追加します。 読み込みだけできればいいので、SELECT権限だけ付与します。

mysql> create user readonly identified by 'hogehogehoge';
Query OK, 0 rows affected (0.00 sec)

mysql> grant select on hoge.* to readonly@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for readonly;
+---------------------------------------------------------------------------------------------------------+
| Grants for readonly@%                                                                                   |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'readonly'@'%' IDENTIFIED BY PASSWORD '*E8DD65E018E30F27D962FB9BFA2F4E8206DC3AF8' |
| GRANT SELECT ON `hoge`.* TO 'readonly'@'%'                                                              |
+---------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

ユーザーの作成ができたので、動作確認してみます。

$ mysql -u readonly -p -h 127.0.0.1 -P 13306

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hoge               |
+--------------------+
2 rows in set (0.00 sec)

mysql> use hoge;
Database changed
mysql> show tables;
+----------------+
| Tables_in_hoge |
+----------------+
| users          |
+----------------+
1 row in set (0.00 sec)

mysql> select * from users;
+----+--------+
| id | name   |
+----+--------+
|  1 | Taro   |
|  2 | Hanako |
|  3 | Jiro   |
+----+--------+
3 rows in set (0.00 sec)

mysql> insert into users(name) values('Saburou');
ERROR 1142 (42000): INSERT command denied to user 'readonly'@'172.17.0.1' for table 'users'

select文で内容を表示することはできましたが、insert文を実行することはできませんでした。

以上です。

esa のトップページを活発にするなら esapad があるじゃない

(\( ⁰⊖⁰)/) < こんばんは!

おいしい健康でいろんな開発を担当しています、関口 id:tanukiti1987 です。

社名やサービス名となっているおいしい「健康」ですが、今日の晩ご飯はカップラーメンを食べてしまいました。

全粒粉入りの麺だということだったので、それでご勘弁願いたいです。

情報共有ツールとしての esa

弊社では、諸々の事情により社内の情報共有ツールに esa を使っています。

社内wiki として非常に整理された機能を持っており、合わせて WIP でモノを書いていこう!荒々のうちにアウトプットしていこうぜ。のコンセプトが非常に気に入っております。

GoogleAnalytics を仕込むこともでき、みんながいつどれくらい活用しているかだって見れちゃいます。 自前のS3バケットに画像などを保存していくこともできます。

できることが結構多い!最高!

esapad is 何

esa はレスポンシブにデザインされていて、ある程度広い画面で見ていれば 「Recently updated」という項目が見れて、最近のみんなの動きが見れるのですが、ノートPCで特に意識せずにブラウジングしているくらいでは、この項目がまー、出てこない。

そこで esapad です。

github.com

READMEとなるページに特定のタグを埋め込んでおき、 この rubyコードを実行すると、指定したページに stock な記事、flow な記事、最近スターされた記事などをリストでリプレイスしてくれます。

弊社ではこんな感じで活用しています。

f:id:oishi-kenko:20170818204523p:plain

全然見せられそうなのがないので、 esapad に対応した!というblog 記事だけモザイクなしです..

この esapad を定期的にジョブ管理システムに実行させるようにして、対応がサクッと完了します。

弊社ではトップページを開いたときに常にこの stock/flow の記事を見られるようにして、動きを少しでも出すようにしています。

動きがでることで更に活発になっていくことを願って、やってみました。

最後に

esapad は id:hogelog さんが作ったものですが、 gem を公開してくださいよ〜。とツンツンしていたら僕 contributor に加えてくださり、僕が少しだけ手を加えたものです。

こんなことやってみたいんだけど。。使ってみたけどバグってる。。などありましたら、お気軽に issue を立てたり、pull request したりしてください :)

それでは、よい週末を〜。

あれっ。 Xcode9(beta5) が遅すぎる... と思ったときにありがちな問題

こんばんは! 関口@tanukiti1987 です。

おいしい健康にも新たな動きがあり、今は iOS 開発に取り組み始めています。

いきなり余談ですが、新卒で入った会社では iPhone OS 3, iOS 4 までは iPhoneアプリの開発に携わっていました。 今はもう Swift でのアプリ開発が主流になってきていますが、当初はまだ Swift の影もなく、 Objective-C が現役を勤めているころでした。

あれから5年。

久しぶりの iPhone アプリ開発に心踊らせ、弊社のプロジェクトは Swift 4.0 と Xcode9 beta5 で開発を進めています。 このまま、開発を続けていってもアプリをリリースするころには、iOS11もXcode9 も出ているだろうし、それを見越した開発です。

余談が長くなりましたが、久々に起動したXcodeは時折鬼のように遅く、マシンをフリーズさせることもしばしば。。 仕事進めさせてくれよ。。と思っていろいろ調べていると、2つ気をつけなければならないところがあったようでした。

1. IBDesignablesAgentCocoaTouch のCPU食い過ぎ問題

Xcode がフリーズしたときにアクティビティモニターを見ていて気になったこのプロセス。

どうやらプロジェクト内で @IBDesignable を定義していると動くプロセスみたいで。

今週から開発し始めた僕は、 @IBDesignable を意気揚々と定義して、ストーリーボードで開発しやすくするぞ!と思っていたのが仇となっていたようです。

PCのスペックの問題もあるかと思いますが、僕のPCでは苦痛なほど作業効率を悪くするものだったので、スッと消して置きました。

ちなみに Editor -> Automatically Refresh Views をオフにすることでこの手の事象を回避することもできるようです。

stackoverflow.com

2. XcodeまわりのプロセスがCPU食いすぎてマシン応答が劣化していく問題

開発を続けていくと、これと言って何か重い処理をしているわけではないのに、Xcode周りのプロセスがどんどんCPUを使っていき、しまいにはフリーズすることもしばしば。

しばらく困り果てていましたが、 Xcode のウィンドウを開いた状態で Product -> Clean またはオプションキーを押しながら Product -> Clean Build Folder をしてみました。

すると、少なくともCPUが張り付くことがなくなり、ビルド途中でフリーズするとこともなくなりました。

この手の不具合は、5年前にもあったようなきがするけど、すっかり忘れていました。

ときどきクリーンしよう。

終わりに

久々に Xcode を開いてみましたが、 beta を使っていることもあってか、それ以外の不具合にも多数遭遇します。 若干チャレンジングだと思ってはいますが、Swiftもだいぶ書きごこちよく、楽しく開発していますヨ :)

おいしい健康の開発者、本格募集をはじめました!

f:id:oishi-kenko:20170630111418j:plain

おいしい健康で開発全般を担当している関口です。 こんにちは!

4本目の Tech Blog で、さっそく求人のことを書くのはどうなのよ?と自問自答を繰り返しましたが、やっぱりみなさんにお知らせしたい!ということで、おいしい健康で開発者(デザイナも!)の本格募集を始めたお話です。

求人内容のご紹介

今回の求人への思い(番外編)

他社のたくさんの原稿があるなかで、少し毛色の異なる求人なのかなと思っています。

おいしい健康では、どんな思いで日々開発を進めているのかを大切に書かせていただきました。 一方で、福利厚生や待遇面については文字数制限の兼ね合いもあり、控えめに書いています。

まだまだ小さい会社です。はたらきやすさ。というのは、全社員で話し合っていく余地が十分にあり、正しく主張していくことでどれほどにでも働きやすくなっていく環境にあります。どうかその点は心配しないで、来ていただきたいと思っています。

働きやすさの一方で、正直、求めているスキルはすこし高いのかもしれません。 それぞれのスキルや軸がしっかりしているからこそ、その信頼の元にはたらきやすい環境を築ける。というのが僕の理解です。

会社が立ち上がってからの、初めての採用活動です。 いただいた書類は、ていねいに見させていただきます!

面白そうだな、なんか違うな、へーッ。と思ったかた、それぞれの感想があるかと思いますが、共感いただけると一人でもおおくお会いできることを楽しみにしています!

誰のための何のためのデザイン?

おいしい健康のデザイナー深澤です。 昨日wwdc最後の日を終えて、明日帰国します。

実は今回私にとって初のアメリカ旅でした。 正直、渡航前の私はよく知りもしないくせに勝手に、アメリカはすごく合理的で粗野で…とマイナスなイメージを描いていました。デザインに関しても、本当に失礼なのですがあまり期待していなかったというか…得られるものがあまりないんじゃないかとか思っていたんです。 ですが、そういう考えをしていたのが恥ずかしいくらい大きな気づきがありました。 いろんな国の人がいろんな言語を喋り、違う信条で生き一緒の場所で暮らしていくための生活やコミュニケーションの工夫や努力にただただ感動したのです。 それはもちろんwwdcの会場でももちろん感じたのですが、会場の一歩外を出たときにもっとひしひしと感じました。 日本にいるときは、まあこれが普通だよねと「普通」に頼って生きる生活をしていますが、きっとここにきたらそういうスタンスでは生きていけないなと。生活をしていて人との違いに目を向けずにはいられない環境なのです。言葉も見た目も宗教も何もかもが違う人々が同じ環境で生きていくにはどうしたらいいのか、否が応でも考えずにはいられない環境です。

Appleのデザインの考え方にもそういう考え方が現れているんじゃないかと思いました。 いかに「普通」に頼りすぎず様々な人が自分らしく生活できるようにするのか。iPhoneをもし使えない人がいたら…盲目の人や操作が難しい人がいたら…。 いろんなセッションで、Human Interface Guidelineにある「Dynamic Type」という言葉が出てきていたのですが、これはつまり基本設定の文字の大きさをレイアウトに制限を受けずにレスポンシブに表示変更できる、ということです。年配の方や弱視の方もきちんと見えるようになる、ということです。 また、盲目のロッカーがiPhoneのVoiceOverでバンド活動をして音楽を楽しむ生活や、事故の後遺症で肩から上しか体を動かすことができなくなってしまった人が舌でiPhoneを操作し、HomeKitなどを利用して家族と犬と楽しく生活する姿を写した動画を見たりお話を聞くこともできました。

つい開発者が自分の中にある視点だけでものづくりをしてしまうと、そのことだけにとらわれ、例えば見た目をよくしたいということや使い勝手を簡単にしたいというような手っ取り早く簡単に変える方法を第一にしがちですが(もちろんそれも間違いではないし素晴らしいこと)、本当にその人のためになり毎日使いたいと思われ喜ばれ続けるものを作るとしたら…それはそういう表層のことだけではカバーできないのではないか…と改めて思いました。

たくさんの人の話を聞く必要があるし、その人たちの生活や考えや悩みを理解する必要があります。そしてその前に自分がどんな人のどんなことを助けたいと思うのか、きちんと大きな目標を明確にし、たくさんその人の悩みについて研究し、話を聞きに行き理解しようと努力することが必須だと思いました。それなしにデザインはできないなと。

おいしい健康であれば、「世の中の病気で困っている人や健康な人が、毎日のおいしい食事で薬や病院に頼らず健やかでいれる」という目標を実現するために、その人たちの悩みについてものすごく研究する必要があるし、その人たちの日々の話を聞いて理解する必要があります。 おいしい健康は、日々それらを努力をしているつもりでしたが、今回いろんな人と出会うにつれ、まだまだまだ全然理解が足りていない!と改めて思いました。

たくさんの気づきに溢れた出張の機会を与えてくれたwwdcに本当に感謝です。 また、この旅の途中で出会いたくさんいろんなことに気づかせてくれた方々にも感謝です。 おいしい健康は、この学びを糧により一層パワーアップしていきます!

ためになる開発トークではなく、気持ち重視のブログになってしまいましたが、このアウトプットをしないとなんだかこの旅が昇華しきれないような気がしたので投稿します。

来年の今頃またこのブログを見返そう。 来年はアプリを引き下げて必ずこの地に戻ってくるぞ! またね、サンノゼ

f:id:oishi-kenko:20170611173932j:plain


おいしい健康で一緒に働きたい方を募集中です!

おいしい健康エンジニア・デザイナ募集中

iOS11 から AppStore のデザインが変わる..! ので色々気をつける所ありそう

f:id:oishi-kenko:20170608102531p:plain

おいしい健康でエンジニアをしています関口(@tanukiti1987)です。 前回の記事WWDCの話題が上がりましたが、僕もWWDCに来ています!

Yey!

サンノゼは、東京よりも朝夜が特に肌寒く、一枚多く羽織る感じです。 そして、WWDC会場内は一層寒く、凍えながらセッションを聞いています。

周辺の人たちがたくさんの記事を上げていると思いますので、僕からは今回発表されたAppStoreのデザイン変更について感想を書いていきたいと思います。

Awesome!

ちなみに写真は朝食のドーナッツです。 参加者は朝早くに会場入りし、列の横にあるドーナッツやコーヒー、パンや果物を手にしながら、長い長い行列を待つことになります。初日こそ、勇み足で食べていたのですが、徐々に甘さに耐えられなくなってきたところでした。

Redesign App Store

f:id:oishi-kenko:20170608154839p:plain From WWDC 2017 Keynote

iOS11からアップストアのデザインが大きく変わり、タブの内容は

  • Today
  • Game
  • App
  • Update
  • Search

の5つになるようです。

とりわけ目を引くのが Today タブです。

このタブは世界それぞれのリージョンで、Editor と呼ばれる人たちというかチームが厳選するアプリをフィーチャーしたり、様々なコンテキストで必要になるアプリをまとめて一つのカードにし、アプリを探しやすく、ダウンロードしやすくするようになるみたいです。

これらのカードは日ごとに更新され、日々新しいコンテンツを配信してくれるようです。

先程から出てくる カード というのをタップすると、より詳細なコンテンツが見られるようになります。

f:id:oishi-kenko:20170608155341p:plain From WWDC 2017 Keynote

大きなタイトル、サブタイトル、キャッチコピーが書かれたアイキャッチが目に入り、以下にテキストやイラスト、動画が含まれていきます。

これらのページを最初に見たときには、とてもサードパーティーがiTunesConnect などを通して投稿できるものではないと思ったのですが、ここは Editor が実際にアプリをチェックし、そのアプリのストーリー性やユーザビリティをレビューした上でコンテンツを作っていくようです。

我々サードパーティーとしては、アプリにきちんと文脈があり、フォーカスされた目的があり、一見してわかりやすいことがより強く求められるようになるようです。

Keynote 時点から画面の内容は変わっていくのかもしれないですが、やっていきを感じざるを得ません。

やっていこう。

f:id:oishi-kenko:20170608160547p:plain

From WWDC 2017 Keynote

ちなみに動画が自動再生されて、アプリの紹介がされるところも多くあり、アプリの紹介動画やコンセプト動画を作ることは非常に重要になってきそうな気がしました。

あらゆる方面で、正しくアプリを作ることが求められ、AppStore の玉石混交の世界がより玉が多くような世界を目指しているのかなと思います。

たくさんの要素技術が発表されている場でもあるWWDCですが、朝から夜まで出ずっぱりなのでなかなか実際に手元で試してみることができないのですが、早く落ち着いて他の話も書いていきたいですね!(CoreML とか Xcode9 とか)

明日を含め、残り2日! 非常に学びの多い場ですので、出来る限りたくさん吸収して日本に帰ろうと思います。

それでは (^_^)/~