ないぱかの記録

ないぱかからあるぱかになれるか

2023年の振り返り

こんにちは!ないぱかです。

去年に引き続き、大晦日に振り返り記事を書いています。今回で6回目〜!



2023年の振り返り

仕事

社会人6年目になりました。新卒で入ったSIerのSEから転職してからは4年経ちました。
(新卒同期たちが今何やっているのか気になる)

今年は人生2回目の転職をし、4月からAltive株式会社でお世話になっています!

副業していたときからお世話になっていて、心理的安全性が高く、快適な環境で仕事できているのでありがたいです。

引き続き、Flutterアプリ開発をメインにやっていますが、会社の方針でアプリと並行してサーバーサイドの開発もやっていくということになったので、今年からGolangにも入門しました。

受託開発と並行して自社アプリを一から作っていて、サーバーサイドやクラウド周りなどの開発進めるたびに壁にぶつかっていますが、なんとか乗り越えながらやれています。 ChatGPT様様です。
新しいことはじめるのは大変だけど、やれることが増えると楽しいですね。

また、今年は会社の記事として、初めてアドベントカレンダーにも参加しました!

zenn.dev

毎回思うことですが、記事書くと自分の頭も整理されるし、周りの役に立つしでいいことばかりですね。
来年はSNS含めてアウトプットや露出を増やしていきたい。

勉強会

今年はいくつか勉強会にも参加しました。
3年ぶりのオフライン勉強会にも参加。来年も参加していく!

【オンライン】Flutter ハンズオン #11 〜 Supabaseでチャットアプリを作る 〜 - connpass
Go言語プログラミングエッセンス - Forkwell Library#27 - connpass
iOSDC Japan 2023
DroidKaigi 2023
golang.tokyo #33 - connpass
【増枠】GDG DevFest Tokyo 2023 - connpass

個人開発

今年からPikaPikaに課金を導入しました!
サブスクと買い切りプランを作ったのですが、やっぱり買い切り買ってくれる方の方が断然多いですね。
課金機能も喜んでもらえたのでよかった。
既存機能の改善やストアのリリースノートの多言語化を自動化したり。。

また、個人開発で使っているday_night_time_pickerへのPRを出してみました。
少し放置されてたけど声かけたらすぐレビュー・マージしてもらえました。
Contributorsに名前が載っていると嬉しいものですね。

一度PR出してみてからOSSへのPRやissue作成のハードルがかなり下がった気がするので、来年もどんどんやっていきたいです。
(これからswagger_parserをがっつり使っていきそうなので、issueやPR作成で貢献したいと思っています。)

ユーザー数・収益

合計ユーザー数は12月時点で10.5万でした!ついに大台の10万超え!

ただ最近アップデートしていないからか、どんどんMAUが下がっている。。
アップデートしないとなぁと思いつつ、今は自社アプリ作る方が楽しいのでモチベーション的に難しい。。。

収益に関しては、課金機能を導入したことで去年よりも10倍くらい増えました!
毎月不労所得が入ってくるのは精神的にありがたい。。。

プライベート

去年立てた目標が「幅を広げる」だったので、プライベートでもやったことないことを色々しました!

  • 陶芸:
    • 思っていた以上に難しい…!何度かぐしゃった記憶
    • お茶碗作りたかったけど思いのほか小さくなったのでお惣菜入れになりました
  • 漫喫で1日過ごす
    • 人生で一回くらいしか行ったことのなかった漫喫で1日過ごしました
    • ひたすら漫画読む日があってもいいですね
  • 家庭菜園
    • 葉ネギとサニーレタスを育てています!
    • 発芽の体験がとてもよかったので、それを元に家庭菜園に関するアプリを作成中…
  • オーケストラ聴きにいく
  • ロッキン参戦
    • 8/12(土)に参戦
    • サンボマスター間近で見れて最高だった
    • 最後の羊文学だけ見れなかった(疲れすぎて帰ることにした)のが心残り
  • サウナ
    • サウナ好きな友達に連れて行ってもらった
    • 2回行ったけどまだトトノウがわからない、あと何度か行けばわかるかなぁ

「1ヶ月に1回やったことないことをやる」は達成できなかったのですが、来年も引き続き新しいことに挑戦していきたい!

家族

去年結婚してからウイルス感染拡大の影響でできなかった、両家顔合わせや両親への挨拶(直接)などを一通り行いました!
それぞれの両親への挨拶は直接したものの、顔合わせはリモートだったので来年は直接会える場を作りたいと思っています。

新婚旅行で沖縄の宮古島石垣島にも行ってきました!
美味しいもの食べていいホテルでゆったり過ごせて最高でした〜こういうの毎年やりたい。
交通事故にあったり(もう車運転したくない)、駐車中の車の中でWBCの準決勝で勝った瞬間「ヤッター!!!!!!!!」とバンザイして大声出したら妻に「そんな大きな声出るんだ…」とびっくり&引かれたりしたのもいい思い出。

運動

ダンベルやトレーニングベンチを買って筋トレをしたりしなかったり。

12月からSwitchで発売された「HOP! STEP! DANCE!」でダンス始めました!
昔からダンスできる人に憧れがあったので、少しずつ踊れるようになってきて楽しいです。

ゲーム

今年遊んだゲームは去年に比べて少なめでした。やりたいとは思っているけどMac Bookに向かう時間の方が多くなっちゃう。。

