iOSDC 2021 「DateComponentsと仲良くなる」

初めに

askenの @sato-shin です。 iOSDC 2021 で「DateComponentsと仲良くなる」という題目で登壇させていただきましたので、記事としても残しておきます。

この発表をしようとしたきっかけ

弊社askenでは「あすけん」というサービスを開発しています。食事や運動などの記録を行い、生活習慣改善をサポートするサービスです。 あすけんでは朝食、昼食、夕食、間食の区分に分けて食事記録を行えるのですが、このとき1日という表現がとても大事になってきます。 この1日の表現にDate型を使っていたのですが、タイムゾーンの変更に弱く、取り扱いが難しい課題がありました。 これを解決するのにDateComponentsを利用しました。 この改善を通して、「DateComponentsは便利。もっと話題になっても良いのでは?」と思い、CfPを出すことを決めました。

DateComponentsと仲良くなる

時間の基礎

私たちはよく時間を "2021年9月19日 13時30分" というように年月日時分(+秒)を使って時間を認識することが多いと思います。 しかし、この表現方法のルールはとても複雑でコンピュータ上では扱いが簡単ではありません。 コンピュータにとって最も簡単な時間を定義する方法は、「基準点を決め、そこからの長さ」によって、時間を定義することです。

f:id:techaskeninc:20210917182709p:plain

Date型

この時間の定義をそのまま実装したクラスとして、Swift では Date型 が使われます。Date型のイニシャライザを見ると、それがよく分かります。

  • init(timeIntervalSinceNow: TimeInterval)
  • init(timeIntervalSince1970: TimeInterval)
  • init(timeIntervalSinceReferenceDate: TimeInterval)
  • init(timeInterval: TimeInterval, since: Date)
  • init() = (timeIntervalSinceNow: 0) と同義

Sinceは基準点で、TimeIntervalは基準点からの長さを表し単位は秒です。 Sinceに使える特徴的なものとして、以下のものがあります。特にUnixEpochはUnixTimeにおける基準点で、とてもよく使われます。

なお、TimeInterval は Double の alias です。

英語でDateといった場合に想像するものと違うので注意してください。Date型の正体は時間軸上の一点です。

日時計算の難しさ

Date型の表現はコンピュータにとっては扱いやすいのですが、人間にとっては扱いづらいです。 やはり私たちが日付を認識するときには、2021年9月19日 9時30分といった表現を使います。 しかしこの表現のルールは思った以上に複雑です。

  • 1年
  • 1ヶ月
    • 閏年ではない2月 = 28日間
    • 閏年の2月 = 29日間
    • 4, 6, 9, 11月 = 30日間
    • 1, 3, 5, 7, 8, 10, 12月 = 31日間
  • 1日
  • 1分
    • 閏秒が挿入されない = 60秒間
    • 閏秒が挿入される = 61秒間

年や月だけでなく、日や分の長さも固定長ではないことが分かります。さらにサマータイムタイムゾーンに依存するので、タイムゾーン特有の処理も必要になります。 これらを自前で全て網羅しつつ日時計算を行うのはあまりにも非効率です。そこで、多くのプログラミング言語では日時計算を行うものが提供されています。 SwiftではCalendar型が日時計算を担当する型として定義されています。

Date型では表現できないもの

あなたの生年月日をDate型で表現するとしたらどうなるでしょうか? 実はDate型では正確に表現することはできません。 生年月日が持っている情報は、「タイムゾーンに依存しない特定の1日」と言えるでしょう。 このタイムゾーンに依存しないというのが厄介です。 たとえば、日本の1日とニューヨークの1日というのはタイムゾーンによって、「ずれ」があります。 Date型は時間の点なので、この「ずれ」を表現することはできず、生年月日を正確に表現できません。

DateComponents型

そこで、もっと私たちが日常的に使っている日付の形式で表現できる型があると便利です。 この日付の形式で表現できる方というのがDateComponents型です。 DateComponents型は日時の構成要素の集合です。 この構成要素の数が多いため、DateComponentsのイニシャライザの引数は16個と多くなっています。

