ベータコンピューティングの活動や技術、開発のこだわりなどを紹介するブログです。



競技かるたONLINEの裏話(その2)

こんにちは、Beta Computing株式会社の村松です。
前記事に引き続き「競技かるた ONLINE」の裏話をお話いたします。

開発秘話

漫画「ちはやふる」をきっかけに競技かるたに興味を持った私たちですが、競技かるたのルールは漫画を通して把握しているつもりでした。また、アプリ開発にあたり競技かるたのルールをインターネットで検索していました。
そして、自分たちなりに試行錯誤し、「競技かるた ONLINE」の原型となるアプリを開発しました。

その後、たまたま会社の近くにかるた教室があることを知ったので、開発したアプリを持ってお邪魔させていただきました。 皆様に感動してもらえるのではないかと期待して、アプリをお見せしましたが、以下のようなご指摘を受けました。

  • 札のフォントが公式札と違う
  • から札の扱い方が違う
  • 札押しの考え方が違う
  • 決まり字の考え方が違う
  • CPUの取るタイミングがおかしい
  • CPUの定位置がおかしい
  • CPUの送り札がおかしい
  • 暗記時間やから札が出た際の時間の使い方が気におかしい
  • 画面サイズ上25枚:25枚は並べられないのは仕方ないとして、友札を多くしてほしい

などなど

特にかるた教室に子どもたちの反応を見ると、ゲームアプリということで楽しそうに遊んではくれたものの、競技かるたという内容に対しては「ぜんぜんちがーう!」「えー!意味わからない!」という声が聞こえてきました。

更に、かるた教室の先生からは「あなた達は実際にかるたをやったことがないのではないか。まずは百首を覚えて、練習に参加し、大会に出なさい。」とごもっともなご意見を頂きました。 そこから、私達は1年以上かるた教室に通い、百首は当然暗記し、大会に出て少し勝ち進めるまでになりました。

漫画やインターネットで競技かるたのルールを理解していたつもりでしたが、実際に真剣にかるたに取り組んでみて、やっと当初の指摘の意味が分かってきました。

  • 札は大石天狗堂様の札でないと取りづらい
  • から札はルールとして必須、決まり字変化にも影響があり、暗記し直す時間にもなる
  • 取り判定の厳密なタイミング
  • CPUは決まり字が読まれてから取るべきだが、決まり字変化や残り枚数によってもスピードが変化するべき
  • 定位置や送り札にも戦略がある
  • アプリでは基本8枚:8枚の試合だが、決まり字変化を楽しむために、使われる札はランダムではなく、計算が必要

などなど

これらの経験や知識を反映させたものが、現在の「競技かるた ONLINE」でございます。 囲い手やフライング判定など、アプリ上ではどうしても再現させることができなかったルールもございますが、できる限り競技かるたのルールを再現するよう努力しております。

このように、インターネットでルールを理解したつもりで開発しましたが、実際のかるた競技者から見ると本質を理解できていないアプリだったということがわかりました。
全日本かるた協会様、各地域のかるた教室様、各大会で出会った選手様、大石天狗堂様、読手様等、皆様のご協力の上で開発することができたアプリです。改めてお礼申し上げます。本当にありがとうございます。

なお、このエピソードは「競技かるた ONLINE」だけではなく、ソフトウェア開発やスマートフォンアプリ開発全般に通ずるものがあると考えています。
以降弊社では、スマートフォンアプリを開発する際は、アプリを利用される業種の勉強や、現場の調査を十分に行い、設計・開発するよう心がけています。どのアプリも関係者の皆様のお力を借りながら、開発しております。

開発費

前記事でもお話しましたが、弊社のメイン事業はソフトウェア開発の受託業務でございます。 受託業務の合間に自社製品開発として「競技かるた ONLINE」の開発を進めておりました。

「競技かるた ONLINE」は開発着手から初回リリースまで約1年半かかっております。 その間にかるた教室に通ったり、受託業務の合間にアプリを何度も修正したりということもございますが、単純な期間だけでいうと約1年半になります。

「競技かるた ONLINE」の初回リリースまでにかかった費用は主に以下の通りです。

  • 人件費
  • 読手様の音声収録費
  • イラストデータの素材費
  • BGM・SEデータの素材費
  • サーバ費
  • 調査や関係者とお会いするための旅費交通費
  • 広告宣伝費

などなど

本来であれば多額の費用がかかりますが、各種補助金(小規模事業者持続化補助金、新製品開発補助金)を利用することで、約300万円の実費負担で開発することができました。
その他、サービス継続のために運営費としてサーバ費や保守対応費用がかかっております。

「競技かるた ONLINE」は会社の広告宣伝として、無料でかつ広告表示もできる限り少なくリリースしております。 ぜひとも弊社スマートフォンアプリ開発のBeta Computing株式会社を認識いただけると大変嬉しく思います。

終わりに

「競技かるた ONLINE」の開発や運営の裏話を中心にお話しましたが、私達も競技かるたを習って大会に出場することで、より一層競技かるたの奥深さと楽しさを知ることができました。同時に調査を進めることで、競技かるた界が抱える課題なども多く知ることができました。
弊社では「ちはやふる基金」「全日本かるた協会」「各大会への協賛」「地元かるた教室への貢献」等、少額ではありますが支援しております。 「競技かるた ONLINE」も競技かるた界の発展に少しでも役立つことを願って、開発と保守を続けてまいります。

