💝PrismDBとかプリッカソンでやってたこと

f:id:banjun:20191217230827j:plain

ばんじゅんです。最近は「原宿駅からすぐ近くの表参道」でお仕事をしています。プリパラで好きな曲は HAPPYぱLUCKY です。 この記事はプリッカソン Advent Calendar 2019の18日目の記事です。昨日はやっちさんの「真中のんさんの魅力について」でした。まだの方は是非こちらも読んでみてください。

プリッカソンはプリティーシリーズにまつわるものづくりコミュニティです。

takanakahiko.hatenablog.com

わたしは今年は4月・7月・10月のプリッカソンに参加しました。今年はPrismDBをネタにした活動が多めにしていたので,PrismDBとその周辺技術の話をざっくりまとめようと思います。特にブログにもしなかったし。私がやった作業の話というよりは,私の作業とその周辺で起きていたことのお話ということで,実際の立案や開発編集はここのコントリビューターの方々やその周辺でアドバイスをする人たちによるものです。

はじめに PrismDBの基本スペック

PrismDBはプリティーシリーズの情報をまとめるプラットフォームで, https://prismdb.takanakahiko.me でホストされている。プリティーシリーズのキャラクター・アニメ・楽曲・筐体があるお店・筐体のアイテムがまとめられるべく,データが追加編集されていっている。

プリッカソンのようなイベントで,キャラクターの名前一覧が欲しいときに使うというようなシンプルな利用から,SoLaMi♡SMILEがアニメ中でライブをした話数とそのときのコーデと曲を一覧を取得するような利用もできるように想定している。(現状ではアニメ中のコーデのデータは足りていないと思われるが原理上は・・・!協力あるとうれしい)

現時点では元データはgithubで管理されている。

github.com

データの種類ごとに分かれたCSVにデータを入れてPulll Requestしてマージされると上記サイトにホストされるので,Web UIで見たり,SPARQLのクエリを投げたり,RESTで取り出せる。現時点で35キャラクター106楽曲300エピソード227ライブ2983アイテム2289店舗が登録されている。

ところで

今年のライブはマイパマ、マイパマ、マイパマ、マイパマ、オオサカプ、マクパリに行きました。

f:id:banjun:20191218001646p:plain
sketch.pixiv.net/items/3898127405622949419

PrismDBの変遷

ハッカソン系のイベントでなにかサービスを開発しようとしたときに,作品の基本情報が既にまとまっていると便利なことがある。アイマス界隈 では im@sparql というSPARQLエンドポイントがあったので,それを成功事例として,プリパラでも情報をまとめようとした。

はじめはプリパラDB(仮)と呼ばれていて,Firebase Realtime DatabaseにJSON様の構造で書いていた。お手本となるim@sparqlではRDFのXML(例)を編集する必要があったため,データ編集作業をもっと簡単にできないかということで,Googleスプレッドシートを使うとか,編集用のWeb UIをつくるなどが検討されたが,多様なデータ構造を扱うのはそんなに簡単でもなく,「差分で見たい」「データ破壊があっても平気なようにバックアップしたい」を満たすために,githubCSVでデータを置いてJSON変換して表示するように移行,さらにRESTのユースケースを事前に定めて実装することなくデータに直接ク エリを投げられるよう,また他の作品のエンドポイントと相互接続できるよう,RDF変換してSPARQLエンドポイント提供がされるようになった。

RDFというのは,キャラクターや楽曲などの対象URIを付け,そのURI間やURIと文字列などの値(キャラクターの名前とか)のあいだに関連を貼るだけの構造で,繋がりの自由度は高い。しかしそのまま書くのは難しい(あるいは敷居が高い)。実際にある対象(例えばプリパラ13話)の編集作業を(たくさんすることを)考えると,表を作る作業とあまり変わらないことも多いので,データを書く人が単に表感覚で編集できるようにCSVで書けるようにしている。

githubにデータを置くことによって得られるメリットは様々だが,github慣れしていない場合に編集に参加しづらくなるのではという懸念がある。githubGoogleではないのでスプシのように編集できるわけではない。(MSに買収されたので,そのへんの技術で,CSVをいい感じにWeb上で編集してPRできるようになったらいいなぁ)。データ追加事例ではぐんそーさんの PrismDBにアイテムデータを追加してみた|ぐんそー|note がパワーがあってすごい。

ところで

Winterのキラリスト・ジュエリスト良きでしたね。

music.apple.com

SwiftSparql — SPARQLをSwiftで使う

いっぽう私は2月にほぼ無職期間があったので,Swift用にSPARQLのクエリジェネレーターと結果パーサーを作った。

github.com

これは半分くらいはSPARQLの構文をSwiftの型に落とす肉体労働だったので寝ぼけながらもアイドルはキンリョクということで乗り切った。

少しはSPARQLの文法が分かるようになり,文字列リテラル一致のセマンティクスが分かりづらいので言語文字列リテラルを使わないほうがミスりにくいとか,タイプ(rdf:type)を付けるとクエリ(とクエリジェネレータ)を書きやすいとか,そのタイプごとに語彙(述語のリスト)を把握したほうがよいとか,の知見を得た。

github.com

得られた知見をもとに,これらいくつかの設計をした。TypeScriptを書いたことはなかったが、まぁなかひこくんがレビューしてくれるしな、って書いた。

ところで

ロケットハートもライブで聴きたいですね。

ロケットハート

ロケットハート

music.apple.com

プリッカソンでやってたこと2019

4月は,アニメのライブ部分だけを無限再生するアプリ作ろうかなと思って,もしライブの時刻アノテーションがPrismDBにあったとしたら,で再生部分が作れるかを試した(banjun/PrismTV)。今となっては,再生の仕組みと,アノテーションPrismDBに追記する仕組みは,分離せずにひとつのワークフローの中で出来るようにしないと手間が減らなくて進まないなと思っている。

7月は,SwiftSparqlをSwift 5対応にしたあと,PrismDBの語彙であるところのプリズム語彙の補完に対応させた。プリズム語彙って言うとかえって難しく見えそうでもあるが,単にPrismDBで使われている述語の一覧のこと(prism-schema.ttl)である。