init(calendar: Calendar?, timeZone: TimeZone?, era: Int?, year: Int?, month: Int?, day: Int?, hour: Int?, minute: Int?, second: Int?, nanosecond: Int?, weekday: Int?, weekdayOrdinal: Int?, quarter: Int?, weekOfMonth: Int?, weekOfYear: Int?, yearForWeekOfYear: Int?)

全てoptionalとなっているため一度に全て利用しなければいけないわけではありません。表現したい時間に必要なものだけを指定します。 また、要素一つ一つは簡単です。

  • calendar: Calendar? = カレンダー(暦)
  • timeZone: TimeZone? = タイムゾーン
  • era: Int? = 時代、年号
    • グレゴリオ暦では 0 が紀元前を、1 が西暦を表す
    • 和暦では、0 が大化を、249 が平成を、250 が令和を表す
  • year: Int? = 年
  • month: Int? = 月
  • day: Int? = 日
  • hour: Int? = 時
  • minute: Int? = 分
  • second: Int? = 秒
  • nanosecond: Int? = ナノ秒
  • weekday: Int? = 曜日
  • weekdayOrdinal: Int? = その曜日が何番目か
    • たとえば、2021年9月19日は第日曜日
  • quarter: Int? = 四半期
  • weekOfMonth: Int? = その月の何週目か
    • たとえば、2021年9月19日は第4週目
  • weekOfYear: Int? = その年の何週目か
  • yearForWeekOfYear: Int? = weekOfYear計算用の年

DateComponents型の3つの表現

DateComoponents型は日時の構成要素の集合であり、実際にどのような意味を持つかはプログラムによって異なります。 意味のパターンとしては、大きく分けて3つあります。

  • 日時を表す
  • 量を表す
  • パターンマッチングを表す

日時を表す

この表現は、私たちがよく利用する "2021年9月19日 13時30分" などといった日時を表現することを目的とし、Date型へと変換可能な表現になります。

let today = DateComponents(calendar: gregorianCalendar, year: 2021, month: 9, day: 19, hour: 13, minute: 30)

DateComponents型では、意識しないものについては指定しなくて良いので、「Date型では表現できないもの」のところで挙げた生年月日を正しく表現することができます。 たとえば、私の誕生日は西暦1990年10月18日なのですが、これをDateComponents型で表現すると以下のようになります。

let birthday = DateComponents(calendar: gregorianCalendar, year: 1990, month: 10, day: 18)

ここで着目して欲しいのが、TimeZoneを指定していないということです。 生年月日が表したい「タイムゾーンに依存しない特定の1日」というものを正確に表現できています。

量を表す

この表現では時間の長さを表します。時間の量を表す型としてTimeInterval型がありますが、これは単位が秒しか扱えませんでした。 DateComponents型を使うことで、年、月、日、時、分といった長さも正しく表現できるようになります。 この量の表現と、Calendar型の日時計算関数を利用して日時計算を行うことができます。 たとえば、今から一ヶ月後を計算する場合には以下のように書けます。

let oneMonth = DateComponents(month: 1)
let oneMonthLater = calendar.date(byAdding: oneMonth, to: Date())

パターンマッチを表す

毎朝、決まった時間に目覚まし時計を設定している人は多いと思います。 この表現はそんなときに利用できます。 たとえば、朝の8時30分に通知したい場合のUserNotificationTriggerを作りたい場合には以下のように書けます。

let wakeUpAlertTime = DateComponents(hour: 8, minute: 30)
let trigger = UNCalendarNotificationTrigger(dateMatching: wakeUpAlertTime, repeats: true)

Tips

DateComponents型がここまで説明したどの意味を持つかはプログラムによって異なります。 たとえば、コードを以下のような切れ端で見たときに、

DateComponents(hour: 12)
  • 12時間という「量」の表現
  • 12時という「パターンマッチ」の表現