ゼルダの伝説 ティアーズ オブ ザ キングダム | Nintendo Switch | 任天堂

ここ数年やったゲームの中で一番好きです…ブレワイ、無双含めて記憶消してまたやりたい。 最後の演出良すぎた。。

FINAL FANTASY XVI (ファイナルファンタジー16)| SQUARE ENIX

待ちに待ったFF16…!バトルアクション楽しい!召喚獣戦迫力やばすぎ!
少し期待しすぎていたのかがっかりした部分はあったものの、全体的には満足。
久々にPS5を起動したらDLCが発売されていたので落ち着いたらやりたい。

FINAL FANTASY VIII Remastered ダウンロード版 | My Nintendo Store(マイニンテンドーストア)

セールで安くなってたので買ってみました!面白かった。
本編よりもカードゲームの方が夢中になっちゃったかも。

2024年の目標

2023年の目標は「幅を広げる」でした。技術面ではFlutter以外の分野に入門したり、趣味でも色々初めての経験ができたので概ね達成と言っても良さそうです。

2024年の目標は「深める」にします!
今年色々と手を出した分野のインプットとアウトプットを増やして知識を深め、受託・自社アプリ開発を加速させていきたい!

最後に

毎年振り返れてえらい。

以上、ないぱかでした!良いお年を〜!

これまでの振り返り記事一覧

naipaka.hatenablog.com

naipaka.hatenablog.com

note.com

note.com

naipaka.hatenablog.com

2022年の振り返りと2023年の目標

特別お題「わたしの2022年・2023年にやりたいこと

こんにちは!ないぱかです。

本日は大晦日。大晦日といえばTwitterで「Bigみそか」や「デカみそか」というワードを見つけてウケました。気に入ったので使っていきたい。

さて、今回は毎年恒例の振り返り記事です。今回で5回目だッ。



2022年の振り返り

本業

まずは本業関連の振り返り。

とうとう社会人5年目になりました。モバイルエンジニア転職してからは3年目。
(最近これらの年数に対して相応しいスキルが身に付けられているのか不安になることが多い。)

今年も去年と同様Flutterでのアプリ開発をメインでやっていました。
全部で3つのプロジェクトに参画したのでそれぞれを振り返っていこうと思います。

1月〜6月

半年間は去年に引き続き2020年11月から参画していたFlutterアプリの案件に携わっていました。

下記のように去年の2021年では規模が大きめなチームで開発を行なっていましたが、開発タスクが落ち着いてきたこともあり、8人×2チームの体制に変わっていきました。

開発しているアプリは比較的大規模なアプリで、開発しているチームの規模も大きく(平均 8〜10 人の開発チーム × 3 チーム)、他では経験できないような良い経験をさせてもらっています。

業務内容は変わらず実装・レビューがメインで、新しい機能の追加実装やリファクタリング、バグ修正をやっていた気がします。(当時のことをちゃんとメモしてなくて今年から覚えていない…メモ大事。)

1年以上同じプロジェクトに参画して慣れてきたのもあって、知見のあるタスクは即対応できるようになっていましたが、それと同時に仕事内容にマンネリ感を覚え始めたり、チームメンバーへの不満等が溜まってしまったのもあり、退プロすることに決めました。

7月〜11月

7月からは新規事業のプロジェクトに参画しました。

要件定義からのスタートだったので、難しくもありましたがかなり楽しく仕事できていたなと思います。要件定義後は要件に合わせてワイヤーフレームを作成し、機能をデザインに落とし込み、大体の枠組みが決まった後は実際にFlutterを使ってモックアプリを作成していました。

他のメンバーが別プロジェクトで忙しいこともあり、基本一人での作業が多かったのですが、仕事自体は個人開発の延長のような気持ちで取り組めていました。

ただ対話する機会が少なかったのでやはり寂しさをかなり感じました。
やっぱり誰かとなんやかんや言いながら開発した方が学びも多いし楽しいですな。

上記プロジェクトと同時に、Flutter未経験のチームメンバーに対してFlutterの勉強会も実施しました。
人に教える経験があまりなく自分なんかが教えられるのかと心配でしたが、いざやってみると「身になっている」と言ってもらえたり、自分自身も学びを得られたりといいことが多くあったので、やってよかったなと思っています。

12月〜

12月中旬から自社のチームメンバーと一緒にFlutterアプリ開発プロジェクトに参画し始めました。

まだ参画したばかりなのですが、早速新規参画者用ドキュメントで気になったところを更新したり、VSCodeの起動ファイルの改善提案を行ったりと積極的に動けています。

スクラムがしっかりしており、勉強になることも多そうな感じがしているので、足りないところは吸収しつつ、どんどん貢献していきたいです。

副業

続いては副業についての振り返り。

これから先本業以外でも稼いでいくことを考慮して、開業届を出し、バーチャルオフィスを契約して、今年から個人事業主として副業を始めました。青色申告で節税したかったので目的の1つですね。

副業の内容としては、去年に引き続きFlutterアプリ開発のプロジェクトに参画し、設計から実装・レビューまで幅広く対応していました。

設計に関して少し先走ってしまい、手戻りが発生してしまったこともありましたが、最終的には全員が納得いく形になったのでいい経験になったかと思います。