10月は,Xcode 11のSwiftで使えるFunction Buildersの構文を使って,クエリジェネレータの不要なインデントを落としてすっきり書けるようになるかを試した。結果としては効果は大きくなかったしより適用を増やせばデメリットも増えていきそうだったので保留にしている。未着手の新機能系では,Xcode Previewsに対応させたほうが楽しそうである。

おねがい!

SoLaMi♡SMILEにも新曲をください!

PrismDBデータ化における概念の難しさ

比較的自由な構造でデータを追加できるようになったとはいえ,プリティーシリーズ特有の概念の難しさと向き合わなければいけない局面は出てきて,これはプリティーシリーズに詳しい女児のみなさんがプリッカソンで集まったとしても概念の統合と分離には諸説出てしまうくらい難しいようなネタがあるようだ。一例としてはこんな問題(問い)があるので,わたしのように,果たして真中らぁらとはなんであるのか・・・と考えてみるのも楽しいと思う。複雑性を楽しみつつもデータは充実させていこう。

  • 大らぁら(プリパラらぁら)と小らぁらは別のキャラクターなのか?
  • 「らぁら&みれぃ」はチームなのか?
    • 任意のキャラクター同士の組み合わせはチームであるのか?楽曲があるか?一緒に歌ったか?結成式をしたか?
  • アニメ中の(劇中)ライブリアルのライブ(プリパラWinterライブ2019とか)の両方に「ライブ」という名前はややこしい
    • ライブはショーなのか?
  • リアルライブのセットリストの毎回信頼できる情報源は存在するのか
    • おともだちのツイート?BD発売されると分かる?メディアのレポート?
  • アニメのコーデ筐体のコーデは同じ?異なる?
    • デザインは一致しているのか? 筐体はパーツ,アニメはひと揃いで出現・名付けがされる?
  • 筐体アイテムのIDはなんなのか?採番が被っている例がある?
  • そらみドレッシングi☆Risなのか?
    • キャラクターならそらみドレッシングで中の人ならi☆Ris?OP/EDやCDの名義との一貫性は?「Run Girls, Run! ※アーティスト」パターン?
  • 一人二役(1声優:複数キャラクター)はどこまで扱えるのか?
    • ライブの出演者リストでは複数役かどうか区別されてそう?曲からどちらかが決まる?衣装?Make it!歌ってたらどうする?

おわりに

そのままでは絵として見えてこないということで、やっぱりなんだかよく分からないものをやってる感はやはり出てしまうのかなぁ、分かりやすい成果物がほしいなぁとは思いつつ。でも直近で欲しいのって,PrismDBから出力されPrismDBに追従して更新されていく漢字変換辞書だったりして。。それもまた地味かもしれないですね。でもほしくないですか?

プリッカソンアドベントカレンダーの明日はダンディ(閣下)さんです。そちらのチャンネルもぜひご覧ください。つながる広がるフォロワーの輪!! ステキな番組 ON AIR!!

🔊watchOS 6の騒音レベルとともにライブを振り返る ~ 心拍数もあるよ ~

ばんじゅんです。最近はZOZOTOWNiOSアプリの実装のリアルと技術的に向き合うお仕事をしています。この記事はZOZOテクノロジーズ #2 Advent Calendar 2019の12日目の記事です。昨日の記事はymd_aaaさんの「SpringAnimationを気軽に使おう」でした。こちらの記事も是非ご覧ください。

これまでのあらすじ

banjun.hatenablog.com

アイマスライブをはじめとしていくつかのライブにApple Watchを付けていって、心拍数を記録し、ログをみて振り返りをしたり、1年後のライブBlu-rayの発売後にそれを再生しつつ同時刻の心拍数グラフを重ねて表示するためのライブラリ banjun/YesBDTimeやそのアプリmzp/HeartVoiceを作成した。

今年の試み

Apple Watch Series 4 + watchOS 6では、耳の健康(ヒアリングヘルス)を守るために、騒音レベル(またはノイズレベルやAudio Exposureと呼ばれる)の測定と警告通知の機能が搭載された。この騒音レベルはHealthKitに記録され、ヘルスケアアプリで見ることができるし、APIから取得もできる。

support.apple.com

Apple Watch を装着している間は、Apple Watch が一日を通して騒音レベルを定期的に測定します。これにはマイクを使いますが、音声の録音や保存は行いません。

ライブ会場で常時録音機能があると、持ち込みのレギュレーションに心配があるが、Appleの公式仕様によれば録音機能を持たないので安心である(※私が安心と思っているの意でありいずれかの組織の確認が取れた情報ではありません)。

ヘルスケアアプリで見るとdBで細かく記録されているが、概要レベルのグラフしか見ることはできないので、HealthKitのAPIを利用して騒音レベルを全て取得し、ライブが開催されていた時間帯について、心拍数のグラフと騒音レベルのグラフを並べて表示してみたい。

データ収集

各地でライブに行ってデータ収集をしていたが、ここではTHE IDOLM@STER CINDERELLA GIRLS 7thLIVE TOUR Special 3chord♪のツアーの幕張・名古屋の計4日間のデータを使用した。チケット連番で現地に連れていってくれたり余らせたチケット連番を受けてくれた方々に感謝します。

f:id:banjun:20191211003114j:plain
千葉公演 Comical Pops!の会場となった幕張メッセ国際展示場 9-11ホールにて(背景はZOZO・ZOZOテクノロジーズ(幕張オフィス)の入居するビル)

開発 ~ アイマスハッカソンにて ~

imas.connpass.com

12/7(土)にアイマスハッカソン2019 in 関東 があったので、その場で開発した。レポジトリは前回心拍数を取得してMacに送るために開発した banjun/DOKIDOKI-Rhythm

f:id:banjun:20191211004806j:plain
アイマスハッカソンの名札

developer.apple.com

前回の実装から2年近く経っていたので今年のWWDCでのHealthKitのセッションをざっくり見るところから始めた。どうやらデータ構造が無駄の少ないように変わったらしい。メリットしかない(フラグ)。実装の様子はもくもくとやっていただけなので割愛。

HealthKitの最近(2017-2019)の変更点