このどちらの表現なのかは察することはできません。プログラムの前後の文脈から判断するしかありません。 ですので、作っているアプリケーションでどのような表現が欲しいのか?を分析し、それに合うようなラッパークラスを作るのをお勧めします。 たとえば、時間の長さが必要であるといった場合には以下のようなラッパークラスを作るだけでも、どんな表現をしたいのか?が分かりやすくなります。

struct DateLength {
    var value: DateComponents
}

最後に

Date型は原始的な時間の表現であり、単純なケースではとても扱いやすいです。 しかし、Date型では表現しきれなかったり、複雑になるケースも多くあります。 DateComponents型がその問題を解決してくれる可能性があります。 実際に私は開発内で、DateComponents型を使うことでコードをスッキリさせることができました。

「これまでDate型しか使ったことなかったよ」という人は、これを期にDateComponents型を使った方が良いケースがないかどうか考えてみてください。

We are hiring!

askenでは、iOSエンジニアを募集しています! https://www.wantedly.com/companies/asken

なぜエンジニアはマネージャーになるのに不安を覚えるのか

こんにちは。askenでエンジニアリング戦略や組織づくりを担当しているやすにしです。

マネジメントを中心にしておりまして、せっかくなのでブログでもマネジメントについて書いてみますね。

私はこれまでVPoEとしてエンジニア組織のマネジメントや、様々な会社でマネージャー向けにコーチン1 をやってきました。そこで接してきたエンジニアリングマネージャーに共通しているのは「キャリアに悩んでいる」ということです。
例えばこのようなことです。

  • コーディングをしなくなり、技術的に取り残されて、エンジニアとしてやっていけなくなる感じがする
  • 自分でやらないから成果が見えない。やっている感じがしない。
  • マネジメントをどうやればいいか、どう学べばいいかわからない。
  • マネージャーのキャリアで自分は定年(?)まで生きていけるのか?

共通点は、色々理由を言葉にしているものの、どれもしっくりきている感じではなく、「なんとなく不安」という感じでした。私自身は、組織に課題感を感じることが多い人種だったので、以前よりマネジメントにも興味を持ち色々やってきたものの、同じような不安を感じることがありました。だからこそ、今はプロダクトづくりにも時間を割いていることは確かです。

そこで、実体験や他のエンジニアリングマネージャーのお話から、私なりになぜ不安なのかを整理してみました。

エンジニア(プレイヤー)→マネージャーは何が変わるのか?

もともとエンジニア(あるいはプレイヤー)だった方がマネージャーになることがほとんどだと思いますが、エンジニア→マネージャーになると何が変わるのでしょうか。

一般的には「リーダーシップ」と「マネジメント」が求められると言われています。 ふむふむ、そうだよねと思いつつ、リーダーシップとはなんでだと思いますか?マネジメントはなんだと思いますか?

答えは無限にあり、唯一の正解はない世界ではありますが、私なりに定義をしてみました。

f:id:techaskeninc:20210908113504p:plain

リーダーシップ:一歩踏み出す

リーダーシップは、一部の人に求められることではなく、すべての人に求められることです。戦略を作り組織の先頭に立つような大きなこともそうですが、シーンとしている会議で最初に発言する、会議でホワイトボードの前に自ら立つなども大事なリーダーシップです。それぞれに共通的な行動とは何かを言語化してみた結果、「一歩踏み出す」を選んでみました。

マネジメント:チームを成果に導く

マネジメントは、自分で手を動かして成果を出すのではなく、チームが成果を出せる状態にすることだ、という意味でこの言葉を定義してみました。ドラッカーエッセンシャル版マネジメント

組織をして高度の成果をあげさせることが、自由と尊厳を守る唯一の方策である。
その組織に成果をあげさせるものがマネジメントであり、マネージャーの力である。

と言っています。

答えがわからない上に、やったことがないことを求められる

マネージャーになり、リーダーシップとマネジメントを求められた時に、この事実を目の当たりにします。

f:id:techaskeninc:20210908113815p:plain