また、業務で初めてアプリの課金処理を実装しました。途中開発環境で動作確認ができず詰まったところもありましたが、無事何事もなくリリースすることができました。
実装以外に関しても、GitHubのDisscussionなどでアプリ構成の提案をしたり、レビューフローの改善を提案したりと、積極的にチームに貢献しようと動くことができたと思っています。
上記の行動等を評価してもらうことができ、単価も上げていただけました。(感謝!)

10月から一旦休ませてもらっていましたが、来年も1月からまた参画する予定なので、さらに貢献できるよう積極的に動いていこうと思います。

確定申告

そういえば、今年は初めて確定申告を行いました。
正しくできるか不安でしたが、マイナンバーカードを発行していたからか、家にいながら全ての過程を完了することができたのでとても楽ちんでした。

また、原則2月中旬からが確定申告の受付開始ですが、1月4日からでも受付してくれるようだったので、1月中旬に終わらせて高みの見物をキメてましたw

2023年も年末年始休暇中にサクッと終わらせたいですね。

個人開発

次に個人開発。今年はあまり去年・一昨年に比べてあまり触ることができませんでした。モチベが上がらない期間が長かった…!そんな時もあるよね。

また、去年の目標で新アプリをリリースすることを挙げていましたが、達成ならずでした。
来年はリリースしたいなぁ。

開発

主にPikaPika周りの開発をおこなっていました。

アップデートは3回のみ…まぁ「掃除管理」キーワードでは検索結果1位を維持できているのでヨシッ!
今年はCI/CDを整えたり、テスト追加したりがメインでした。

CI/CDに関しては、リリースブランチをpush・マージするだけで、ビルド/デプロイ/審査まで一発で行えるようなワークフローを組むことができました。
それまで手動で行なっていた部分を自動化できたのでかなり便利になりました。

また、テスト追加では学習も兼ねてアプリコードのカバレッジ100%になるまでテストを書いてみました。
Flutterのテストには「Unit Test」「Widget Test」「Integration Test」などがありますが、この特訓のおかげで「Unit Test」「Widget Test」に関してはかなり書けるようになりました。
本業・副業でも活かすことができたので、やってよかったと思っています。

ユーザー数・収益

ユーザー数は12月時点でMAUが7300、登録ユーザー数が51440でした。
去年・一昨年と比べると緩やかですが成長し続けていますね!

ユーザー数の増え方からMAUがもっと増えていてもいいなと思うのですが、増えていないということは定着してもらえなかったユーザーが多いということですかね。改善しなければ。

DAU MAU ユーザー数
2020年 90 600 1000
2021年 600 4000 18000
2022年 1200 7300 51000

収益ですが、7月あたりから毎月1万円以上の収益をキープできるようになりました…!ありがてぇ…
現在は広告からの収益だけなので、サブスクリプション機能を追加してそこから収益得られるようにもなりたいですね。

プライベート

引越し・結婚

5月に相手のご両親に挨拶し、8月に引っ越しをし、10月に籍を入れました!

結婚までも半同棲状態だったので生活としてはあまり変わらない感じですが、家賃が浮いたり家具家電に妥協しなくても良くなったり嬉しいことが多かったですね。

突然ですが、家具家電買ってよかったランキング〜!

1位 食洗機:手洗いの時間が激減した最高。

2位 電動リクライニングソファ:映画やゲーム、リラックスするのに最高。

3位 ベッド:買うまで布団で寝ていて敷いたり畳んだりが面倒だったので、その手間がなくなって最高。

健康

きんにくんの動画を見ながら筋トレをしたり、しなかったり。
12月からはHIITをやり始めました。きついけど体力ついていく感じがありますね。

あと11月にコロコロちゃんに罹りました。直近2週間で1度スーパーに買い出し行っただけでそれ以外に外出しなかったのに罹ってしまいました。かなしみ。

ちゃんと隔離できてなかったけど、妻はなぜかずっと無症状&陰性で謎でした。

ゲーム

今年はゲームたくさんやりました!

ついにPS5の購入権も当選したので遊びまくってます。いと楽し。

NieR:Automata

ずっと前からやりたかったニーアオートマタ。ついに遊びました。

キャラクターのファッションや世界観がかなりツボで、最終エンディングまでずっと最高でした…

FINAL FANTASY VII REMAKE

PS5を買って最初に遊んだゲームがFF7Rでした。オリジナルやったことなかったのでずっとやってみたかった。

クラウドかっこよい。ティファきれい。エアリスかわよい。

最後「えっこれで終わり?」と思ったけど3部作なんですね。今後も楽しみです。

Horizon Forbidden West

Horizon Zero Downの続編。これも楽しかった。

PS5で遊んだのでコントローラーの弓引く感覚がリアルで良い。

ドラゴンクエストX オフライン

正直にいうと、これまでやったドラクエの中で一番楽しめなかったかもしれません。

エストが移動させるばかりで面倒だったり、グラフィックが微妙に感じたり、ストーリーにもあまり入り込めず…

逆にこれをやったことでビジュアルが良く、見てるだけで楽しいゲームが好きなんだなぁと再実感したりもしました。

CRISIS CORE -FINAL FANTASY VII- REUNION

FF7ストーリーの前日譚。ザックスやクラウドの過去がわかってスッキリしました。FF7Rやった人は絶対やった方がいいですね。