もし弊社にご協力できそうなことがあればお気軽にお問い合わせください。 どうぞよろしくお願いいたします。

競技かるた ONLINEについてのお詫びと裏話(その1)

こんにちは、Beta Computing株式会社の村松です。 今日は「競技かるた ONLINE」についてお詫びと裏話をお話いたします。

Android版の「競技かるた ONLINE」がインストールできない件について

まず、現在(2024年6月7日時点) Android版「競技かるた ONLINE」がGoogle Play ストアからインストールできない状況となっております。大変申し訳ございません。 本件、ユーザー様からのお問い合わせも多数頂いており、期待してくれている方も多くいる中で、ご迷惑おかけしている状況です。

こちら、原因は判明しておりまして、現在対応中でございます。 2024年9月頃にアップデート完了する予定ですので、もうしばらくお待ちいただけますようお願いいたします。 同時に、機能追加や読手音声の追加も予定しておりますので、ご期待ください。

なお、「競技かるた ONLINE」の更新状況については、公式X(旧Twitter)の方でもお知らせしてまいります。 よろしければフォローいただければと思います。 https://x.com/karutaapp

Beta Computing株式会社について

本記事をご覧の方の中には、弊社についてご存じない方も多いと思いますので、まずは会社紹介をさせていただきます。

弊社は2015年に創業しました石川県の津幡町(金沢市の隣)にあるスマートフォンアプリ開発に特化したソフトウェア開発会社です。 「競技かるた ONLINE」や「かるた読唱 〜百人一首読み上げ〜」を自社製品としてリリースしておりますが、かるた専門の会社ではなく、ゲーム専門の会社でもございません。
(かるたもゲームも大好きです。今後もかるたアプリやゲームアプリも開発してまいります。)

弊社のメイン事業は、ソフトウェア開発の受託業務でございます。 もし興味を持っていただけましたら、弊社HPの会社概要開発実績をご覧いただければと思います。

「競技かるた ONLINE」の開発経緯について

「競技かるた ONLINE」は2019年4月25日にリリースしました。

karuta.betacomputing.co.jp

「競技かるた ONLINE」を開発したきっかけ

「競技かるた ONLINE」を開発したきっかけは大きく分けて2つございます。

1.Beta Computingの自社製品がなかった
弊社のメイン事業はソフトウェア開発の受託業務ですが、創業当時は営業活動に苦戦しておりました。

というのも、創業当時は会社としての開発実績がなかったために、お客様に弊社のアプリのイメージや弊社の技術力を伝えることが難しいという課題がございました。

また、ソフトウェア業界には「秘密保持契約」というものがございまして、弊社で開発したアプリでもお客様企業の名前で世の中にリリースされることが多く、弊社の名前は外に出ない上、弊社の開発実績として掲載・紹介できないものがいくつも存在します。
(現在は弊社HPに「開発実績」のページがございますが、それぞれお客様の許可を頂けたものを掲載させていただいております。お客様には感謝申し上げます。)

そこで、自社製品を開発することで、営業時に弊社の技術力を伝えやすくしようと考えました。 悩んだ結果、オンライン対戦のゲームアプリであれば、技術的な難易度が高いため、営業にも役立つという結論になりました。 また、ゲームアプリであれば一般ユーザーに楽しんでもらえる上、広告塔として弊社の知名度向上にも繋がるのではないかと考えました。

2.漫画「ちはやふる」がおもしろく、影響を受けた
ゲームアプリを開発しようと考えましたが、具体的にどのようなアプリにするかは決めておりませんでした。

ちょうどその頃、弊社メンバーが「ちはやふる」にハマっていたこともあり、社内でかるた大会をしようとしました。しかし、実際に札や読み上げ音声を用意するのは面倒なので、簡単にアプリで遊べるものがないか調べたところ、競技かるたのルールに沿ったゲームアプリがないことに気が付きました。

そこで、競技かるたのアプリを開発しようということになりました。「ちはやふる」のおかげもあり、楽しんで開発に取り組むことができました。

企画時の余談

余談ですが、「競技かるた ONLINE」企画当初は、ゲーム性を持たせ、相手の札を並び替えてしまうような自分に有利なアイテムや、相手を1回休みにするような相手が不利になるアイテムなどを設ける案もありました。競技かるたのルールを忠実に再現すると、百人一首をすべて覚えている前提になるので、ターゲットとなるユーザー数が少なすぎると考えたからです。そのため百人一首を知らないユーザーでも遊べる仕組みにしようという案がありました。 しかし、競技かるたのルールに沿ったゲームアプリがないというきっかけから開発を決めたアプリだったので、実際に競技かるたをやっているユーザーや、これから競技かるたを本格的に始めるユーザーが楽しめるアプリを開発することにしました。

開発面でのメリット

また、競技かるたを題材にしたゲームアプリは開発面でも多くメリットがありました。その中でも3つほど紹介します。

1.必要なイラスト素材が少ない
ゲームアプリを開発するとなると、例えばアクションゲームやRPGゲームであれば、ステージの数だけステージ検討やイラストデータの素材、キャラクターの素材などが必要になり、莫大な費用がかかってしまいます。開発当時、弊社は3人体制の小さな会社だったので、開発費と時間を極力抑える必要がありました。 かるたであれば、最低限100枚の札と畳の画像データ、読手音声のデータさえあれば開発できます。