つまり、答えがないことに答えを出し、自分がやらずに成果を出すことをやらなければなりません。そして、エンジニア(プレイヤー)としてやってきた 仕事のやり方を大きく変える 必要があり、このように戸惑います。

f:id:techaskeninc:20210908113958p:plain

答えがわからない」上に、プレイヤー経験のみの方は「やったことがない」ことをやらざるを得なくなるのです。これは戸惑うのが当たり前です。みんなそうです。私も未だに変わりません。

これが、プレイヤーからマネージャーになったときに戸惑ってしまう理由だと私は考えています。

答えがない事実を受け入れ、学び続けること

じゃあどうすればいいか。私が学んできたリーダーシップやコーチング経験から考察してみます。

まず大事なのは「答えがない事実を受け入れる」ことです。すべてのことに答えはありません。人によって違う認識があり、違う選択があるだけです。つまり、自分で答えを出すしかありません。大きい組織や影響力が大きい意思決定においてはなおさらです。いくら情報を集めても判断の決め手はなく、決して断つ、つまり決断が必要な場面ばかりです。リーダーシップを発揮するというのはそういうものです。それを受け入れ、自分で考え、決めていくしかありません。個人の人生における選択も答えがない問いの連続なので、誰しも必要なことかもしれません。

答えがないことに向き合う上で、もう一点大事なのは、「学び続けること」です。わからない、できない自分を受け入れ、どんなこと、どんな人からも学ぶ。そして、仮説と検証とふりかえり。つまりアジャイルな人になるということです。

大人の学びとは「悦び」であり、「痛み」でもある と言われています。わからないことに対峙すると、ときに居心地の悪いこともあります。でもそこに向き合い乗り越えていくことで、「わかった!」「できるようになった!」という悦びを得ることができます。 もしこのような学びに対峙できれば、視野が広がり、人間的な成長をすることができるなあと個人的に実感しています。マネージャーをやった結果の学びなのに、エンジニアとしての視野も広がり、技術に対する景色も変わってきます。

エンジニアとマネージャーの共通点

では、エンジニアとマネージャーはぜんぜん違うから、エンジニアのスキルは活きないのか、というと僕は全くそう思っていません。 私が考える共通点を2つ挙げてみます。

①エンジニアリングもマネジメントも課題解決である

実際のところ、ソフトウェア開発上の問題の多くは、技術的というより社会学的なものである

私の好きな ピープルウェア(トム・デマルコ) の一節です。現実的にはそんなことばかりです。マネジメントは社会学的な課題解決をしていくとも言えます。同時に、私が出会ってきたエンジニアの多くは、課題解決が大好きです。その時点でエンジニアはマネジメントに向いているのではないでしょうか。

②すべてがモデリング(設計)である

私はモデリングが大好きで、何をするときもモデルにして考えてしまうのですが、これはかなりマネジメントに活きているなと実感しています。

ドラッカーはマネジメントを

組織に成果をあげさせるための道具、機能、機関

と定義しています。道具、機能、機関を作ること自体、モデリング(設計)です。全体を俯瞰し、目標を作り、制度を作り、組織を作り、チームを作る。そこにどういうメッセージを投げかけ、働きかけて変化をつけていくかもモデリング。1on1で話すときは相手のメンタルモデルを理解して問いを投げかけます。だからマネジメントをしていく際には、常にモデリングだ!と思ってやるようにしています。

パワーアップしてエンジニアに戻ることができる

私自身はエンジニアリングマネージャーをやりつつ、コーディングも続けながらプロダクトマネジメントに足を踏み入れているのですが、私の知り合いでも エンジニア専任に戻った方 を何人も知っています。彼らを見ていて思うのは、パワーアップしてエンジニアをやっているなと感じます。例えばこんな部分です。

  • リーダーシップを発揮する経験をしたことで、マネージャーや経営層が何を考えて意思決定しているかその意図も読み取れる
  • マネジメントを経験したことで、今のチームで自分はどんな言動をすると成果につながるかを意識しながら動ける
  • 目の前のタスクや事象だけに惑わされず、全体を俯瞰した上で、最適な行動を選択できる
  • 言葉にして伝える大切さを学んだことで、チームとのコミュニケーションやコーディングに活きる