ストーリーもバトルも面白く、スロットシステムも新鮮で楽しかったです。

メモツール

去年始めたNotionでの日報ですが、振り返りづらいし書きにくいしで面倒になってやめちゃいました。

代わりに参加しているコミュニティでおすすめされていた「Obsidian」を12月から始めてみたのですが、今のところとてもいい感じです。

フォルダ構成とか考えずに、メモしたことをリンク化しちゃえばいいので雑にメモができて楽しいです。

ショートカットやテンプレート機能も充実していて操作体験もいい感じなので、これまでiOSのメモやEvernote、Notionにまとめていたメモを全部Obsidianに移行しはじめています。

2023年はObsidianで色々日々の活動やメモをまとめていこうと思っています。


2023年の目標

2022年の目標は『「自分が羽ばたける場所を見つける年」にしたい』でした。伸び伸び仕事できる場所ですね。1年ずっと考え続けていて、ここかなという場所を見つけたので、概ね達成したような気がします。

2023年は「幅を広げる」を目標にします。技術の幅、趣味の幅、などなど。

自分はインドアを理由に外に出て遊ぶことが少ないのですが、このまま行くと自分が直接体験して感じるという機会がなくなっていき、人から見聞きした情報しか知らず、人として浅い人間になってしまうのではないか、という危機感を持ちはじめています。

技術に関しても同じで、逆に今後自分が触れたことのない領域に手を出していくことでエンジニアとして深みが出てくるのではないかと思います。

なので、2023年は「幅を広げる」を意識して行動してきます。

仕事

  • チームに積極的に貢献する
  • 技術の幅を広げる、やったことのない領域に手を出す

個人開発

  • MAU1万達成
  • サブスク機能導入
  • 多言語対応自動化

健康

  • ムキムキになる

その他

  • 1ヶ月に1回やったことないことをやるor行ったことのない場所に行く

最後に

振り返ってみると意外と色々ありました。
ただ、少し技術的な成長が少なかったかも?
来年は振り返った時に充実した1年だったなと思える1年にしたいです。

以上、ないぱかでした。良いお年を!


これまでの振り返り記事一覧

2021年の振り返り

naipaka.hatenablog.com

2020年の振り返り

note.com

2019年の振り返り

note.com

2018年の振り返り

naipaka.hatenablog.com

【iOS】既存のリリースアプリのレーティング情報の取得方法

概要

fastlaneのdeliverを使っていて、オプションにapp_rating_config_path(アプリのレーティング情報が載ったjsonのパス)も設定できるけど、どこからその情報取得できるんです??となって調べたので備忘録として残します。

取得方法

1. App Store ConnectのAPIリクエストのトークンの生成する

App Store Connect(以下ASC)にあるレーティング情報が欲しいので、まずはASCにアクセスするためのトークンを生成します。

トークンを生成するために、ASCのAPIキーを作成します。
APIキーの作成方法については下記記事が画像付きで分かりやすかったのでそちらを参考にしてください。

zenn.dev

上記でAPIキーを生成すると以下3つが取得でき、これらを用いてトークンを生成します。

  • キーID
  • IssuerID
  • .p18ファイル

まず、トークンを作成するためにJWT.ioにアクセスします。

次に、Generating Tokens for API Requestsを元に、以下画像のようにHEADERPAYLOADVERIFY SIGNATUREを入力します。

https://user-images.githubusercontent.com/45661924/159005356-738761c0-d9bd-4856-a23f-933d265d6a28.png

iatexpはそれぞれトークン作成時間トークン有効期限UNIX時間です。
有効期間は作成時間から20分以内にする必要があります。

tool.konisimple.net

また、アプリのAppStoreのIDはASCの一般情報の「Apple ID」です。

https://user-images.githubusercontent.com/45661924/159010019-076a1585-4492-4d58-8b37-ae3fb58aebea.png

入力が完了すると、左側にエンコードされたトークンが生成されるので、それを用いてASCのAPIを叩いていきます。

JWT.ioはまだ使うのでそのままにしておきます。)

2. App Informationを取得する(appinfos用のidを取得する)

Read App Information

上記のAPIを叩いてまずはApp Informationを取得します。

先ほど生成したトークンをヘッダーに付与してAPIが叩ければなんでも良いのですが、自分は下記のようにVSCode拡張機能の「REST Client」を用いて叩いています。参考

GET https://api.appstoreconnect.apple.com/v1/apps/<アプリのAppStore ID>/appInfos
Authorization: Bearer <生成したトークン>

https://user-images.githubusercontent.com/45661924/159007066-4074d452-c09f-4824-a13b-864fac287413.png

するとレスポンスが下記のように返ってくるので、先ほどトークンを生成したJWT.ioで適当な値を入れていた「アプリのリソースID」にここで取得したidvalueを設定します。

https://user-images.githubusercontent.com/45661924/159007740-1d57e29d-5cb6-40cd-abdb-f7e1cfd553aa.png

そうするとトークンがまた変わるので、それをコピーしておきます。

3. レーティングに関する情報を取得する

GET /v1/appInfos/{id}/ageRatingDeclaration

最後に上記APIを叩きます。

先ほど生成したトークンをヘッダーにつけてAPIを叩くと…

GET https://api.appstoreconnect.apple.com/v1/<アプリのリソースID>/ageRatingDeclaration
Authorization: Bearer <生成したトークン>