(心拍数や騒音レベルを上記目的で取得するだけの観点において)

  • 騒音レベルが追加されている: environmentalAudioExposure - HKQuantityTypeIdentifier | Apple Developer Documentation
  • プライバシーの使用目的に最低文字数制限が追加され、短い文字列を使っていた場合はリビルドするだけでクラッシュするようになる。長くすると通る(2倍にコピペするとか): The string "心拍数を表示します" is an invalid value for NSHealthShareUsageDescription
  • 一連の測定値のメタデータをまとめるためにQuantity Seriesという構造が導入されている
  • 全測定値は HKQuantitySeriesSampleQuery で取得するようになっている
  • HKAnchoredObjectQuery はかつては全測定値を返したがリビルドすると返さなくなっている (詳細未確認)

実現された実装

github.com

各ライブの開催時間に対して心拍数のログ(ピンク)と騒音レベルのログ(青)を表示できるようになった。

グラフの心拍数のピークから、どの曲で反応してるか分かる人には分かるが、騒音レベルからなにかを推定するのは難しい? 果たして有用性はあるのか・・・?

残されている課題

  • Catalina以降ではMac Blu-ray Playerのバージョンを上げる必要があり、そこではYesBDTimeによる再生時刻取得の手法が使えなくなっている。 help wanted
  • 騒音レベルのさらなる活用法を探る必要がある

所感

騒音レベルはヘルスケアの全てのデータで見るだけだとdBでの数値リストしか見えないので、全部取得したらおもしろいデータが取れると思っていたが、グラフにしてみるとそれほど分かりやすいデータではなかった。ライブ中は常に一定の範囲のうるささに収まっているようだ。音量が上がってないのに心拍数がやたら上がっているとか、音量の下がったところでBD再生位置合わせの補助になるかもしれないとか、そういう活用がありうるのか、試してみたい。

少ないサンプルの感覚値では、騒音レベルは自分の席の近傍の影響をよく反映するようで、ライブ開演前のCMコーナーでの謎の(?)盛り上がり&歓声で既にライブピーク値と同じくらいの騒音レベルを記録している可能性もある。

WWDCのHealthKitのセッションをみて、便利になったのだなと思っていたが、既存の実装だと得られるデータの粒度が大幅に粗くなっていた。あえて従来コードコピペによる別タブ逃がしをしてから新規コードを書いたので、それに気付けたので良かったが、まさかデータ構造が新しくなったということ自体がデグレのフラグだったとは?? となった。

7thライブツアー最終地は2月の大阪!どういう構成になるのか本当に楽しみ。

おわりに

みなさんもHealthKitに保管されているデータを使って今年あったイベントを振り返ってみてはいかがでしょうか? 明日は_sa_chi_03さんの記事が公開予定です。是非そちらもご覧ください!

🍓2018年振り返り

f:id:banjun:20181231233015j:plain 今年もいろいろなチャレンジができた。

勉強会・カンファレンス

登壇

2017年が2回の登壇だったので、今年は3回以上にしようとした。

🎤 AKIBA枠じゃないけどAKIBA要素を入れたAKIBA.swift

AKIBA.swift × エウレカ コードレイアウト勉強会 - connpass

カジュアルにはじめるVFL / Let's start VFL - Speaker Deck

🎤 30分枠で登壇を依頼してもらえたIM@S Engineer Talks。けっこう直前まで作りこんでいたのでUNION!!イベがあまり回せていない。内容は、去年のシンデレラ5thでたくさん取得したライブ中の心拍数を、今年発売されたライブBDの再生時に使う、複数年にまたがるお話。

【増枠】IM@S Engineer Talks - connpass

かわいいを支援するAppleハック,そして💓で振り返るシンデレラ5th / Apple hack assisting kawaii & Replay Cinderella Girls 5th LIVE with heartbeats - Speaker Deck

IM@S Engineer Talksで喋ってきた話のメイキングのおはなし #imas_hack - ツバメになったバリスタ

🎤 そしてiOSDCに初登壇して30分枠。録画トラブルでYouTubeに残っていないのが残念。 喋れるのか不安があったが、 登壇練習会 at Ebisu - connpass で練習会できたのがよかった。

5000行のUITableViewを差分更新する by ばんじゅん🍓 | プロポーザル | iOSDC Japan 2018 - fortee.jp

5000行のUITableViewを差分更新する / Difference update UITableView with 5000 rows - Speaker Deck

iOSDC 2018 に参加して登壇してきた - ツバメになったバリスタ

🎤 その他、プリッカソンでの成果発表など。

参加

🍎 今年はmacOSコミュニティが再び盛り上がる年だったのでは。 try! macOS meet-up - connpass に始まり、 macOS native シンポジウムが2回開催された。トーク内容は最新事例まで追っているものだが、macOS界隈はどうしても昔話が入り込みやすいというのもあり、もっと新しい人が入ってくるにはどうすればいいのだろうと思う。

➡️ try! SwiftもiOS界隈の普段の勉強会にも継続参加ができた。

🎀 アイマスハッカソンリスペクトで、プリッカソン(当時はプリパラハッカソン)が開催されていた。いいペースで開催されていたので気付いたときには2回目だったので2回目から参加し、3回参加した。

プリパラハッカソン #2 - connpass

初参加のときが「プリパラは明後日で最終回ですね」みたいなエモエモのタイミングであった。新シリーズは始まるが、現状のコンテンツに対してコントリビュートするのか、新しいコンテンツを自ら供給するのか、みたいに考えどころがあった。また、このハッカソンに存続してほしいので協力できることはないのか、とサポートしたくなってしまったので、気持ちだけちょっとだけお手伝いというかなんというかをした。

🌐 WWDCには残年ながら外れてしまったので、 【同時通訳あり】WWDC Extended Tokyo 2018 - connpass でライブビューイング参加した。100人が平日深夜に集まってキーノートをみるイベント、アツくてよかった。わたしはWWDC期間中はPacific Timeで働くため、例外的にリモート+深夜残業+休出扱いにしてもらい、全てのセッションをリアルタイム時間で追っていた。

主催

🏢 会社で勉強会を主催する話が出たので、主催やるのもいいかもなと思って乗っかり、勉強会を開催した。 茅場町モバイルアプリもくもく会 #1 - connpass

いくつものハッカソンや勉強会に参加したので、そこで見たことをベースに主催していけるのでは? という心境になったというのが、要因としては大きい。最初は参加ゼロ人だったらどうしようと不安に思い宣伝などしていたのだが、たくさんの人に来てもらい、本当に感謝している。