などなどです。マネージャーでの経験は確実にエンジニアでも活きます。面倒なことも多いことは否定しませんが、チームのパフォーマンスに大きく影響しますし、全然別の景色が見えるし、人間的にも成長させてもらえる価値ある役割だと思います。そして、マネージャーになってもエンジニアに戻れます。これは絶対。キャッチアップできます。

一方で、askenではスペシャリストのキャリアも用意しています

とはいえ、人には向き不向きや好き嫌いがあります。 エンジニアリングが好きで、エンジニアとして深く広く活躍できる方は、ずっとやっていたほうが良いに決まっています。なので、askenではスペシャリストでも活躍できるキャリアを用意しています。

興味のある方は是非 ご連絡 くださいませ。


  1. freeeさんやSansanさんで、マネージャー向けに今もコーチングをやらせていただいています

あすけんSlackの人気絵文字ランキング

はじめまして!
askenのユウマと申します😊

shoku-pan🍞という名前でTwitterをやっています。
askenでは、MLエンジニアとして働いてます。
主に、画像処理や自然言語処理、データサイエンス周りを担当しています。
また、業務効率化のためのツールの作成や、ナレッジ共有のための社内勉強会を開いたりもしてます。
社外では、kaggleやatmaCupに参加したり、データサイエンティストの方達ともくもく作業したりと、ゆるゆると活動しています。

さて、先日以下のTweetが弊社のエンジニアの間で話題になりました。

最近よく目にする(気がする)この動く棒グラフは、「bar chart race」と呼ばれるものらしいですね。
Slack APIで、社内Slackの絵文字データを集計し、データを可視化するツールを使えばできるようです!
僕自身、Slack APIを使った経験はあまりなく、「Slackのデータを色々と分析できたら面白いだろうな」と思っていました。

弊社askenのSlackでもやってみたので、この記事で紹介します😊

目次

  • はじめに
  • 目次
  • 全体の流れ
  • セットアップ
    • Slack Appの作成
  • 実装
  • Bar chart raceの表示
  • 🎉結果発表🎉
  • まとめ
  • 参考資料

全体の流れ

まず、全体の流れは以下になります。

  • セットアップ
    • Slack Appの作成
  • 実装
    • Slackからメッセージ履歴を取得
    • 絵文字データを抽出・集計
    • csvファイルに出力
  • 可視化
    • Flourishにcsvファイルをインポート
    • bar chart raceの表示

セットアップ

Slack Appの作成

まず、Slackからデータを取得するために、Slack Appを作成します。 Slack Appの作成方法は、こちらの記事
Slack API | Web API から Slack App 経由で チャンネル履歴を取得する
を参考にしました。
ここで、Slack APIにどこまで権限を与えるか(スコープ)を決める必要があるのですが、今回は

  • channels:history
  • reactions:read

を指定しました。
※OAuth & Permissions > Scopes > User Token Scopes で設定できます。
スコープを指定してSlack APPを作成し、Slackのワークスペースにインストールできれば、いよいよ実装です!

実装

今回、言語はPython、環境はGoogle Colaboratoryを使用しました。
それでは、まずは設定です。

# Settings
TOKEN = '[token ID]'
CHANNEL = '[channel ID]'
NUMDAYS = 365 # データを取得する日数

ここで、[token ID]には
OAuth & Permissions > OAuth Tokens for Your Workspace > User OAuth Token
に記載されている文字列を指定します。
[channel ID]の確認方法は以下が参考になります。
Slack — APIに使う「チャンネルID」を取得する方法
※なお、これらは重要な情報なので、取り扱いに注意して下さい

NUMDAYSには、過去何日分のデータを取得するかを指定しています。
今回は1年分となる365日を指定しました。
※この値が大きいほど、データの取得には時間がかかります。