2.札を飛ばす物理演算
競技かるたでは、漫画や映画で札を弾き飛ばしている様子が描かれますが、札押しというルールがあります。ただ札をタッチするだけではなく、ルールに沿って札を弾き飛ばしたいと考えました。また、ユーザーにとっても札を弾き飛ばせることが楽しいと考えたからです。 この札押しを再現するためには、物理演算という札の動きを計算して表現する必要があります。札押しの再現が技術力のアピールに繋がると考え開発しました。

その他にも、和の雰囲気を伝える見た目、説明書がなくても使いやすいUI/UXなどにこだわって開発しました。特に伝統的な日本語の文字遊びを意識しており、テキスト表示はメニュー画面を含め、縦書きになるようこだわっています。実は文字の縦書きをスマートフォンアプリ上で綺麗に見せることは大変難しく、他のアプリではあまり見られない高度な技術力アピールになっています。

3.リアルタイムオンライン対戦
スマートフォンアプリでは通信処理が絡むことが多いです。技術力宣伝のためにもネットワーク周りの処理を実装したかったのですが、かるたゲームであればリアルタイムにオンライン通信する必要があります。 リアルタイムオンライン対戦を実現することで、業務アプリの通信処理でも開発できる技術力があるというアピールに繋がります。

よくある質問

こちらも余談ですが、オンライン対戦についてはユーザー様からのお問い合わせも多いので、よくあるご質問2点にお答えします。

よくある質問1:オンライン対戦で自分の方が早く取ったにも関わらず、相手の取りになった
判定の取得秒数につきまして、決まり字が読まれてから取るまでの時間を端末内で0.001秒単位で計測し、何秒で取ったかを解析しております。オンライン対戦では各自計測した秒数を相手と突き合わせて、早い方の取りになります。ですので、取りの判定に誤りはございません。 しかし、自分もしくは相手の端末スペックが低い場合やネットワーク環境が悪い場合は、試合中に表示される取りのエフェクトが遅れて表示されることがございます。 特にネットワーク環境が悪い場合は、取ったことを対戦相手に伝えるまでの通信に時間がかかってしまうのでアプリ側ではどうしても改善できません。 そのため、エフェクトは遅れて表示されるが、実際は相手がもっと早く取っていたという状況が発生し、自分の方が早く取ったにも関わらず、相手の取りになったという見え方になってしまいます。 恐れ入りますが、取りの判定結果が正しいもので、エフェクトは参考程度に見えるものとご了承いただきますようお願いいたします。

よくある質問2:札押しをしたのに取り判定にならない
札の払いに関しましては、競技かるたの公式ルールに従いまして、札が競技線の外に完全に出た瞬間に取りの判定になります。札の一部でも競技線の内側に残っていると取り判定にはなりません。 ですので、札が競技線の外に完全出る前に、対戦相手に札直で触れられると相手の取りになります。

どちらもコンマ何秒の世界になりますので、技術的に実現が難しく、表現も難しいため、分かりづらい部分もあるかと思いますが、ご了承いただけると幸いです。

開発秘話 や 開発費と運営費 について

記事が長くなりましたので、次の記事に分けて書きたいと思います。

続きます。

大学や高専で会社紹介をさせていただきました

こんにちは、Beta Computing株式会社の村松です。

ブログの更新頻度が減っておりました。 閲覧してくれている方がいると信じて、今後更新回数を増やしていこうと思います。 よろしくお願いいたします。

講義活動について

2017年頃から教育機関での講義活動を依頼される機会が増え、大学、専門学校、高校で講師として登壇させていただくことが度々ございました。 ありがたいことに、以降毎年講師を務める機会をいただいております。

今年も、金沢大学、金沢工業大学、石川工業高等専門学校で講義を行いましたので、その内容をご紹介いたします。

金沢大学大学院「イノベーション方法論」

金沢大学大学院の「イノベーション方法論」では、私の起業の経緯と自己分析の重要性についてお話ししました。 対面授業でございましたが、講義室に入り切らない人数だったため同時にオンラインでの配信も行う形式でした。 真剣にお話を聞いていただき、鋭い質問も多く頂きました。

金沢大学融合学域スマート創成科学類「アントレプレナー演習Ⅰ」

金沢大学融合学域スマート創成科学類の「アントレプレナー演習Ⅰ」では、ISAと金沢大学の連携活動の一環として、弊社の紹介をさせていただきました。 スマート創成科学類は、文系理系の概念に囚われず、仮想と現実の融合を実装し,イノベーションの創成をリードする人材の養成を目的としております。 学生の皆様にはぜひ、弊社はもちろんのこと、石川県内の企業に興味を持っていただければと思います。 時間いっぱいまで多くの質問を頂き、講義後も先生方や学生の皆さまとお話する機会をいただきました。

金沢工業大学情報フロンティア学部メディア情報学科「進路セミナーⅠ」

金沢工業大学情報フロンティア学部メディア情報学科の「進路セミナーⅠ」では、地域での仕事や就職活動についてもお話ししました。 私も金沢工業大学出身ですので、金沢工業大学卒業から今に至るまでの話や、 地域で働くことの意味、就職活動において重要な要素である自己PRや志望動機の作成方法、面接の対策などについても説明しました。 レポート課題にて質問を多く頂きましたので、フィードバックをお送りしました。

石川工業高等専門学校電子情報工学科「実験3」