会社のサイトや転職サイトにメッセージ付き写真つきで掲載されるようになったので、社のエンジニアイメージアップ活動で表に出ていた。

ライブ

🎶 2017にあれだけ多かったシンデレラ5thのようなライブがない今年は少なくならないかと心配だったが、振り返ってみるとたくさん行っていた。よかった。

  • 初星宴舞 (1日目現地、2日目LV)
  • すぷりんぐふぇすてぃばる (try! Swiftハッカソン午前参加から直接移動してLV)
  • 劇場版 プリパラ&キラッとプリ☆チャン ~きらきらメモリアルライブ~ (ライブではないが、、舞台挨拶付き。全コースみたし応援上映もいった)
  • (ライブではないが、、劇場版アイマスを初めてみた。そのあと映画館で再上映もあったので、またみた)
  • アイマス MR ST@GE!! MUSIC♪GROOVE 千早回 @DMM VR THEATER
  • あにてれのプリ☆チャントークイベント&上映会 @DNP (小さいハコの最前列の最近傍、すごい)
  • ミリオン5th (1日目LV、2日目現地)
  • プロデューサーミーティング (LV)
  • SS3A (現地)
  • アイマス MR ST@GE!! MUSIC♪GROOVE やよい回 ζ*'ヮ')ζ @DMM VR THEATER
  • プリパラ&キラッとプリ☆チャンAUTUMN LIVE TOUR み~んなでアイドルやってみた! 昼の部 (現地)
  • CG STAR LIVE new generations Brilliant★Party! @VR ZONE SHINJUKU
  • シンデレラ6th メットライフドーム (現地)
  • シンデレラ6th ナゴヤドーム (現地)
  • み~んなでキラッとプリティーライブ2018 昼の部 (現地)

ようするにアイマスとプリパラ。

つくったもの・描いたもの

🖌 Apple Pencilでのイラストを描くのを継続している。 pixiv senseiのコースに(一時)課金して学んだ。Apple Pencilより前まではイラストを避けて生活していたので、知識がゼロなところに、pixiv senseiのように知識を与えてくれるコースはありがたい。

イラストの描き方を動画で学ぶ! - sensei by pixiv

描いたイラストは、登壇スライドを華やかにする素材として使うこともできて、楽しかった。

フラスタ

💐 去年 はフラスタに初めて出資したという実績だったが、今年はフラスタのイラストを描くというのをやった。これは今年初めてチャレンジしたことのなかで大きな成果になった。自分の描いたものを他の人に渡して後のことをやってもらうというのは初めて達成した。

www.pixiv.net

ありすはメットライフドームのみの出演なので、ナゴヤドームではフラスタにも出てこない。ありすのボードを回収できるというので、企画の方にナゴヤドームに持ってきてもらって渡してもらった。自分で描いたありすがボードになって、メットライフドームに行って、ナゴヤドームに行って、経路は違うけれど同じツアーを辿っていて、一周まわってまたうちに帰ってきたというの、めちゃエモい。

誕生日イラスト

🎂 今年の誕生日イラストは卯月とありすを描いた。作画できるスコープも作画にかかる時間もだいぶよくなった。

www.pixiv.net

www.pixiv.net

ライブイラスト

🎨 初星宴舞くらいから、ライブのあとにイラストを描くというのをやってみていた。高まって語彙を失なって記憶もなくなっていくなかでイラストを描くというのは、負荷が高くて中毒性がある。

名刺・シール

📛 去年後半に作りはじめた名刺は100枚印刷して無くなるころにマイナーチェンジしてまた100枚印刷、で300枚目を印刷してその半分くらいを配った。途中Pixiv Factoryも試したので+30枚くらい。1年とすこしでこれだけの枚数配れるとは予想していなかった。だいたいライブのPさんたちだが、エンジニア界隈にも配ってみていた。稀に返ってくるの驚きだし楽しみでもある。

自分のアイコンをシールにするというのもやってみた。界隈の性質上、アイコンで認知されているというのもあり、便利な場面もあった。twitterアイコンとありすアイコンがある。欲しいと言われるとめちゃ嬉しい。もっと配りたい。

Me-MAMORIOは丸いので、シールを貼って疑似グッズ化のにちょうどよかった。お気に入り。

iOS 12関連のいろいろ

🔨 iOS 12 betaが出てから、いくつかを試した。

他のOSS活動

AquaSKK

🔽 AquaSKKをみていくことにした。いままでひっそりとレビューをしていたが。。ひとまずはリリースをしたところ。応援ください!

Release Sticky Shift · codefirst/aquaskk · GitHub

というか真面目な話で、普通にメンテ協力者を求めている。

行ったところ

🌄 Apple 渋谷のオープンに並んだ。初めてAppleのオープンに並んだ。

転職活動

📱 10月くらいから転職ドラフトをきっかけに転職活動をしていた。序盤は現職に残る可能性を捨てていなくて、100万円くらい現年収を上げる交渉は成功した。ピーク時は平日の半分以上は面接をしていてほかのことがあまりできなかったが、スキルマッチしているところの中の話を聞くのは毎回とても興味深くたくさん話をした。次をどこにするかは決めているので、来年のご報告としたい。

iOS 12ショートカットからim@sparqlにアクセスしてクイズをつくってみた

このあいだiOS 12のショートカットを試して楽しかったので、今度は遊べるようにクイズを作ってみた。 完成系はこんな感じ↓。アイマスのアイドル(、他)がランダムに10名表示されるので、身長が149cm以下のアイドルをすべて選択すると、合っているかどうかを表示してくれる。

https://esa-storage-tokyo.s3-ap-northeast-1.amazonaws.com/uploads/production/attachments/9621/2018/09/27/1855/6b48385d-8576-4ace-b7a2-cf84881efeaa.mp4

このショートカットの中身は、下記のアクションで構成されている。このブログエントリでは、ショートカットの配布リンク提供と、ショートカットの中身のウォークスルー解説をする。

f:id:banjun:20180926200311j:plain

うまくオリジナルサイズの画像が貼れなくて読めないと思うので、オリジナルサイズはこっち。