あらかじめ、必要なライブラリもインポートしておきます。

# Import libraries
import pandas as pd
import requests
import datetime

次に関数を定義します。

# Functions
def get_conversations_history(oldest_date, latest_date):
    """
    メッセージ履歴を取得する
    """
    url = "https://slack.com/api/conversations.history"
    headers = {"Authorization": "Bearer "+TOKEN}
    params = {
    "channel": CHANNEL,
    "limit": NUMDAYS,
    "oldest": oldest_date,
    "latest": latest_date,
    }
    response = requests.get(url, headers=headers, params=params)
    return response.json()
def count_emoji(conversations_history, df, date):
    """
    メッセージ履歴から絵文字をカウントする
    """
    for i in conversations_history['messages']:
        if 'ts' in i and 'reactions' in i:
            ts = i['ts']
            ts = datetime.datetime.fromtimestamp(int(ts.split('.')[0])) # unix時刻から標準時刻へ変換
            ts = ts.date() # 日付部分のみ取得
            reactions = i['reactions']
            for reaction in reactions:
                reaction_name = reaction['name']
                reaction_count = reaction['count']
                if reaction_name not in df.index:
                    df.loc[reaction_name] = 0
                df[date][df.index==reaction_name] += reaction_count

メインの処理は以下になります。

# Main
# 絵文字データをdataframeに格納
df=pd.DataFrame()
today = datetime.datetime.today()
# 今日の日付からNUMDAYS日前までのデータを取得。
# reversedで、日付の古い順に並び替え
for index, i in enumerate(reversed(range(0, NUMDAYS))):
    date_new = today - datetime.timedelta(days=i)
    date_old = today - datetime.timedelta(days=i+1)
    # Slack APIの時刻parameterはunix timeなので変換
    date_new_unix = date_new.timestamp()
    date_old_unix = date_old.timestamp()
    if index == 0:
        # df[date]に各絵文字の集計結果を格納する。カウント初日は0
        df[date_new.date()] = 0
    else:
        # df[date]に各絵文字の集計結果を格納する。前日の集計結果に足していく。
        df[date_new.date()] = df[date_old.date()]
        conversations_history = get_conversations_history(oldest_date=date_old_unix, latest_date=date_new_unix)
        if conversations_history['ok']: # responseが正しく返ってきた場合のみ処理実行
            count_emoji(conversations_history, df, date_new.date())
    
df # 結果確認

実行すると、以下のようなDataframeが出力されるはずです。
Slackの絵文字データがちゃんと集計されていますね!

f:id:techaskeninc:20210826174543p:plain

1日毎だとデータ量(カラム)が多すぎるので、1週間ごとに集計し直しました。
※カラムが多すぎると、この後Flourishにインポートしたときに全てのデータを表示することができませんでした。。

# Modify dataframe
df_result = df.copy()
df_weekly = pd.DataFrame()
for i in range(2, len(df_result.columns)):
    if i % 7 == 0:
        df_weekly[df_result.columns[i]] = df_result[df_result.columns[i]]
df_weekly

実行すると、以下のように出力されます。
今度は絵文字データが1週間単位(7日ごと)で集計されていますね!

f:id:techaskeninc:20210826174702p:plain

最後に、Dataframeをcsvファイルに出力しましょう。

# Output
df_weekly.to_csv('emoji_ranking_weekly.csv')

Bar chart raceの表示

ここまでで、Slackのデータを収集して絵文字データを集計し、結果をcsvファイルに出力するところまでできました。
では、このデータを使ってBar chart raceを表示してみましょう。
今回、Bar chart raceを表示するにあたっては、Flourishというサービスを使用しました。
こちらにアクセスしてください。
チュートリアルに従ってcsvファイルをupすれば、bar chart raceが表示されるハズです😉

🎉結果発表🎉