石川工業高等専門学校電子情報工学科の「実験3」では、お時間を頂いて弊社の紹介を行いました。 石川高専卒業生の弊社社員からも、卒業生としてアドバイスのメッセージを伝えました。

また、逆に高専生の皆様の活動をご紹介いただきました。興味深い活動ばかりで技術の高さと行動力に大変感銘を受けました。 授業後の放課後も、研究室の学生の皆様とお話する場を設けていただき、交流を深めることができました。

講義の振り返り

これらの講義を通じて出会った学生たちは、本当に素晴らしく、全員が非常に優秀でした。 私たちも負けていられないなと大きな刺激をもらいました。

また、学生の皆様に就職先の候補をお聞きしたところ、大手企業だけでなく、中小企業やベンチャー企業に興味がある学生も多くいることに驚きました。 自分で起業したいという学生もおり、将来について真剣に考えている様子が印象に残っています。

今回は講師という立場でお話させてもらいましたが、いつか皆様とビジネスパートナーとしてお話できれば幸いです。 ぜひBeta Computingという会社があることを覚えておいてもらえると嬉しいです。

採用活動のご案内

弊社では現在、採用活動を積極的に行っており、才能ある若い世代を迎え入れたいと考えています。 もし、弊社に興味を持っていただける方がいらっしゃいましたら、ぜひご応募いただきたいと思います。

弊社は、社員一人ひとりが持つスキルと個性を最大限に活かし、共に成長できる環境を提供しています。 特に、新しい技術やイノベーションに興味を持ち、自らの手で未来を切り拓いていきたいという意欲を持つ方を歓迎しています。

採用情報はこちら

また、弊社ではインターンシップも募集しております。 インターンシップは、学生たちが実際の業務を体験し、自分のキャリアを具体的に考える貴重な機会です。 実務経験を積むことで、より深い理解とスキルの向上が期待できます。 インターンシップに参加することで、学生たちは企業の文化や働き方を肌で感じ、自分の適性や興味を確認することができます。 弊社のインターンシップに興味がある方は、ぜひお問い合わせください。

インターンシップ情報はこちら

最後に

講義活動を通じて、多くの優秀な学生たちと出会えたことは私たちにとっても得るものが多くあります。 皆様の熱意には感銘を受けています。これからも教育機関との連携を深めていければと考えております。 引き続き、教育機関との共同研究やプロジェクトにも積極的に参加してまいりますので、お力添えのほどお願いいたします。

これからも皆様のご支援とご協力を賜りますよう、お願い申し上げます。どうぞよろしくお願いいたします。

Androidアプリケーション開発を経験して学んだこと#フレームワーク&ライブラリ編

この記事について

こんにちは、Beta Computing株式会社でアルバイトをしていますAndroidアプリケーション開発担当です。
前回の「Androidアプリケーション開発を経験して学んだこと#ツール編」に引き続き、学んだことを書いていきます。今回はフレームワークやライブラリについてです。

学んだこと

Gitにおけるブランチ名

私はアプリケーション開発に関わる以前、Gitに関する知識が浅く、ブランチを分けることすらしていませんでした。
しかし開発となるとそうはいかず、ブランチを適切に作成し進める必要があります。
そこで問題になったのがブランチの命名方法です。複数人で開発を行う際はブランチの命名は適当では無く、社内で共通ルールを決めて命名する場合があります。
例えば以下の様な命名方法があります。

  • git-flowモデル
    • masterブランチ - メインブランチ
    • developブランチ - 次回リリースする際にmasterマージするブランチ
    • featureブランチ - 新しい機能を開発する際のブランチ

その他については以下のサイトが勉強になりました。

参照:Gitのブランチモデル(git-flow, GitHub Flow, GitLab Flow)のブランチ名まとめ


ドキュメンテーションコメント

過去の私はとにかくいろいろな場所にドキュメンテーションコメントと呼ばれるものを書いていましたが、その役割についてはあまり理解していませんでした。今回、先輩社員の方からアドバイスをいただいたので、それについてまとめたいと思います。

まず、ドキュメンテーションコメントとはクラスや変数・メソッドなどにそれらの概要や目的を説明するために書くコメントのことです。 Javaなどではドキュメンテーションコメントを書いておくことによって、クラスの仕様書のようなもの(Javadocなど)を簡単に作成できたりします。
例えば以下の様に書くことが出来ます。

/**
 * クラスの説明
 **/
class TestClass {
  /**
   * メンバの説明
   **/
  int value = 0;
}

ドキュメンテーションコメントはとても便利なのですが、常にどこでも使えばよいというわけではないようです。
privateメソッドなどにはドキュメンテーションコメントではなく、普通のコメントを使用します。

/**
 * クラスの説明
 **/
class TestClass {
  // privateメソッドの実装内容(通常コメントを使用する)
  private void function(int value) {
    ...
  }
}

ドキュメンテーションコメントについては以下のサイトが勉強になりました。

参照:Javadoc ドキュメンテーションコメントの書き方


ktlint(コードスタイルのチェック)

ktlintとはKotlinのコードスタイルをチャックしてくれるライブラリです。
今回はそのktlintをGradleプラグインとして導入できる「org.jlleitschuh.gradle.ktlint」を使用しました。
このライブラリを導入した後に、コマンドラインで「./gradlew ktlintCheck」を実行するだけで、プロジェクト内のコードをチェックしてくれます。下の画面をご覧ください。