https://img.esa.io/uploads/production/attachments/9621/2018/09/26/1855/aa46e4ad-7205-49a2-8607-c6f58a46ab3f.jpg

ショートカットの入手と実行

ショートカット本体は、iCloudでシェアできる。実際にこのiCloudリンクから入手して、実行したり、なかみを見たりできる。ぜひiPhoneに入れて動かしてみてほしい(App Storeでショートカットアプリを入れておく必要がある)。

im@sparql 身長U149クイズショートカット: https://www.icloud.com/shortcuts/93a3d2a6052048638943300edb80e8a9

なお依存先のショートカットがひとつあるので、下記のショートカットと合わせて2本、インストールする必要がある。

im@sparqlクエリ実行ショートカット: https://www.icloud.com/shortcuts/922ef6fc7366437e8b01659372fe48af

im@sparql 身長U149クイズショートカット のフロー解説

以下、ざっと流れの解説。長いスクショを見ながら追うといいかも?(いいのか?)

f:id:banjun:20180927001540j:plain

テキスト「SELECT...」→ ショートカットを実行「im@sparqlクエリ実行」で、アイドル名と身長のリストをとってくる。400以上の結果が返ってくる。データが充実しているのはim@sparql自体がすごい。「im@sparqlクエリ実行」ショートカットは、別のショートカットの入力に渡して結果を受け取る。さしあたり、SPARQLのSELECTクエリを渡すとim@sparqlから結果を辞書でとりだしてくれるすごいやつ、と認識しておけばよい。

SPARQL自体をどう書くか、については下記のページで解説されているので、そちらを参照。

im@sparqlを組み込んでみる

f:id:banjun:20180927001743j:plain

「リストから項目を取得」→「それぞれで繰り返す」で、ランダム順のあたま10名ぶんを取り出し、なまえと身長の辞書、のリスト、を得る。「辞書の値を取得」は、JSONのキーを辿るやつ。.name.valueになまえ、.height.valueに身長がはいっているので、そう辿る。「それぞれで繰り返す」は、リストのmapであるから、「繰り返しの終了」の直前をみると、map先の値がわかる。アクションの入出力のフローは一直線なので、「繰り返し項目」を二回入力として使うために、途中で「変数を取得」して入力を読みなおしている。

出力はこまめに変数にいれておくと、わかりやすい(変数にいれなくても、各アクションの出力は、マジック変数で参照できる)。

f:id:banjun:20180927001927p:plain

「リストから選択」ではクイズの出題と回答のUIを提供する。この入力は、ユーザーにみせる文字列のリストでないといけない。この制約がけっこう厳しい。辞書を渡せればいいのだが、表示名だけを渡さないといけない。。「複数を選択」にすることで、選択した項目のリストを得られるので、今回のクイズが実現できる。

f:id:banjun:20180927002007p:plain


f:id:banjun:20180927002020p:plain

そのあとほぼ終わりまで続く長い「それぞれで繰り返す」が、答え合わせのループとなる。「リストから選択」の制約で、選択された項目については、アイドルの表示名のリストについてのデータしか持ち合わせていない。したがって、再度、なまえ身長リストをループして、答え合わせをしていく必要がある。

f:id:banjun:20180927002105p:plain

または不正解

f:id:banjun:20180927002651p:plain

「次の場合」はif-else-endifの形式のブロック構造をしている。アイドルごとの判定は「そのアイドルは149cm以下かどうか」×「ユーザーはそのアイドルを選択したかどうか」なので、「次の場合」を2重にネストして、それぞれの4パターンの答え合わせ結果を生成する。「次の場合」も結果を上位のブロックに出力するので、4パターンとも、結果を「テキスト」にして、正解と不正解をもたせる。すると、2重ネストの外側の出力として、「結果が以下の場合」の変数に、正解か不正解かが流れてくる。

f:id:banjun:20180927002121p:plain

f:id:banjun:20180927003229p:plain

f:id:banjun:20180927003729p:plain

[結果が以下の場合] に答え合わせ結果のテキストを絵文字で入れているので、こんな感じの出力になる。×が出たら覚えていこう。

f:id:banjun:20180927002148p:plain

これがアイドル10名ぶんmapで繰り返されてくるので、joinする。joinは「テキストを結合」で、改行区切りを選択する。 最後に「クイックルック」で結果をユーザーに表示してやる。「クイックルック」は、ショートカットを組み立てるときに、途中に挟んで、実行を止めて出力の内容を見られるので、プリントデバッグ的な感じでべんりに使える。

im@sparqlクエリ実行ショートカット のフロー解説

こちらのほうが短いけれど、オリジナルサイズの全容はこちら。

https://img.esa.io/uploads/production/attachments/9621/2018/09/27/1855/932481f7-a32c-4d65-8993-f466f8962652.jpg

SPARQL初心者なので、SPARQLのSELECT書いたらim@sparqlで実行してくれるだけのモジュールとしてのショートカットを作って、試行錯誤しようとして、↑↑のクイズのショートカットから分離したもの。

SPARQLのクエリはPREFIXとSELECTからなるようで、PREFIXはお決まりのものを入れておけば良いかなと思って、SELECTだけ書いたら動くようになっている。

「ショートカットの入力」で他のショートカットから入力をもらう。「次の場合」では、空実行されたときに後段まで実行されて無駄クエリを投げることがないように、キャンセルできるようにしている。ただのキャンセルというのが分からなかったので、[キャンセル][OK]でキャンセルできる、というだけ。

URLエンコードして、im@sparqlのエンドポイントのqueryにくっつける。im@sparqlの結果はJSONで返ってくるようで、辞書にして、お決まりの階層がいくつかあるようなので、results→bindingsと辿って、結果の辞書部分だけをこのショートカットの出力とする。

これで、SELECTを書くだけのショートカットを作りやすくなる。例えば、下記のページで提供されているようなクエリ実行は、こうなる。

https://sparql.crssnky.xyz/imas/ImasIllustTheme.html

f:id:banjun:20180927001333j:plain

このサンプルのショートカットへのリンク: https://www.icloud.com/shortcuts/41d10a57b1e84a03b38914fc95be0d86

おわりに