https://user-images.githubusercontent.com/45661924/159008364-21917809-ebe0-417c-9de8-b4fba194f9b2.png

無事レーティング情報を取得できました!

https://user-images.githubusercontent.com/45661924/159008596-3ec8e817-7a14-4536-a36e-2cd72f70af53.png

fastlaneのapp_rating_config_pathに指定するjsonには上記からattributesvalueを転記すればOKです。

{
  "alcoholTobaccoOrDrugUseOrReferences": "NONE",
  "contests": "NONE",
  "gamblingAndContests": false,
  "gambling": false,
  "gamblingSimulated": "NONE",
  "kidsAgeBand": null,
  "medicalOrTreatmentInformation": "NONE",
  "profanityOrCrudeHumor": "NONE",
  "sexualContentGraphicAndNudity": "NONE",
  "sexualContentOrNudity": "NONE",
  "seventeenPlus": false,
  "horrorOrFearThemes": "NONE",
  "matureOrSuggestiveThemes": "NONE",
  "unrestrictedWebAccess": false,
  "violenceCartoonOrFantasy": "NONE",
  "violenceRealisticProlongedGraphicOrSadistic": "NONE",
  "violenceRealistic": "NONE"
}

まとめ

これでアプリのレーティングに関する情報もgitで管理できるようになりました!

少し面倒だったので、もっと簡単な方法があったらぜひ教えていただきたいです。🙏

【Flutter】GitHub Actionsでpubspec.yml記載のビルド番号をインクリメントする

概要

最近個人開発や副業でFlutterでCI/CD環境を構築しています。
その中でPRをトリガーにpubspec.yml記載のビルド番号をインクリメントしてpushまで行うジョブを作ってみたので紹介します。

GitHub Actionsでワークフローが走るたびに採番される番号をビルド番号に使うのも良さそうなのですが、自分の場合はCodemagicも併用して使っており、いつでも切り替えができるような状況にしておきたかったのでワークフローの中でインクリメントできるようにしてみました。

完成形

以下完成形です。

on:
  pull_request:
    types: [opened]
  bump_build_number:
    name: Bump build number
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      # 1. PRのHEADブランチをチェックアウト
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.ref }}

      # 2. ビルド番号をインクリメント
      - name: Bump build number
        run: perl -i -pe 's/^(version:\s+\d+\.\d+\.\d+\+)(\d+)$/$1.($2+1)/e' pubspec.yaml

      # 3. Git操作をするための設定
      - name: Git config
        run: |
          git remote set-url origin https://github-actions:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}
          git config --global user.name "${GITHUB_ACTOR}"
          git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"

      # 4. 変更をcommit&push
      - name: Push updated pubspec.yml
        run: |
          git add .
          git commit -m "Bump build number"
          git push origin ${{ github.event.pull_request.head.ref }}

順に説明します。

1. PRのHEADブランチをチェックアウト

まずはref${{ github.event.pull_request.head.ref }}を指定してチェックアウトします。

これによって、例えばfeature/xxxブランチからdevelopへ向けたPRを作成するとfeature/xxxブランチの最新コミットをチェックアウトしてくれます。

下記理由からrefを指定せずにそのままチェックアウトするとワークフロー内でHEADに対してpushができなくなるため、明示的に指定する必要があります。

pull_requestイベントを起点に動かす場合、actions/checkout はそのPull Requestが生成しようとしているmerge commitをチェックアウトする

2 ビルド番号をインクリメント

perlを使ってpubspec.ymlのビルド番号をインクリメントしています。

version: 1.0.0+1に対応する箇所をversion: 1.0.0+2に置換してくれる形です。

3. Git操作をするための設定

タイトルの通り、Git操作(commitやpush)をするための設定です。

GH_TOKENについては${{ secrets.GITHUB_TOKEN }}から取得します。
自動でGITHUB_TOKENを設定してくれるので、自前でSercretsに登録する必要はありません。

4. 変更をcommit&push

最後にpubspec.ymlに加えた変更をcommit&pushします。

ここでもチェックアウト時同様に${{ github.event.pull_request.head.ref }}に対してpushするようにします。

まとめ

このジョブを使うことでPRを作成するたびに自動でビルド番号をインクリメント・コミットしてくれるので、デプロイ時にビルド番号の競合を意識しなくて済むようになります。

個人開発環境では下記のようなワークフローを作っているので、それぞれの事前アクションとしてビルド番号のインクリメント処理を入れています。

  • feature/xxxからdevelopにマージされたらstaging環境アプリをFirebase App Distributionにデプロイ
  • release/x.x.xからmasterにマージされたらproduction環境アプリをApp Store Connect/Google Play Consleにデプロイ

どなたかの参考になれば幸いです!

参考

r7kamura.com

github.com

【Flutter】破線(切り取り線)を実装する

概要

破線を表示できるWidgetを実装してみたので備忘録として残します。

開発環境

Tool Version
macOS 12.2.1
Visual Studio Code 1.65.2
Flutter 2.10.3
Dart 2.16.0

前提

下記のような画面を元にAとBの間に破線を実装します。

実装

実装方法は2通り。

カスタマイズ性を求めない場合

まずは、カスタマイズ性をそれほど求めない場合の実装についてです。

例えば破線の間のスペース間隔や領域をはみ出した部分をどうするかなどを気にしない場合はこちらで問題ないかと思います。