画像のように「BUILD SUCCESSFUL」と表示されればコードスタイルに問題が無かったということになります。
逆にビルドに失敗すると、コードスタイルが間違っているところを提示してくれます。
ビルドが成功するまでコードを修正することでコードを綺麗に保てます。

ktlintについては以下のサイトが勉強になりました。

参考:【Android】コードスタイルをチェックする ktlint の導入方法


Timber(ログの出力方法)

TimberとはAndroidアプリケーションにおけるログ出力を便利にするライブラリです。
まず、普通にAndroid studioでログを出力させるには、以下のようにします。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d("MainActivity","ログ出力テスト")
    }
}

すると以下の様にログが出力されます。

ここで先ほどのコードをみていただきたいのですが、Log.d() 内には二つの引数を渡す必要があります。
左側にはタグを、右側にはメッセージを渡しています。そして出力では左側の方にタグが、右側の方にメッセージが出力されています。

それに対して、Timberを使用すると以下の様に書くことが出来ます。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Timber.d("ログ出力テスト")
    }
}

Timberを使うと、ログ出力時にフォーマット書式を組み立ててくれたり、ビルドバリアントごとにログ出力の設定 (Tree) をカスタマイズできたり、ログ出力の書式に関してLintによる警告を追加してくれたりします。
特に、デバッグ用途でログを使用する際は、ライブラリ標準のDebugTreeというTree (ログの出力制御ロジック) を使用するのが一般的ですが、このDebugTreeを使用している場合、わざわざ自分でログのタグ名を指定せずとも、呼び出し元のクラス名を元に勝手にタグ名を設定してくれたりします。
ただし、このDebugTreeはパフォーマンスの関係上リリースビルドでは使用しないことが多く、注意が必要です。

また、Timberを導入すると、元々のLogを使ってログを出力していた箇所を指摘してくれます。以下の画像をご覧ください。

ここからTimberへの書き換えはワンクリックで可能です。

大変便利なTimberですが、導入は以下の手順で行います。 まず、build.gradleファイルに次の記載が必要です。

dependencies {

    implementation("com.jakewharton.timber:timber:5.0.1")
}

追記した後は右上の「Snyc Now」を押して同期します。
同期が完了した次は、Applicationクラスの設定します。
以下の様なクラスを追加で作成します。「MyApplication」は適宜命名してください。重要なのはApplicationクラスを継承していることです。

import android.app.Application
import timber.log.Timber

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
    }
}

こちらでTreeにDebugTreeを設定しています。
ここで自作したTreeを設定することも可能です。
Treeを自作することで、出力時のルールの変更、ログの外部出力といったカスタマイズを追加することが出来ます。
※Applicationクラスについては以下のサイトが簡潔に説明されていました。

参照:Applicationクラスとは何か?

Applicationクラスを継承したクラスを作成した後は、プロジェクトの「AndroidManifest.xml」ファイルに以下の記述を追加します。

    <application
        android:name = ".MyApplication"

以上がTimberの使い方および導入方法です。 Timberについては以下のサイトが勉強になりました。

参照:AndroidのLogとTimberについて


Hilt(DIコンテナ)

Hiltは依存性(オブジェクト)の注入を簡素化することが出来るライブラリです。
依存性の注入とは、あるオブジェクトや関数が、依存する他のオブジェクトや関数を受け取るデザインパターンです。
これにより、プログラムの柔軟性が向上し、テストが容易になります。 導入方法や使い方は説明するとそれだけで記事が書けてしまいそうなので、今回は割愛します。

Hiltについては以下のサイトが勉強になりました。

参照:Hiltを使ってみよう


Ktor(Http通信)と Kotlinx.serialization.json

Ktorとは、Kotlinで動くWebアプリケーションフレームワークです。
KtorのHttpクライアントを使うことで、Http通信を簡単に行うことができます。 さらに、後述する「Kotlinx.serialization.json」と組み合わせることで、パースも簡単かつ高速に行うことが出来ます。

Kotlinx.serialization.jsonはJsonのパースを簡単かつ高速に行うことが出来るライブラリです。
Httpクライアントと一緒に使うことで、Http通信を簡単かつ高速に行えます。

KtorのHttpクライアントとKotlinx.serialization.jsonを使うには、モジュールのbuild.gradleファイルに次の記載が必要です。

plugins {
    // Kotlin Serialization関連
    id 'org.jetbrains.kotlin.plugin.serialization'
}

dependencies {

    // Ktor(ケイター)関連
    implementation "io.ktor:ktor-client-core:2.3.2"
    implementation "io.ktor:ktor-client-cio:2.3.2"
    implementation "io.ktor:ktor-client-json:2.3.2"
    implementation "io.ktor:ktor-client-serialization:2.3.2"
    implementation "io.ktor:ktor-client-content-negotiation:2.3.2"
    implementation "io.ktor:ktor-serialization-kotlinx-json:2.3.2"

    // Kotlin Serialization関連
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1"
}

また、プロジェクトのbuild.gradleファイルにも以下の記載が必要です。

plugins {
    id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.20' apply false
}

Kotlinx.serialization.jsonにいては、詳しい設定や使い方は以下のサイトが大変わかりやすく説明しています。

参照:【Kotlin】Kotlin Serialization で JSON をパースする

設定は以上です。
次に使い方ですが、APIコールしてデータを受け取りログに出力するアプリケーションを例に考えてみます。 まずAPIコールには以下のユーザー情報をランダムに作成するAPIを使用します。

参照:RANDOM USER GENERATOR