こうやって、ショートカットでなにかをするときにはこのアクションを使えばいいのかな?、ってアクションの語彙が増えていくと、iPhoneだけでどんどんロジックを組めるようになってくる。iPhoneなので電車のなかでも組める。実際に今回のショートカットのほとんどは、毎日の電車のなかで作成した。 たぶんショートカットはもっといろんな連携のパターンがあると思うから、ショートカットで出来ることの語彙を増やしていきたい。

こんなアクションつかったらきれいにできる、とか、ここは分離して別のショートカットにしたらいい、とか、そういうネタがあったら教えてほしい。

謝辞

github.com

このデータ量よ

nrstudy.connpass.com

このブログ書きました

esa.io

べんり

プリッカソン#5でノンプログラミングやってみた

prickathon.connpass.com

ちょっと間があいて久々のプリッカソンに行ってきた。参加するとアナウンスで、一度休んだから行きづらいということはなく、予定が合ったら行こうかなくらいでいいですよ〜くらいのノリで、と言われていて、カジュアルに参加できて良いのだが、なんだかんだ最近は連続で参加できている。暇というわけではなく9月の忙しさのなかによくうまくはまったなというか.. .

f:id:banjun:20180924003131j:plain

今回やったのは、プリパラDB(仮) + iOS 12ショートカット。このブログエントリでは内部的な解説成分多めで。ショートカットの情報がまだどれくらいあるか分かっていないので。

プリパラDB(仮)側

、、って、今回のプリッカソン参加者はrubyでgemにしていたの?? という話もあった。ruby直であれば最速っぽいが、今回は↑のほうの話。

github.com

ようするにプリパラに関するデータを蓄積していくのだが、すべてをいちどにやるのは無理なので、現時点での関心領域は、キャラとか、アニメの話数とか、曲名とか、アニメに出てきた曲、誰が、とか、そのあたり。しかもプリパラのみ(アイドルタイムプリパラも、まだ)。ではあるが、他のシリーズとか、アニメ以外の情報へ拡張していくのは原理的にはできるはず、、というか、できる構造を狙ってつくっていく、というものだった。

いちどはfirebaseに置いてみたり(つまりほぼjsonで書いて、さらにCloud Functionで整形する方式)、どこかのRDBに置く話の検討もあったが、インフラ側の準備作業がちょっとあるのに加えて、おもに編集作業がつらいのであった。生データを直で触れない場合は編集UIが要るし、データに制約がある場合は制約を設計して、編集者が理解して、あるいは制約をきれいに編集できるUIが必要になり、という感じで、編集にとりかかるハードルが高い。そういうUIがあるのは良いことだが、必須でないほうがありがたい。Googleスプシで書けるくらいで始められたらよい。

webapi-mock-up/pripara-episodes.csv at master · prickathon/webapi-mock-up · GitHub

なかひこくんさんが、githubcsvを置くと整形表示とフィルターがある、と言ってCSV書いてみていた。なかなかよいし、github上にマスターデータがあるということはdiffも歴史もあってよい。firebaseもRDBも、diffと歴史の保存(てきとうにいじってデータ壊してたときのためにバックアップとるとか)は課題として上がっていたし。

なんか、エディタによってはCSVの色わけをうまくやるというのもあるみたい。Vimでもいけるかな?

https://prickathon.github.io/webapi-mock-up/episodes.json

github pagesのJekyllでCSVJSONに変換できるんですよ、というのも見せてもらって、なるほどインフラ不要でよい、と思った。

webapi-mock-up/episodes.json at master · prickathon/webapi-mock-up · GitHub

その実装をみて、なるほどJSON変換、とは・・・?となったが、別インフラも別な生成スクリプトの実行もなくて済むし低コストだし、ありよりのあり。 (そういえば頭の角ブラケット...)

webapi-mock-up/pripara-lives.csv at master · prickathon/webapi-mock-up · GitHub

webapi-mock-up/lives.json at master · prickathon/webapi-mock-up · GitHub

というわけで、アニメの各話に出てきた曲が、どの曲で、誰が歌ったか、を引けるようにするために、CSVを書き足して、JSON APIをつくってみたのがこれ。書いてるのCSVとテンプレートだし、プログラミングとしてはノーカンでいいよね。

iOS 12ショートカット側

iOS 12でショートカット (Workflow) のアプリがいい感じになっていて、リリースとともにさっそく使ってみた話をタイムラインでよく見かけるようになった。そんなに意味のあることはできないのかなと先入観を持っていたが、わりと高度なことまで出来るようだったので、興味が出てきたので、プリッカソンで調べてやってみようと思った。

知識ほぼゼロでアプリ起動してショートカットで使えるアクションを検索すると、JSONを辞書として扱えるようにするのがあった。その入力までは、URL → URLの内容を取得 → 入力から辞書を取得。ドラッグドロップで並べて、アクションの設定値をいれていく。

f:id:banjun:20180924115904j:plain

残念ながらCSVを読めるアクションはなさそうだった。Swiftクライアント書くならCSV直でもJSON APIでもクライアントサイドジョインがあってもまぁなんでもいいかなという気持ちもあったが、ショートカットで実現することを考えると、とりあえずJSONになっているだけでもありがたい。さっきのJekyllが役立っている。

f:id:banjun:20180924120234p:plain

キャラクターのJSONをとってきて、そのキーのリストをユーザー選択のアクションシートに出して、そのキャラの情報を引いてくることができる。ここでの未解決課題は、キーではなく名前を出したいのだが、リストから選択アクションでは、選択する値そのものしか表示できないらしい。キーをそのままユーザーにみせるしかない。

f:id:banjun:20180924120512j:plain

触ってみてわかってきたのは、いちいち結果を変数に名付けておくと分かりやすいし、フローを切って次のフローを始められるのでよい。日本語もつかえるので、選択したキャラの「なまえ」と「チャーム」を保持しておいて、「[なまえ]は[チャーム]ね」というフォーマットで結果表示できる。わかりやすい。いかにもプログラミング入門めいてきた。「らぁらちゃんがショートカットで◯◯を作る本」だれか書かないかな?

次に、曲名を選択すると、それが歌われたアニメの話数を表示するショートカットをつくってみる。入力はsongs.jsonをみる。

f:id:banjun:20180924121023j:plain