それでは、askenのSlackチャンネルの絵文字ランキングを発表します!
今回集計したデータは以下になります。

  • 全ての絵文字を集計(デフォルト絵文字およびカスタム絵文字)
  • generalチャンネル
  • リアクションとして使用された絵文字に限る(本文中で使用された絵文字は対象外)
  • 集計の期間は直近までの1年間
  • 上位15位を表示

直近1年間での集計の最終的なランキングは以下になりました🎉

順位 絵文字 絵文字名
🥇 tada
🥈 bows
🥉 done
4位 +1
5位 ok_hand
6位 ultra_fast_parrot
7位 asken2
8位 miki
9位 heart
10位 odaizini
11位 man-gesturing-ok
12位 woman-bowing
13位 nyan_parrot
14位 muscle
15位 sob

1位は🎉でした!新しいサービスのリリースやメディアでの紹介、また新入社員の紹介など、おめでたいことやテンションのあがる投稿に対するリアクションとして多く使われていました。
2位のは、「ありがとう」と感謝の気持ちをつたえる際に、3位のは依頼された作業を完了したときに使用されているようです。
また、7位には弊社サービス「あすけん」のロゴが、8位にはそのキャラクターの未来さんがランクインしていました。
これら2つはカスタム絵文字で、askenらしさがよく出た結果となりました😊

まとめ

いかがでしたか?

今回は、弊社askenのSlackの絵文字データを集計して、bar chart raceを表示してみました。
Slack APIを使用して、Pythonでデータを抽出・集計し、Flourishというサービスを使用することでつくることができます。

みなさんの会社でもやってみてはいかがでしょうか?
盛り上がること間違いなしだと思います!
ぜひ、皆さんの会社の絵文字ランキングも教えて下さいね

参考資料

自動化に対する取り組み

こんにちは。システム部の大澤です。 普段は北米版あすけんのiOSアプリを開発しています。

昨年の9月に入社して、もうすぐ、1年経とうしています。 iOSアプリの開発を担当し、1日の中でもたくさんの作業をしています。 その中で日々の作業の一部を自動化してきました。 その取り組みについてまとめました。 今回はとくにiOS開発以外にも活用できそうなものを中心にしました。

CI環境の整備

  • Bitriseを積極的に活用しました。
  • 毎回手動で作業するのは大変なので何度も作業するものはCIに任せました。

主な実行タスク

Task Trigger
ライブラリのアップデート 毎週火曜日の朝に1度、実行している
Dangerの実行 Pull Reqeustにpushしたとき
Unit Testの実行 Pull Reqeustにpushしたとき
git-pr-releaseを実行する developにマージしたとき
ライブラリのライセンスの更新チェック developにマージしたとき
Staging環境用のバイナリをアップロード developへpushしたとき
本番用のバイナリをApp Store Connectへアップロード masterにpushしたとき

Danger

  • Dangerとは
    • CIで実行して、Pull Requestのコードを解析して、ルールに合わせて、コメントをしてくれるツールです。
    • danger/danger
  • 主なルール
    • WIPがついている
    • Pull Requestにアサイン済みかのチェック
    • Merge可能か
    • ファイルがソートされているか
    • 作業内容に合わせて、GitHubのlabelを付与する
    • スペルミスがないかどうか
      • こちらは後ほど詳しく記載します
    • すべてパスするとLGTM画像が投稿される
  • 導入するとレビューで細かい指摘をしなくなり、本質的な部分を集中して、レビューすることができるようになりました。

f:id:techaskeninc:20210728151411p:plain

git-pr-release

  • x-motemen/git-pr-release
  • masterへマージする際にどの機能をマージしようとしているか一覧で把握できます。
  • Pull Reqeustのsummaryにリストで表示されます。
  • リグレッションテスト時に優先的にチェックする箇所を把握しやすくなった。
  • GitHubのリリースノート作成時にこのリストをそのまま再利用することもできます。

f:id:techaskeninc:20210728151506p:plain