このAPIを使うと以下の様なレスポンスが返ってきます。

{
    "results": [
        {
            "gender": "female",
            "name": { // 名前
                "title": "Ms",
                "first": "Rena",
                "last": "Großmann"
            },
            "location": { // 住所
                "street": {
                    "number": 7366,
                    "name": "Parkstraße"
                },
                "city": "Waghäusel",
                "state": "Bayern",
                "country": "Germany",
                "postcode": 11878,
                "coordinates": {
                    "latitude": "-54.8818",
                    "longitude": "149.4619"
                },
                "timezone": {
                    "offset": "-3:00",
                    "description": "Brazil, Buenos Aires, Georgetown"
                }
            },
            "email": "rena.grossmann@example.com",

// 以下情報が続く...

このレスポンスをパースしてログに出力してみます。 まずはこのJsonをパースするためのデータクラスを作成します。
「Kotlinx.serialization.json」を使ったパースでは、受け取るJsonの構造と同じ構造をしたデータクラスを作るだけでその型としてJsonデータをパースして受け取ってくれます。
さらに、Jsonの必要な一部のデータのみを受け取ることも可能です。

では、先ほどのレスポンスから名前と住所のみを受け取るデータクラスを定義してみましょう。 以下が受け取る対象です。

{
    "results": [
        {
            //...
            "name": {
                "title": "Miss",
                "first": "Naja",
                "last": "Andersen"
            },
            "location": {
                //...
                "city": "Stenderup",
                "state": "Syddanmark",
                "country": "Denmark",
                //...
            },
            //...
        }
    ],
    //...
}

以上の内容をデータクラス化します。まずは以下のコードをご覧ください。

package com.example.myapplication

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class UserJson (
    @SerialName("results") val results : List<Result>?
)

@Serializable
data class Result (
    @SerialName("name") val name: Name?,
    @SerialName("location") val location: Location?
)

@Serializable
data class Name (
    @SerialName("title") val title: String?,
    @SerialName("first") val first: String?,
    @SerialName("last") val last: String?
)

@Serializable
data class Location(
    @SerialName("city") val city: String?,
    @SerialName("state") val state: String?,
    @SerialName("country") val country: String?
)

Jsonの階層構造をそのままデータクラスで表現しています。
Jsonとデータクラスを紐付けるには@Serializable アノテーションをそれぞれのクラスに付与します。
@SerialName アノテーションは、変数名とJsonにおけるキーの値が異なる場合に必要になります。

次に以下の様なクラスを用意します。
※サンプルコードのため細かなエラーハンドリングは割愛しています。

package com.example.myapplication

import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.engine.cio.CIO
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.get
import io.ktor.client.statement.HttpResponse
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
import timber.log.Timber

class UserQueryService {
    // HttpClientおよびJsonパーサーを使い回します。
    private val _client: HttpClient by lazy {
        HttpClient(CIO) {
            install(ContentNegotiation) {
                json(
                    Json {
                        ignoreUnknownKeys = true
                        coerceInputValues = true
                    }
                )
            }
        }
    }

    suspend fun getRandomUser() {
        val request = "https://randomuser.me/api/"

        val result: UserJson
        try {
            val response: HttpResponse = _client.get(request)
            //  TODO: 今回は割愛しますが、エラーハンドリングを行います。

            result = response.body()
        } catch (ex: IOException) {
            Timber.e("通信エラー")
            //  TODO: 今回は割愛しますが、エラーハンドリングを行います。
        }
        Timber.d("パース成功")
        Timber.d(result.toString())
    }
}

このクラスにはメンバーに変数の_client と、メソッドのgetTandomUser() があります。

_client はHttpクライアントとJsonパーサーの役割を持っています。
この変数は通信処理が起こるたびにインスタンスを作り直すのでは無く、メンバーとして宣言し使い回す方が効率的です。

getTandomUser()_client を用いて実際にHttp通信とJsonのパースを実行します。
このように記述することで、APIコールの結果のレスポンスボディがUserJson型にパースされ、APIの処理結果を取り扱うことが出来ます。 この関数をコルーチンを用いて実行すると以下の結果が得られました。

  UserJson(result=[Result(name=Name(title=Ms, first=Namratha, last=Uchil), location=Location(city=Thoothukudi, state=Tripura, country=India))])

ちゃんとパース出来ているようです。

以上がHttpクライアントとKotlinx.serialization.jsonを使ったHttp通信とJsonパースです。
このコードを動かすにはコルーチンを使った非同期処理の実装が必要ですが、コルーチンについては次の設計編で紹介します。

まとめ

今回はAndroidアプリケーションの開発を通して、学んだことのうちフレームワークとライブラリに関するものを集めました。フレームワークなどを扱うにはフレームワークそのもの以外の知識も要求され、使いこなすのことは簡単ではありませんでした。また、まだまだ知らない部分や理解していないことも多く、さらなる勉強が必要であると感じています。

Androidアプリケーション開発を経験して学んだこと#ツール編

この記事について

こんにちは、Beta Computing株式会社でアルバイトをしていますAndroidアプリケーション開発担当です。
現在、Androidアプリケーションの開発を学んでおり、そこで得た知識をこの記事で書いていこうと思います。
ただし、どのようなアプリケーションを開発したかはここでは秘密保持の関係上述べることはできませんのでご了承ください。

目次

Androidアプリケーションを開発して思ったこと

Androidアプリケーションの開発において、私が感じたことを述べます。
まず、コードの書き方やツールの更新が非常に早いことが挙げられます。1、2年前に書かれた記事を参考にしても、新しい技術や流行が出現したことで、その情報が古くなってしまうことがよくありました。私は主に本を購入して技術を学んでいましたが、本は体系的に学べるメリットがある一方で、出版時点ですでに技術が古くなってしまうデメリットもあることを学びました。これらのことから、アプリケーションの開発においては、常に最新の情報を追いかけることが重要だと感じました。
また、経験からしか分からないことが多いということも感じました。インターネット上には様々なコードの書き方やツールの使い方が説明されていますが、それらの最適解を知る方法は限られています。私がアプリケーションを作る過程で、Androidアプリ開発担当の有明さんから様々な指摘を受け、多くのツールや技術を学ぶことができました。私が勉強不足だったこともありますが、普通にインターネットや書籍で調べても知ることができなかった知識がたくさんありました。これらのことから、アプリケーション開発においては、経験を積むことが重要だと感じました。 以上が、私がAndroidアプリケーション開発において感じたことです。常に最新の情報を追いかけることと、経験を積むことが重要だということが分かりました。今後も、これらのことを意識してアプリケーション開発に取り組んでいきたいと思います。

学んだこと

1. GitBucketについて

アプリケーションのバージョン管理およびコードレビューは、GitBucketと呼ばれるツールを使用して行いました。
GitBucketは、Web上でGitを管理するためのGitのホスティングサービスの1つです。
また、自分のサーバー上で管理・運営することができ、GitHubのように外部にソースコードを公開せずにWeb上でリポジトリを管理することができます。
GitBucketはオープンソースで公開されており、弊社でも社内用サーバに導入しています。

私はGitHubやGitLabを使用した経験がありましたので、少し慣れない部分もありましたが、基本的な使い方はすぐに慣れることができました。しかし、プルリクエストを立ててからマージする流れは今でも時々混乱します。
そこで、本項ではGitBucketを使用してプルリクエストを立ててからマージするまでの手順を簡単にまとめておこうと思います(リポジトリの作成やCloneなどは既に行われているものとします)。

手順1:プルリクエスト画面を開く

まずGitBucketを開くと、下のような画面になると思います。

右のメニューの中から「Pull requests」を選択します(画像の吹き出しを参考にしてください)。
次に右上の「New pull request」ボタンをクリックして新しいプルリクエストを作成していきます。

手順2:マージ先とマージするブランチを指定する

まず、ページ上部でマージ先とマージするブランチを作成します。今回はsubブランチをmainブランチにマージしたいので、下の画像のように選択します。左がマージ先のブランチで、右がマージするブランチです。

選択後は「Create pull request」ボタンをクリックして次の画面に進みます。

手順3:プルリクエストの内容を記述

ここでは、プルリクエストの内容を記述していきます。まず下の画面上部にタイトルと変更内容を記述する場所がありますので、そちらにそれぞれ記述します。 ここでは、他の方がレビューすることになるので、丁寧に書きます。

内容に問題が無ければ、右下の「Create pull request」をクリックします。

手順4:プルリクエストを確認する

無事プルリクエストを作成できれば、「pull requests」のメニューから先ほど作成したプルリクエストの詳細画面にたどり着けることができます。以下がその画面です。

ページ下のコメント欄からコメントすることも可能です。レビューする側の人はこちらから指摘事項を投稿します。

手順5:マージしてクローズする

レビューが終わり、いよいよマージすることになった場合は、先ほどの画面の真ん中にある「Merge pull request」ボタンをクリックしてマージします。
その際、コメントを書く画面に移るので、コメントを書いて「Confirm merge」ボタンをクリックしマージを確定します。
この手順を踏めば、プルリクエストは自動的にクローズされるようです。
私はよくこの手順を間違えてマージする前にクローズしたりしていました。

以上がGitBucketにおけるプルリクエストからマージまでの手順となります。
普段様々なツールを使い分けていると混乱してしまうのでこの機会に使い方整理してみました。

Git Bucketの詳しい情報は以下からご覧ください。

GitBacket詳細はこちら(GitBucket公式ページ)


2. GitHub Desktop(GUI)について

今回の開発ではGUI(グラフィカルユーザーインターフェース)であるGitHub Desktopを使用してGitを操作しました。
私がGitを勉強するために読んでいた本の内容がコマンドによる操作中心で、今までGUIには触れてきませんでしたが、勉強目的でGUIを導入してみました。
GitのGUIクライアントには色々ありますが、今回はGitHub Desktopが一番使いやすそうに見えたのでこちらの説明をします。
まずGitHub Desktopを導入して感じたことは、直感的でとてもわかりやすく、操作が簡単だということです。
以下の画像がGitHub Desktopの画面一例です。
リポジトリの選択、ブランチの選択、コミットまでクリック一つで可能です。
さらにコマンドを打つことを無く差分を確認したり(真ん中の緑の枠をご覧ください)、コミットするファイルの選択も簡単に選択することができます(ファイル右のチェックから可能です)。
しかも変更も勝手に認識されます。

もちろんプッシュもクリック一つでできます。下の画像をご覧ください(さらには、画面の中央でコミット後にプッシュできることを提案してくれますね)。

また、「History」タブを開けば、今までのコミット履歴を変更差分と共に簡単にかつ視覚的に確認することができます。下の画像をご覧ください。

ブランチの新規作成も簡単です。下の画像をご覧ください。

さらにはCherry-pickと呼ばれる他のブランチのコミットを別のブランチに適応させる操作もGitHub Desktopだとドラッグ&ドロップだけで出来てしまいます。

これには感動しました。

以上がGitHub Desktopの基本的な使い方になります。コマンドより簡単に操作が出来るため基本的にはこちらを使っていこうと思います。

GitHub Desktop詳細はこちら(GitHub Desktop公式ページ)


3. Kotlinについて

今回のAndroidアプリケーションの開発言語にはKotlinを使用しました。
私はJavaを既に学習しており、Androidアプリケーション開発においてもJavaを用いようと考えていましたが、Kotlinの方が効率的かつ安全にアプリケーションを開発できるとのアドバイスをいただき、Kotlinによる開発に挑戦することとなりました。

kotlinとは?

まずkotlinとはどのような言語でしょうか。 KotlinはJavaと互換性のある、JVM(Java仮想マシン)上で動く言語です。つまりJavaのコードはKotlinで呼び出すことが可能ですし、その逆も可能です。 また、Javaよりもコードを簡潔に書くことが出来ます。 以下はKotlinの一例です。

fun main() {
  println("Hello, world")
  // Hello, worldと出力されます
}

さらにkotlinにはnull安全性が保証されています。
null安全性は簡単にいえば、non-nullable型などを導入することでnullに関連する例外が起こらないようにしてくれるシステムです。
non-nullable型とは、nullを代入することを許さない型です。
そもそもnullを使わないようにすることで、Javaで起こりがちだったNullPointerException例外を極力排除することが出来ます(ただし入出力などでは適切にnullを扱う必要があります)。

以上がKotlinの大まかな特徴になります。KotlinはAndroidアプリケーション開発の公式言語であり、今後もよりKotlinの需要は増えていくと考えていますので、私も乗り遅れないようにKotlinについてもっと勉強しようと思います。

Kotlinについては、以下の公式サイトからさらに詳しく知ることが出来ます。

kotlin詳細(Kotlin公式サイト)

まとめ

本記事では、Androidアプリケーション開発を通して学んだことの中でもツールに関連するものをまとめました。
このような便利なツールは、知らないだけで他にもたくさんあり、自分でも探してみようと思いました。それらを使いこなして自分の力にしたいと考えています。

インターンシップに参加した感想

自己紹介

こんにちは、私は金沢大学大学院 自然科学研究科に所属しております学生です。
今回はBeta Computing株式会社のインターンシップに参加した感想をまとめます。

インターンシップに参加した理由

私が通っている大学には、イノベーション方法論という講義があります。 この講義では、さまざまな企業の方を講師として招き、実際の起業体験や起業の魅力、難しさについて学ぶことができます。 その中でBeta Computing株式会社の村松さんが講師を務められている講義があったのですが、会社説明でお話されていた少数精鋭の運営方針に非常に興味を持ちました。 一人ひとりの意見やスキルが経営戦略に直接的に反映されるため、立場に関係なく仕事やプロジェクトに大いに関与できる環境が魅力的に映りました。また、私はアプリケーションの開発にも興味があり、スマートフォンアプリケーションの開発を中心としている業務にも関心を持ち、Beta Computing社へのインターンシップの応募を決めました。

インターンシップの概要

Flutterによるアプリケーションの開発を体験しました。 具体的にはFlutterを使用するためのAndroid Studio(Androidアプリケーションを作成するためのツール)などの環境構築からFlutterを用いてBMI(体格指数)を計算し表示するアプリケーションの開発まで体験しました。
また、社員の方々とお話させていただく時間もあり、社風や制度について多くのことを知ることができました。

感想

スマートフォンアプリケーションの開発に関して、一部分実装方法やより良い設計方法などが分からないことがありましたが、Androidアプリ開発担当の有明さんから的確なアドバイスがあったおかげで、最後まで実装を終えることができたと感じました。今まで私は、Javaのプログラミングの勉強を続けており、プログラミングには自信があったのですが、実際の開発や設計に触れたことで私のスキルはまだまだ未熟であることを痛感いたしました。また、別の言い方をすれば、社員の方々の技術力がとても高度だったことに感銘を受けました。特に「こうすることでアプリケーションのパフォーマンスが上がる。」といったアドバイスから、ただ動くだけのものを作るのではなく、より良いものを作ろうとしている意識があることにプロ意識を感じました。これらのアプリケーションの開発を通して得た知識や考え方は、今後エンジニアとして働いていく上で役に立つと思いましたし、大変有益で勉強になりました。
次に、社員の方々との座談会について、代表取締役社長の吉村さんを含めて全ての方とお話しでき、Beta Computing株式会社の雰囲気をつかむことができたと感じました。また、業務や制度に関する細かな質問から、就職に対するアドバイスなどさまざまな対応をいただきました。今後の就職活動に大変有益な情報を得ることができました。この場を借りて感謝申し上げます。

最後に

本インターンシップを通じて、Beta Computing株式会社についての概要や業務・制度、日々の業務の進行方法など、幅広い体験と知識を得ることができました。 これらの経験から得たものは、将来の就職活動においても大いに役立てていきたいと思っています。

また、本インターンシップをきっかけにアルバイトとして勤務させていただくことになりました。 引き続きブログ記事をまとめていきたいと思いますので、皆様宜しくお願い致します。