jsonのキー一覧を、「それぞれで繰り返す」で、jsonから値取得してnameをとる、ことは、曲名のリストを得ることになる。つまり「それぞれで繰り返す」はmapのことである。これでキーのリストではなく曲名のリストでユーザーに選択させられるのだが、さっきの未解決課題のとおり、選択されたキーがなにか、というのは失なってしまう。しかたがないので、曲名に重複がないことを利用して、もう一度繰り返しで、選択された曲名と一致するところだけを処理する。 概念的には for 曲辞書の値 { if 選択された曲名 == 曲名 { ... } } みたいな。

f:id:banjun:20180924121613p:plain

ifに相当するのが「次の場合」のようだ。「次の場合に終了」までのブロックが生成されるが、これは日本語だから分かりづらいのかなぁ。英語みてないけど、endif的なものだと思われる。ネストが深くなると余計にややこしくなるので、ifが成立したときに変数にいれておくだけにして、フローを切るとよさそう。

これで選択した曲情報は得られる。このうえで、songs.jsonJSON API側(Jekyllによる)でjoinされているlivesをもってくる。なぜlives.json側から引いてきていないかというと、、、これも未解決課題で、filterやuniqueの操作をショートカットでやる方法が見つけられていないから。だからAPI側で、やりたいことに合わせてjoinをしておかないと難易度が変わってしまう。Swiftクライアントならどっちでもよさそうなものだが(クライアントに書くかAPIサイドに書くかの違いのみで、ある特定のクライアント都合のユースケースAPIサイドに書いていいものか問題はある)、ショートカットでは、クライアントでつらい仕事はAPIサイドに書くのが正解かもしれない。

f:id:banjun:20180924122127j:plain

結果表示はリストを埋め込んでも改行で表示される。機械的に改行されている感じが、プリパラ世界の「システム」である、めがねぇっぽくてこれはこれで良い。空を判定して分岐はできるようだったので、見つからないときに別のメッセージを出すのもできた。

f:id:banjun:20180924122411j:plain

f:id:banjun:20180924122414j:plain

リストから文字列へは好きな区切り文字で結合できて、こうするとより人間的になる。

f:id:banjun:20180924122623j:plain

ショートカットは当然にSiriのフレーズを設定できるので、「この曲いつのだっけ」で起動できるようにした。いま再生中の曲名も取れそうなので、曲名一致をどうにかクリアすれば、再生中の曲からもいけそうである。

あとはデータの充実で、ここのcsvを充実させてくれる協力者がいれば、、、という感じ。プリ☆チャンは毎週データ増えていくし、プリ☆チャン用も同様にして誰かつくりませんか? どうですか?

webapi-mock-up/pripara-lives.csv at master · prickathon/webapi-mock-up · GitHub

成果物

このショートカットは、iOS 12で↓のリンクからインストールできる。もちろん中身の実装がみられるし、編集もできる。

https://www.icloud.com/shortcuts/384204a915a1429db3e7d2a1c21ba0f7

ノンプログラミングで、できました。

所感

ショートカットをやっているとMacBook Proは必要なかった。iPhone上でドラッグドロップを精度よくやっていくだけ。もちろんどこでもできるので、↑のテキスト結合あたりは、帰りの電車で見つけて実装した。べんり。ショートカットのシェアーができるのも良い。どこかにアップロードする場所を用意する必要もない。ハッカソンだと、iOSアプリって作ってもすぐシェアーできないので(TestFlightだとしても審査に1日かかってしまう)、そういう意味ではアドバンテージが高い。ただ、シェアーしたショートカットをどう残していくかと、どうバージョンアップしていくかは、課題。ツイートでいいんだろうけど、流れていくし、かといって、つくったショートカットの一覧ページみたいなのつくるのも、ちょっと作業がいるかなぁ。

プリッカソン会場はここ数回はサポーターズの広い会場で、いつも快適で良い。参加人数もじわじわ増えている。わたしはプリズムストーンのコスプレ参加(?)だったけど、サポーターズのコスプレ参加(?)のひともいた。

f:id:banjun:20180924124417j:plain

成果発表のあと買い出しして懇親会。参加者みんな(論理)女児だしアルコール買わないので安いというのもあるが、前回よりさらに安く済み、一人300円となった。遠足のおやつレベルでは。

次回はまた予定があえば参加、今度はもっとプログラミングしようかな。connpassページから辿るとSlackもあるので気になっているおともだちもぜひ。よろしくお願いします。

iOSDC 2018 に参加して登壇してきた

f:id:banjun:20180907230358j:plain

パンフ,うれしい。

プロポーザルと登壇

iOSDCには2016,2017と参加してきて3年目,初めてプロポーザルを出した。30分枠とLT枠と出して,30分の差分更新のトータルパフォーマンスのほうが採択された。VFLの話もしたかったな...?

5000行のUITableViewを差分更新する by ばんじゅん🍓 | プロポーザル | iOSDC Japan 2018 - fortee.jp

https://fortee.jp/iosdc-japan-2018/proposal/3ae8b788-8df5-4f1e-8862-7c5170a14d36

今回プロポーザルを出したのは,そろそろ勉強会慣れもしたし喋れそうかな?と思ったのもあるが,まわりで,プロポーザルを出す,いくつ出す,15分と30分と両方出したほうがいいらしい,みたいなプロポーザル提出時点での盛り上がりがかなりあり,雰囲気に釣られて出した部分も大きい。つまりノリである。 年間の大きめのカンファレンスというとtry! SwiftとiOSDCとあるが,どちらかというとiOSDCのほうが好きなことを喋っているという要素が大きい印象がある。言葉にしづらいが。

f:id:banjun:20180907234857j:plain

photo by mzp

f:id:banjun:20180911224529j:plain

photo by iOSDC Japan: iOSDC Japan 2018の写真を公開しました - iOSDC Japan スタッフブログ

登壇自体は緊張したのもあったが,30分喋り続ける体力のほうがつらかったかもしれない。iOS界隈でこれ以上大きいハコで喋ることはなかなか無さそうだし,いまできる範囲でいちばん経験値積めそうなことが出来ました(レベルアップ)という実績解除っぽくてとてもよい。

f:id:banjun:20180908001425j:plain