cspell

  • streetsidesoftware/cspell
  • スペルミスをチェックするツールです。
  • 自分だけではスペルミスをすべて発見するのは難しいです。ツールを導入し、レビュー時にスペルミスをチェックする必要がほぼなくなりました。
  • Dangerと一緒に使うことでPull Reqeust時に気がつくことができる。
  • 導入段階ですでにコードにあるスペルミスを直すのが大変でした😅

App Store Connectの審査状況の通知

  • 審査状況の通知はメールやApp Store Connectのアプリで受け取ることができますがチームのメンバー全員がその環境を設定するのは大変です。
  • こちらの記事を参考に導入しましたiOSアプリの審査状況変更を、Slackに自動通知する(GAS + Slack Webhook)
  • 申請、リジェクト、リリースの通知を自動でSlackに投稿するので審査状況のチェックという作業がなくなりました。

f:id:techaskeninc:20210728151557p:plain

意識したこと

  • 導入段階で他のプロジェクトでもすぐに導入できる形にしておく。
    • ドキュメントは最小限にして、インストールや実行コマンドは手順をスクリプトにしておく。その結果、手軽に試すことができ、新しく関わる人に説明する時間を削減できる。
    • Makefileシェルスクリプトを活用して、よく使うコマンドはまとめた。
  • とりあえず試してみる。
    • 試してみて、必要だとわかることが多くありました。 実際に導入してみましたが、活用されず、廃止されたものもあります。

今後やってみたいこと

  • 今後は、Swaggerのようなドキュメントからコードを自動で生成するツールなどを導入して、実装コストの削減をやっていきたいです。その仕組みをiOS以外にも展開していきたいです。

まとめ

入社して、約1年でやってみたことをまとめてみました。一度導入してしまえば、長期的に作業時間の削減に貢献します。 さらに、iOS開発だけでなく、他の開発でも使えるものを積極的に導入できました。 まだ、自動化できる作業は残っているので今後も挑戦していきたいです。 askenでは、一緒に働いてくれるiOSエンジニアを募集しています。少しでも興味を持っていただけたら、ぜひ採用情報をご確認ください。

askenテックブログはじめます!

皆さん、はじめまして〜!
株式会社askenのシステム部にて部長をしている服巻です。


コロナのワクチン接種を約1ヶ月後に控え、「接種後も全然平気だよ」と「めっちゃ腕痛くなるよ」という接種した社内メンバーの声に気持ちを翻弄されている今日この頃です。

 

さて、今日はそんな僕のほうから告知があって本記事を書いているわけですが、何かというとaskenエンジニアによる公式ブログを始めるよ!って告知ですー!

 

その記念すべき最初の記事ということで、弊社サービスの紹介を少し。
弊社は、食事改善アプリ「あすけん」を国内外に展開・運営しています。

「ひとびとの明日を今日より健康にする」をミッションとし、ユーザーへ提供する価値を最大限にするべく、日々、様々な課題に対してチームで果敢にチャレンジしています。

 

思い返せば8年前の11月、冬の足音が聞こえてきそうな中、そのaskenに僕は入社しました。当時、エンジニアは僕だけの1人システム部でしたが、今では優秀で個性豊かな仲間たちが集まってくれて、12名の愉快な仲間たちになりました。(ホント嬉しい!)


メンバーが増えるたびに新たな価値観が混ざり芽生え、各人、各チームが主体的に学ぶ姿勢をもって成長してくれる文化ができつつあります。このブログでは、そんな彼らの取り組みを少しでも周りに知ってほしい!へ〜って思ってほしい!ときに笑ってもほしい!と個人的に思っています。


組織的には、このブログを通じてaskenエンジニアが日々どんなことに取り組んでいるかを皆さんに少しでも知ってもらえる機会になればいいなと思っていますし、記事にすることによって各人がそれぞれのテーマについてより深い学びに繋がってくれることも期待してたりします。

 

さてさて、今後どんなテーマで発信されていくのやら楽しみでしかありません!!
皆さんも一緒に「askenテックブログ」を楽しみにしてくれる事を願っています!!!