以下実装コードです。

import 'package:flutter/material.dart';

/// 破線
class DashedLine extends StatelessWidget {
  const DashedLine({
    Key? key,
    this.dashedWidth = 5,
    this.dashedHeight = 1,
    this.color = Colors.black,
  }) : super(key: key);

  /// 破線単体の幅
  final double dashedWidth;

  /// 破線の高さ
  final double dashedHeight;

  /// 破線の色
  final Color color;

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        // 破線単体の数
        // 表示する領域の最大幅 / (破線の幅 * 2)
        // 破線同士の間隔は破線の幅と同じ幅となる
        final dashedCount = (constraints.maxWidth / (2 * dashedWidth)).floor();
        return Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: List.generate(dashedCount, (_) {
            return Container(
              width: dashedWidth,
              height: dashedHeight,
              color: color,
            );
          }),
        );
      },
    );
  }
}

やっていることは「表示する領域の最大幅」と「破線の幅」から表示可能な破線単体の数を割り出して、その数の分だけ指定された幅と高さと色のContainerを表示しているだけです。

こちらをサンプルの画面に適用して切り取り線ぽくしてみると下記のような形になります。

カスタマイズ性を求める場合

続いて、カスタマイズ性を求めたい場合の実装についてです。

例えば破線の間のスペース間隔や描画領域をはみ出した部分をどうするかなどを設定できるようにしたい場合はこちらの実装をおすすめします。

以下実装コードです。

import 'package:flutter/material.dart';

/// 破線
class DashedLine extends StatelessWidget {
  const DashedLine({
    Key? key,
    this.dashedWidth = 10,
    this.dashedHeight = 5,
    this.dashedSpace = 5,
    this.color = Colors.black,
  }) : super(key: key);

  /// 破線単体の幅
  final double dashedWidth;

  /// 破線の高さ
  final double dashedHeight;

  /// 破線の間隔
  final double dashedSpace;

  /// 破線の色
  final Color color;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: dashedHeight,
      child: CustomPaint(
        painter: _DashedLinePainter(
          dashedWidth: dashedWidth,
          dashedHeight: dashedHeight,
          dashedSpace: dashedSpace,
          color: color,
        ),
      ),
    );
  }
}

class _DashedLinePainter extends CustomPainter {
  const _DashedLinePainter({
    required this.dashedWidth,
    required this.dashedHeight,
    required this.dashedSpace,
    required this.color,
  });

  /// 破線単体の幅
  final double dashedWidth;

  /// 破線の高さ
  final double dashedHeight;

  /// 破線の間隔
  final double dashedSpace;

  /// 破線の色
  final Color color;