登壇中と前後はワークアウトにして心拍数をとっていた。ライブとおなじ。それなりに高い。なぜか10分くらい喋ったところが高い。

資料とまとめ

トークの内容的には,UITableViewの差分更新がなにか知らないところから入ってもメリットが分かるようになっていて,ほとんどの場合はライブラリを入れるだけで利用できるけれども,大きな行数の場合には遅くなってしまうかもしれない,そういうときにパフォーマンス解析するにはどうしたらいいだろう?という流れになっている。パフォーマンス向上ネタをいくつも持っていても,ボトルネックがそこにあるかどうかというのは勘で当たったり当たらなかったりする。Instrumentsで見れば事実が分かる。知らないボトルネックが登場したら,それはSwiftの内部や,UIKitの特徴を新しく知ることになり,それはそれで知見になる。そういう手段も持ち合わせておくと気が楽になるし,差分更新をどんどん使っていけたら良い。

speakerdeck.com

togetter.com

YouTube配信もそのうちあるはず?

実況の様子を後からみるの楽しい。まとめてくれたかっくんありがとう。 登壇で言いたいことってなかなか言葉で伝えづらいものだなと感じたが,ツイートをみるときれいにまとめられていて,そう言えばいいのかみんな賢いすごいと思いながら読んだ。

記述ミスへの指摘を実況+Q&Aでしてくれた方もいて,もやっとしたままにせず共有されたのは良かった。(speakerdeckはその後修正して更新した,はずだが,反映されてないかも...)

Ask the Speakers

そうか登壇するとAsk the Speakersもやることになるのか~と感動していた。来てくれた方は本当にありがとうございます。うれしかった。 人がこないときは並行しているセッションのスピーカーと喋ったりというのも良い機会だった。

登壇練習

いままでの他の登壇では発表練習らしい練習をしたことがなかったが,今回は2回発表練習をした。社内勉強会での発表練習と,Timersでの登壇練習会。

mokumoku-ebisu.connpass.com

つきあってくれたみなさんには感謝している。特に,Timersで,他のスピーカーの練習をレビューする側で4時間くらい(??)やっていて,これは聴いてフィードバックするというのは大変なことだなと実感した。 フィードバックはそれ自体が良い影響があるが,発表練習がなによりも良いのは,その期日までに進捗が出る,ということで,これは助かった。さすがに作らずに練習はできない。技術的内容とか構成以外だと,どこが意外とウケないとか,ここ意外とウケるんだ,とか,そういうのが役に立った。録音しておいたので後でどのスライドが何分くらいか分かるし,自分の発表を聴くことで,喋りの反省と喋る内容を記憶するのに,役に立った。

もくもく会で資料準備

茅場町モバイルアプリもくもく会 #2 - connpass

7月から, @shiozaki_study さんと,もくもく会の主催をするようになったので,そこでも登壇資料を作っていた。Instrumentsのスクショを集める作業が意外と難しくて何度かやりなおす必要があったので。もくもく会だから,コードを書かなければならないということはない。が,コードを書いて進捗だしている人たちが楽しそうだったので,やはり今度はコード書けるように準備をしておこうと思いながらスクショ作業をした。また9月も開催するのでぜひ来てね(いつも参加枠が一杯になってから宣伝してしまうやつ...)。

茅場町モバイルアプリもくもく会 #3 - connpass

iOSDC当日のいろいろ

トークセッションが並行でいくつもあるので,選ばなければいけない。Interactive Round Table (IRT)もあり,アンカンファレンスもあり,スポンサーブースまわりで喋るのもよし,Ask the Speakerも行きたいのあるし,どこに行くべきか。聴かなかったトークも良いものであるという情報が流れてきて,やはり・・・あとでチェックしなくては,となる。まるでWWDCのときのように,どんどんとチェックすべきタスクが積まれていく,というような話を聴いた。なるほどその通りである。

アンカンファレンスの自由さもよい。(わいわいswiftcに行った)。休憩時間ごとに,「フリーのIRTもひとつ用意してあります」ってアナウンスされてると,これは何かテーマを出したらいいんじゃないかって思いをめぐらすことになるのもよい。macOSの話をするまでには至らなかったのだけれど。予定されていたIRTのなかでは,autolayout/storyboardに行った。Visual Format Languageこそ至高。時間がいくらあっても足りないのでは感があった。VFLの項目だけネタとして出して,登壇の時間なので登壇してきたら,VFLネタそのあとのIRTで拾ってくれていたらしい。

f:id:banjun:20180907234643j:plain

それとは別に,コードレイアウトアンケートがあったのでVFLの領域を書き足しておいたのだが,増えていたらしい・・・一体誰なんだ・・・。

f:id:banjun:20180907235017j:plain

ある日の朝はドーナツが置いてあった。すくなくとも私が辿り着いたときにはフレンチクルーラーはなかった。

f:id:banjun:20180907235200j:plain

ある日の朝は野菜になっていた。

macOS nativeシンポジウム

なぜか,たまたま,iOSDCに隣接して,macOSネイティブ勢のシンポジウムがあった。たまたまなのでiOSDCの話に混ぜるのは不自然かもしれないが,なぜかたまたまなので混ざることもある。iOSDCのオープニンの懇親会とかぶっていたが,レアリティという意味ではmacOSネイティブのほうが高いので,これに参加していた。

macos-native.connpass.com

macOSネイティブ勢はすぐ昔話になりがちという印象があるが,シンポジウムのトークはむしろ,歴史を観察・分類し,現時点ではこうなっている,という話の傾向だった。いま作っているmacOSアプリをどうするか,これから作るものはどうするか,という視点で勉強になった。

とはいえ懇親会で老人会のようなネタ振りをして盛り上がってしまったのも事実で,Instrumentsの前って何をつかってましたっけ?みたいな話が出来る場があって本当に楽しいなと思った。

なぜ60人キャパに対し30人しか集まらないのか・・・。みんなmacOSアプリ使ってるはずだし開発環境も既に整っているはずだし,もっとネイティブアプリ自作しようよ。

おわりだよ~

f:id:banjun:20180907234747j:plain

f:id:banjun:20180911230111j:plain

次は俺コン&リジェクトコンで。聴きたかったトークあるから楽しみ。iOSDCで話せなかった人とも話したい。話しかけてくれるとうれしい。。