  @override
  void paint(Canvas canvas, Size size) {
    var dashedStartX = 0.0;
    final paint = Paint()
      ..color = color
      ..strokeWidth = dashedHeight;
    while (dashedStartX < size.width) {
      // 始点
      final startOffset = Offset(dashedStartX, 0);
      // 終点
      final endOffset = Offset(dashedStartX + dashedWidth, 0);
      // 始点から終点にかけて描画
      canvas.drawLine(startOffset, endOffset, paint);
      // 始点のX座標を更新
      dashedStartX = dashedStartX + dashedWidth + dashedSpace;
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

CustomPainterを使用して破線単体の始点から終点までをcolorで描画する、というのを画面いっぱいはみ出すまで繰り返すような形です。

こちらもサンプルの画面に適用して切り取り線ぽくしてみると下記のような形になります。

まとめ

今回は破線を実装方法をまとめてみました。

あまりCustomPainterを使う機会がなかったので勉強になりました!

参考

stackoverflow.com

サンプルリポジトリ

github.com

2021年の振り返りと2022年の目標

こんにちは。ないぱかです。

2022年になりましたね。明けましておめでとうございます。

年を明けてから少し日が経ってしまいましたが、去年2021年の振り返りと今年2022年の目標をまとめます!

目次

2021年の振り返り

本業

昨年は2020年11月から参画していたFlutterアプリの案件に引き続き携わっていた形でした。

開発しているアプリは比較的大規模なアプリで、開発しているチームの規模も大きく(平均 8〜10 人の開発チーム × 3 チーム)、他では経験できないような良い経験をさせてもらっています。

ただ、良いことばかりではなく、やらかしてしまった経験もありました。
アプリの中でほとんど自分で実装したような機能があるのですが、後戻りできない段階でその機能の中でバグを見つけてしまいました。
見つけた瞬間は絶望していましたが、プロダクトオーナーに報告した後、改めて調査した結果、ユーザーに響くような大きな影響はなさそうということがわかり、心底安心したのを覚えています。
もし影響が出ていたら自分もせいでどれだけの損害が出るのかと想像してしまって正直泣きそうでした。いやもう泣いてたかも。

この失敗から自分で実装した部分に対してレビューが通っても安易に大丈夫だろうと思わず、漏れているところがないか、考えられるパターンはないかを常に意識するようになりました。
今後も忘れることがないように振り返りにも残しておきます。戒め。


1〜3月の間はリリースに向けてやらなきゃいけないことが山積みでした。深夜残業、休日出勤なども必要になることがあり、とても忙しかったです。
その中でわかったのが、夜遅くまで仕事をしたりと生活に余裕がなくなってしまうと、考え方がマイナス思考寄りになってしまうということでした。
下記は2月中旬の日報の一部です。病んでますね笑

なんのために働いてるんだっけ
自分のアプリには価値がない
自分にはなんのスキルもない

ここまでくると他に何も手につかなくなったりするので、この頃のような働き方はなるべくしないように調整していきたいです。

4月以降から現在まではかなり稼働時間も落ち着いてきて、比較的伸び伸びと開発できるようになってきました。
本業以外の副業や個人開発などを通して得た知識を活かして、Flutterに関する情報提供やレビューを行なったり、レビューアが固定の人に依存している状態を改善するための提案を行なったりと、チームに貢献できた機会も増えてきていると感じています。

所感ですが、今後もさらに貢献していけるように動いていこうと思っていると同時に、1年以上同じ場所で働いてきて、チームメンバーのことや業務の内容など、色々と思うところが出てきたので環境を変えてみるのもありかなと思ったりもしています。

副業

2021年は副業として2つの案件に携わりました。

1つは2020年に引き続き会社の先輩から紹介していただいたお仕事で1〜2月の期間でFlutterアプリを開発していました。
前述の通り1〜3月は本業が忙しくあまり貢献できなかったのですが、本業や個人開発以外の環境で初めて仕事として開発する経験ができたのは良かったです。

もう1つはTwitterで繋がりのある方から紹介していただいた案件で、6月頃から現在まで携わらせてもらっています。

仕事を紹介していただいた方は3年ほど前にとある勉強会に参加した際に知り合った方で、以前から一緒に仕事がしてみたいと思っていたので非常に嬉しく思っています!

上記の副業に限らず、社外の人とのつながりは社会人1年目の時に色んな勉強会に足を運んでいたことがきっかけで生まれているので、あの頃アクティブに動けていて良かったなと実感します。(3年前の自分グッジョブ)

こちらもFlutterアプリの開発で、本業や個人開発では得られない情報が得られたり、これまでやったことのなかった実装を経験できたりと充実しています。

また、提案を受け入れてもらえたり、コミュニケーションの中でポジティブな言葉が多かったりと心理的安全性が非常に高くとても仕事しやすいです。
また、その環境だと仕事のパフォーマンスが上がることが実感できたので、本業として働く場所に求める条件の1つになりました。

今後も続けていきたいと思っています。


副業を続けていて思ったのですが、本業以外で収入があるというのは精神衛生上非常に心強く、ありがたいですね。

複数の分野で仕事を貰い続けられるような人になれるようにこれからも精進していきたいです。

(収入といえば確定申告しないとですね…初めてなので何もわからないので早めに準備します💪)

個人開発

2021年はPikaPikaをリニューアルしました✨

掃除管理アプリ-PikaPika

掃除管理アプリ-PikaPika

  • Ryota Kobayashi
  • ライフスタイル
  • 無料
apps.apple.com

リニューアル前 f:id:naipaka:20220110234756p:plain

リニューアル後 f:id:naipaka:20220110234830p:plain

だいぶモダンな感じになったのではないかと思います。いかがでしょうか?

デザイン部分もそうですが、内部もかなり作り替えました。
NullSafety対応、各バージョン最新化対応、デザイン適用、provider→riverpod置き換えなど、全部で2〜3ヶ月ほどかかりました。

結構大変だったのですが、リニューアル直後に下記のようなレビューコメントが来ていました。

f:id:naipaka:20220110235126j:plain

これを見た時は通勤中だったのですが、見た瞬間周りに人がいる中で泣きそうになったのを覚えています。
この瞬間のために個人開発していると思えるほど嬉しかったです。

今後も多くの方に気に入ってもらえるようなアプリを作り続けていきたいですね。


昨年の振り返り記事を見ると2020年の12月末時点でPikaPikaのMAUは600ほどだったようです。
現在のMAUは4000弱で当初の目標よりもかなり上回ることができました。

ユーザー数も1000程だったところから、現在は18000を超えるユーザーに使われるようになりました。

またAppleStoreで「掃除」「掃除管理」「掃除リスト」などで検索すると検索結果の一番上に出てくるようにもなりました!
リリース前の目標として、掃除に関する検索ワードで1位になることを挙げていたのでとても嬉しく思っています。

収益についてはまだまだですが、1〜2週間分の食費が賄えるくらいの収入が得られるくらいにはなりました。
同じ掃除管理アプリで月4万ドルの収益を上げているアプリもあるようです。夢膨らみますね…!

今年もさらに飛躍できるように引き続き個人開発進めていきます!

その他

2021年は仕事以外のことも色々やっていたのでそれについても振り返ります。

日報

1月から日報を書くのを始めました。

始めた理由としては、1日1日を大事に生きる意識をつけたかったのと、過去を振り返った時に自分が何を考えて何をしていたのかがわかるようになっているといいなと思ったためです。(もし転職する時にも役立つかなと。)

やる気が出ず書かない月とかもありましたが、合計で8ヶ月分くらいの日報を書くことができました。
三日坊主の自分からしたら上出来です。

やってみた結果として、1年の振り返りを書くときに何やっていたかを思い出すのに役立っているし、1日の振り返りをするかしないかで1日の濃さが変わってくると思えたので、これからも極力書いてきたいと思っています。

100日連続リングフィット

100日連続でリングフィットをやるチャレンジを密かに行なっていて、無事達成することができました!

やればできますね自分。

ただ…現在は続いておらず、継続をやめてから確実に太ってきたので再開しようと思ってます…頑張ろう。

ドラクエとFF

人生で死ぬまでにやっておきたいことの1つに「ドラクエとFFのナンバリング作品を全部クリアする」というのがあります。(去年思いつきました)

というわけで、去年はドラクエの1〜3とFFの5をクリアしました!

どれも自分が生まれる前に発売されたゲームでしたが、それぞれストーリーも面白くシンプルでとても楽しめました。
ドット絵ってのも良きですね。

まだまだやったことのない作品はあるので、少しずつ時間を見つけてクリアしていきたいです。

Twitter

去年の4月くらいからないぱかのアカウントでタイムラインを見たりツイートするのをやめました。

理由としては他の人のツイートを見て自分と比べてしまって落ち込んだり、色々な理由で気軽にツイートできなくなってしまったので心を休めるためです。

おかげで心の平穏は保てたのですが、技術的なツイートを見なくなったのでFlutterなどの技術的な情報を追えなくなってしまいました。。

これは現状の課題だと感じているので別アカウント作って有識者のFlutter情報だけ集めるようにしてみようかとも考えています。

2022年の目標

2022年は「自分が羽ばたける場所を見つける年」にしたいです。

そのためには自分自身が羽ばたく力を身につけなければいけないし、自分にとって羽ばたけるような環境とは何かを知らなければいけません。

目標を達成できるように知識をつけてできることを増やしたり、副業を通して仕事のしやすい環境を実感したように自分のパフォーマンスが上がる状態とは何かを考えていきます。


本業・副業では今後も仕事をいただけるように、引き続きアウトプットを通して貢献できるように取り組んでいきます。

個人開発ではPikaPikaの機能追加を行い続けて、MAU1万を達成します。

また、新しいアプリもリリースします。

今のところ考えているのは買い物リストの共有アプリです。
現状は「買うものかご」というアプリを使っており、かなり愛用していたのですが、ユーザーの操作を阻害するほど頻繁に全画面を覆う広告が出てくるようになったり、欲しいと思っている機能がなかったりと、自分に合わない部分が出てきたので自分で作ろうと思った感じです。

自分と同居人が使えればいいのでサクッと作りたいなと思ってます。

あとは、pub.devに自分のパッケージを上げてみるつもりです。
内容はWidget系ではなく、自動ファイル生成ツールみたいなものをイメージしています。

最後に健康でいられるように運動も継続して行います!

上記全て実現できるように頑張っていきます!

以上ないぱかの2021年の振り返りと2022年の目標でした。

今年もよろしくお願いいたします!


去年の振り返り

note.com

Flutterで通信キャリア情報を取得する

概要

最近キャリア判定を行う方法について調べる機会があったので、Flutterでの実装方法についてまとめました。

開発環境

Tool Version
macOS 11.4
Visual Studio Code 1.58.2
Flutter 2.2.3
Dart 2.13.4

実装

キャリア情報を取得するパッケージを探すと下記の2つが見つかります。

(実際には他にもキャリア情報を取得できるパッケージがいくつか存在するのですが、Null safety対応がなされていなかったり、更新頻度が少ないものが多いため、以下2つを挙げました。)

pub.dev

pub.dev

telephonyはドキュメントも整っており非常に使いやすいのですが、現状Androidのみしか対応していないため、今回はcarrier_infoを使ってキャリア判定処理を実装します。

dependencies: 
  carrier_info: ^2.0.1

キャリア情報はキャリア名かMobileCountryCode(MCC)とMobileNetworkCode(MNC)の組み合わせで判定できます。

MCCは運用地域を示す3桁の番号で、日本だと440441が使用されています。

また、MNCは通信キャリアを識別する2桁の番号で00だとソフトバンク10だとNTTドコモであることが判別できます。

en.wikipedia.org

ja.wikipedia.org

carrier_infoでは上記それぞれの情報を取得することができるので、それぞれの値を比較してキャリア情報を判別することができます。

下記のようなUtilクラスを作成し、自分の持っている端末でキャリア情報を取得してみました。

import 'package:carrier_info/carrier_info.dart';

abstract class NetworkUtil {
  /// 携帯サービスプロバイダーを取得する
  static Future<String?> getCarrierName() async {
    return await CarrierInfo.carrierName;
  }

  /// ネットワーク番号を取得する
  static Future<String> getMobileNetworkOperator() async {
    // 運用地域を示す3桁の番号
    final mobileContryCode = await CarrierInfo.mobileCountryCode;
    // 通信キャリアを識別する2桁の番号
    final mobileNetworkCode = await CarrierInfo.mobileNetworkCode;
    // 公衆陸上移動体ネットワーク番号(PLMN)
    return '$mobileContryCode$mobileNetworkCode';
  }
}

これで、それぞれのキャリアごとのPLMNとキャリア名をenum等で定義して取得結果と比較すれば、どのキャリアかを判定して処理を分けたりができそうですね。

まとめ

今回はFlutterで通信キャリア情報を取得する方法についてまとめました。

あまり利用機会がないかもしれませんが、自分のように調べる機会が出てきた方の役に立てたら幸いです。

参考

qiita.com

サンプルリポジトリ

github.com