RailsConf 2018に参加してきました

こんにちは。
Railsエンジニアの大場です。

2018年4月17日(火)~4月19日(木)に開催されました RailsConf 2018@Pittsburgh に参加してきました。

個人的に面白かったセッションや会場の雰囲気を書こうかなと。

 

RailsConfとは

1年に1度のRailsカンファレンスで、今年は4/17(火)〜4/19(木)の3日間で開催されました。

過去にはシカゴやポートランドで開催されていた模様。

続きを読む

MF KESSAI Tech Blog新設のおしらせ

MF KESSAIの篠原(@shinofara)です。

株式会社マネーフォワードのグループ会社として、2017年3月16日にMF KESSAI株式会社を設立して1年が過ぎました。

0から会社設立する忙しさもあり、なかなかブログに登場する事は出来ませんでしたが、過去に以下の2記事を公開させていただきました。

そしてこの度、MF KESSAIでは1年間お世話になった当ブログを離れて、
MF KESSAIとしてTech Blogを公開する事になりました。

https://tech.mfkessai.co.jp/

新設後第一弾として「 MF KESSAIの開発文化 」と題して、MF KESSAIのエンジニアmakitonが公開しています。是非、ご覧ください。

今後は、MF KESSAIのものづくりに関わるエンジニア・デザイナから、それぞれの観点で記事を公開していきます。

本家エンジニアブログは勿論の事、 MF KESSAI Tech Blog もよろしくお願い致します。

続きを読む

Androidアプリのデバッグメニューを作ろう

こんにちは。
Androidエンジニアの@syarihuです。

Androidアプリを作っていて、エンドポイントを切り替えたり、ユーザの状態1を変えたりしたいときありますよね。

エンドポイントの切り替えは、ビルドのやり直しや各環境のapkをインストールするなど手間が発生してしまいます。
アプリをビルドし直したりせずに、エンドポイントなどを切り替えられたら嬉しいですよね。

そこで今回は debug-alter というライブラリを利用して、デバッグ時のみ利用可能なデバッグメニューを作成する方法を紹介します。

 

debug-alterとは

debug-alter は、Javaに対するアスペクト指向プログラミングのための拡張である AspectJ を利用してデバッグ時のメソッドの返り値を任意の値に変更できるように作られたAndroid向けのライブラリです。

debug-alterの詳細については開発者本人が書いたQiitaがあるので、そちらを参照してください。

コードを変更せずにデバッグメニューでAndroidアプリの動作を変更する – Qiita
https://qiita.com/takahirom/items/4067e7bb0c3f614dc749

 

debug-alterの良いところ、良くないところ

私が個人的に感じている debug-alter の良いところ・良くないところは下記の通り。

良いところ

  • @DebugReturn をつけたメソッドを任意の値に差し替え可能
  • プロダクションコードにはアノテーションをつけるだけでよいため、デバッグでプロダクションコードを汚さなくて済む
  • OSSで開発されている
  • Jake Wharton氏が作り、わりと有名だった Hugo というライブラリでもAspectJの仕組みを利用していたという安心感

良くないところ

  • 差し替え対象のメソッド名を自分で書かないといけない
    • 本当は自動生成とかしてくれると良さそう
  • kaptと相性が悪い
    • これについては回避方法があるので次で説明

 

debug-alterを導入する

Money ForwardのAndroidアプリへのdebug-alterの導入を例に説明していきます。

build.gradleの設定

app/build.gradleに次のように設定します。

 buildscript {
     dependencies {
        classpath("com.github.takahirom.debug.alter:plugin:${debug_alter_version}") {
            exclude module: 'kotlin-gradle-plugin'
        }
}

apply plugin: 'com.github.takahirom.debug.alter'

 dependencies {
    // Debug Alter Annotation
    implementation "com.github.takahirom.debug.alter:annotation:${debug_alter_version}@aar"
}

pluginの適用をした時点でdebug-alter自体は利用できます。

しかし、複数のFlavorが存在する場合はFlavorを切り替えるとアノテーションが参照できなくなってしまいます。別途アノテーションのみが含まれるライブラリを導入することで、Flavorを変更してもアノテーションが参照できるようにしています。

また、debug-alterはkaptと非常に相性が悪いです。kaptを利用しているアプリ2で、アプリのKotlinバージョンとdebug-alterのKotlinバージョンに差異があると、kaptのビルドタスクでエラーが発生します。

実際に起きた例として、Money ForwardのAndroidアプリのKotlinのバージョンを上げたところkaptのビルドタスクでエラーが発生してビルドが通らなくなりました。

kaptのビルドタスクでエラーが発生するのを回避するため、classpathの部分にexclude module: 'kotlin-gradle-plugin'を追記しkotlin-gradle-pluginを除外することで、debug-alterのkotlin-gradle-pluginに影響されないようにしました。

デバッグ用のApplicationクラスを作成

デバッグ時に差し替える値をセットする処理とデバッグメニューを開くための通知を送信する、デバッグ用のApplicationクラスを作成します。

class DebugApplication : CustomApplication() {
    override fun onCreate() {
        // 差し替え用のアイテムをセットしておく
        resetDebugAlterItems()
        super.onCreate()
        // デバッグメニューに遷移するための通知を表示
        showNotification()
    }
     <application
        android:name="com.moneyforward.android.DebugApplication"

独自のApplicationクラスが存在していてonCreateで何らかの初期化処理を行っている場合は、onCreateの直前に差し替え用のアイテムをセットすることで、値を差し替えたいメソッドがonCreate内で呼び出されていても値が差し替わるようになります。

またデバッグメニューを開くための通知を送信することで、プロダクトの画面に影響することなく通知からデバッグメニューへ遷移できるようにします。

 

差し替え対象のメソッドにアノテーションをつける

debug-alterでは@DebugReturnがついたメソッドが任意の値を差し替える対象になるため、値を差し替えたいメソッドにアノテーションをつけます。

たとえば、APIのエンドポイントを返却するgetApiEndPointというメソッドをデバッグ時に任意の値に差し替えたい場合は次のように実装します。

@DebugReturn
public static String getApiEndPoint() {

プロダクションコードにはこのアノテーションを実装するだけでよいので、とてもよいですね。

デバッグ用の値に差し替える

debug-alterでは@DebugReturnがついたメソッドを呼び出した際に、次の条件に一致する場合にメソッドの通常の返り値ではなくDebugAlterItemのgetメソッドから取得した値を返却します。

  • @DebugReturnがついているメソッドのkey3とDebugAlterのインスタンスにセットされているDebugAlterItemのkeyが一致している
  • DebugAlterItemのisAlterメソッドの返り値がtrueである

上記の判定に利用するDebugAlterItemのリストを簡単に生成できるようにするため、Helperクラスを作成します。
まずは、Helperクラスの中にメソッドのkeyとメソッドが返却する型を定義したenumクラスを作成しましょう。

class DebugAlterHelper(private val context: Context) {
    private enum class AlterItemInfo(
            val keyResId: Int,
            val alterItemType: AlterItemType
    ) {
        API_END_POINT(R.string.key_api_end_point, AlterItemType.STRING),
        PREMIUM(R.string.key_premium, AlterItemType.BOOLEAN)
    }

    private enum class AlterItemType {
        STRING,
        BOOLEAN
    }
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="key_api_end_point">getApiEndPoint</string>
    ...

差し替える値はPreferenceに保存します。Preferenceのkeyでもそのまま扱えるようにstringリソースに記述し、Preferenceに保存する型はAlterItemTypeという別のenumクラスを作成して、AlterItemInfoのプロパティとしてセットしておきます。

次に、DebugAlterItemのオブジェクトを生成するメソッドを用意します。

class DebugAlterHelper(private val context: Context) {
    ...
    private fun getStringItem(@StringRes keyResId: Int): DebugAlterItem<String> {
        val preference = PreferenceManager.getDefaultSharedPreferences(context)
        return object : DebugAlterItem<String>(context.getString(keyResId)) {
            override fun isAlter(): Boolean = preference.contains(key)
            override fun get(): String? = preference.getString(key, null)
        }
    }
    ...

DebugAlterItemのコンストラクタは引数としてkeyを受け取ります。
リソースIDを元に取得した文字列をkeyとしてDebugAlterItemのオブジェクトを生成します。

isAlterメソッドはPreferenceに対象のkeyが存在する場合にtrueを返却することで、何もない場合は通常のメソッドを実行します。
getStringItemメソッドはPreferenceに保存している値がStringだった場合に利用するメソッドです。もしPreferenceがString以外の型の場合は、その型のDebugAlterItemを返却するメソッドを別途作成する必要があります。

たとえばBooleanの場合は、DebugAlterItemを返却するメソッドを作成します。作成したメソッドを利用して、enumを元にDebugAlterItemのリストを返却するメソッドを作成しましょう。

class DebugAlterHelper(private val context: Context) {
    ...
    fun getAlterItemList(): List<DebugAlterItem<*>> {
        return arrayListOf<DebugAlterItem<*>>().apply {
            AlterItemInfo.values().forEach {
                when (it.alterItemType) {
                    AlterItemType.STRING -> add(getStringItem(it.it.keyResId))
                    AlterItemType.BOOLEAN -> add(getBooleanItem(it.it.keyResId))
                }
            }
        }
    }
    ...

AlterItemInfoが持っているAlterItemTypeを利用して、対象の型のDebugAlterItemが返却されるようにします。
作成したgetAlterItemListメソッドを利用して生成したリストを、DebugAlterのsetItemsメソッドに渡します。

    private fun resetDebugAlterItems() {
        val debugAlterHelper = DebugAlterHelper(this)
        DebugAlter.getInstance().setItems(
                debugAlterHelper.getAlterItemList()
        )
    }

これで @DebugReturn がついているメソッドを実行した際、条件が一致すればPreferenceにセットした値が返却されるようになりました。

 

デバッグメニューを作る

デバッグ時に差し替えたい値を設定するメニュー画面を作成し、デバッグ用のAndroidManifestに追加します。

     <application
         android:name="com.moneyforward.android.DebugApplication"
         ... >
        <activity
            android:name="com.moneyforward.android.DebugMenuActivity"
            android:label="デバッグメニュー" />
    </application>

最後に、作成したデバッグメニューを通知がタップされたときに起動するように実装します。

 

デバッグメニューを使ってみる

Money ForwardのAndroidアプリにデバッグメニューを実装したので、実際にプレミアム状態をデバッグメニューで切り替えてみます。

通知からデバッグメニューを起動し、設定を変更後すぐに反映されているのがわかりますね。
これでデバッグメニューの完成です!

 

まとめ

debug-alterを利用することで、プロダクションコードにはアノテーションをつけるだけでデバッグ時に値を差し替えられるようになりました。

デバッグメニューが実装されたアプリをインストールしてもらうことで、アプリエンジニアの手間を軽減するだけでなく、サーバーサイドのエンジニアが各環境のアプリを確認したい際にも役に立つことでしょう。
ぜひ活用していきましょう。

 

最後に

マネーフォワードでは、エンジニアを募集しています。
ご応募お待ちしています。

【採用サイト】
マネーフォワード採用サイト
Wantedly | マネーフォワード

【マネーフォワードのプロダクト】
自動家計簿・資産管理サービス『マネーフォワード』
Web
iPhone,iPad
Android

「しら」ずにお金が「たま」る 人生を楽しむ貯金アプリ『しらたま』
Web
iPhone,iPad

ビジネス向けクラウドサービス『MFクラウドシリーズ』
バックオフィス業務を効率化『MFクラウド』
会計ソフト『MFクラウド会計』
確定申告ソフト『MFクラウド確定申告』
請求書管理ソフト『MFクラウド請求書』
給与計算ソフト『MFクラウド給与』
経費精算ソフト『MFクラウド経費』
入金消込ソフト『MFクラウド消込』
マイナンバー管理ソフト『MFクラウドマイナンバー』
資金調達サービス『MFクラウドファイナンス』

メディア
くらしの経済メディア『MONEY PLUS』


  1. 通常会員、プレミアム会員など ↩︎

  2. Money ForwardのAndroidアプリは利用している ↩︎

  3. デフォルトではメソッド名がkeyになる。@DebugReturn("key")のようにkeyを変更することも可能 ↩︎

リニューアル後の国税庁サイトを検索できるサービスを作ってみた

こんにちは。
エンジニアのhaitoです。

先日の国税庁ホームページリニューアルに伴い、リニューアル前のリンクでは目的のページが閲覧できない状況となっています。
国税庁も事態を認識しており、対応を進めているそうなのですがしばらく時間が掛かりそうです。

そこで、ページ名からリニューアル後のURLを検索できるサービスを作ってみました。
3月決算でお困りの経理の方、会計事務所の方、ぜひご活用ください!

 
リニューアル後の国税庁サイト検索
※ 当サービスの検索結果により生じたいかなる損害に関して、当社は責任を負いかねます。あらかじめご了承ください。

ソースコードはこちら
https://github.com/moneyforward/tax_newurl

 
<参考リンク>
国税庁ホームページリニューアルのお知らせ

国税庁HPリニューアルでページにたどり着けず…しばらく続く可能性

Coding CDN in MoneyForward

こんにちは。
インフラエンジニアの鈴木です。

MANABIYA -teratail Developer Days にて
「Coding CDN in MoneyForward」というタイトルでLTをしてきました。

本日はその紹介させていただきます。
 

LTについて

発表スライドはこちら
https://speakerdeck.com/syosuke1024/coding-cdn-in-moneyforward-1

テーマはこちらの2点

  • CDN、LB、リバプロ等、フロント周りの悩みをfastly(CDN)を入れて解決した話
  • fastlyのデプロイをコード化、自動化した話

そして、時間の都合で話しきれなかったことがスライドに詰まっています。
(5分では話し切れないことがいっぱい)

ご興味ある方は、スライドをご覧ください。
 

続きを読む

マネーフォワードエンジニアインタビュー 渋谷亮「数年後を見据えて、組織もサービスもスケールさせていく」

マネーフォワードの中の人を知ってもらうため、当社でフルタイムのRubyコミッターを務める卜部昌平が、マネーフォワードのエンジニアにインタビューをするこの企画。今回は、『MFクラウド会計』の開発チームのエンジニア渋谷さんへのインタビューです。

▼過去のエンジニアインタビューはこちら
マネーフォワードエンジニアインタビュー 谷口徹「BtoBはユーザーとの距離が近い」
マネーフォワードエンジニアインタビュー 鈴木信太郎「モノポリーから始まったエンジニアへの道」
マネーフォワードエンジニアインタビュー 金子雄一郎「経理から会計の未来をつくるエンジニアへ」
マネーフォワードエンジニアインタビュー 中川敦「隣のおじさんから学んだC言語と”Inside Macintosh”」
マネーフォワードエンジニアインタビュー 西方夏子「大事なのは、その時々で最善な道を考えること」
マネーフォワードエンジニアインタビュー 飯田祐基「収益を生むインフラを目指したい」
マネーフォワードエンジニアインタビュー 大須賀洋「フロントエンドでの論理的な設計の楽しさ」
マネーフォワードエンジニアインターン 小笠原純也「ユーザーの人生に寄り添えるサービスを」
マネーフォワードエンジニアインタビュー 内波生一「価値のあるものに対して、自分自身が前に進める力になっていたい」

語り手

渋谷亮 (エンジニア)
2007年アドウェイズに入社し、広告システムの開発を担当。2010年にGREEに転職したのち、2014年にマネーフォワード入社。MFクラウド請求書の開発を経て、MFクラウド給与・MFクラウドマイナンバーの立ち上げを経験。現在は、MFクラウド会計の開発に従事。

聞き手

卜部昌平 (Ruby開発者)

その他

青木香菜子 (広報:記事編集・撮影担当)

渋谷亮 インタビュー

eyecatching

続きを読む

DroidKaigi 2018に登壇 & SILVER SPONSORとして協賛します


こんにちは。
Androidエンジニアの @syarihu です。

さて、2018年2月8日 (木) 〜 2月9日(金)にベルサール新宿グランド コンファレンスセンターにて開催されます DroidKaigi 2018 に、マネーフォワードから私、@syarihu が登壇します。

 

登壇セッション

2018年2月9日(金) 17:40 〜 18:10 @ Room 5
Android WearのWatch Faceを作ろう 〜時計の盤面に小さな情報を添えて〜

本セッションでは、Android WearのWatch Faceと呼ばれる時計の盤面について、Watch Faceを開発するために必要なAPIの概要や、そのAPIを利用したWatch Faceの開発方法について解説します。
DroidKaigi 2018でAndroid Wearに関するセッションはこのセッションのみとなっておりますので、Android Wearについて少しでも興味があればぜひお立ち寄りください。

 

SILVER SPONSOR としてDroidKaigi 2018を応援!

また、マネーフォワードは SILVER SPONSOR としてDroidKaigi 2018を応援させていただきます!

当日は、マネーフォワードのブースも出展いたします。
ステッカーやオレオなどを用意しておりますので、ぜひお立ち寄りください。

よろしくお願いします!

続きを読む

MoneyForwardの検索ロジック歴史

はじめまして。
Money Forward で Ruby on Rails のエンジニアをしています辻です。
( ※ CEOの辻とは別の辻です )
現在学生で内定者インターン中です。

今回業務で検索機能を実装する機会があり、検索ロジックはどういう設計にするのが良いのかチームで議論してきました。

MoneyForward ではこれまで検索ロジックに関して様々な設計が採用されていたので、その背景について軽く話しながら今回採用した検索ロジックについて説明します。

はじめに

MoneyForwardでこれまで検索ロジックとして採用されていた設計を、歴史といった時系列で追います。
歴史は1〜4まであり、それぞれ検索に関する設計について説明していきます。

またサンプルコードがあるので、良ければこちらを参照して下さい。
「歴史1」に関するロジックは、sample1_users_controller といった形で歴史の番号と対応したサンプルコードになっています。
https://github.com/ShuheiTsuji/search_history_sample

歴史1:form_tag + controllerべた書きスタイル

続きを読む

エンジニアとデザイナーの相互理解

こんにちは。
iOSエンジニアの廣瀬です。

今日は、“(しら)ずにお金が(たま)る”自動貯金アプリ『しらたま』( https://sirata.ma/ )の開発時に実施した エンジニアとデザイナーの相互理解 についてお話しします

この記事(Atomic Design を導入してみた話) においての活動でもそうなのですが、このような取り組みを行うきっかけは、何か課題を感じた場合です。

この記事では、エンジニアとデザイナーの相互理解 を実現するために起こしたアクション、および何故アクションをとったか、どういう課題を感じていたのかをお話ししていきます。

コミュニケーション

エンジニアとデザイナー間のコミュニケーションについて課題を感じていました。
チームで開発している以上コミュニケーションは欠かせないものです。
コミュニケーション についてどういう風に課題を感じていたか説明します。

続きを読む

Atomic Design を導入してみた話

こんにちは。
iOSエンジニアの廣瀬です。

以前から感じていた課題に、デザインデータ・UIコンポーネントの管理 がありました。
その解決策として Atomic Design の考え方を取り入れてみました。

今日は、“(しら)ずにお金が(たま)る”自動貯金アプリ『しらたま』( https://sirata.ma/ )の開発時に実施した Atomic Designの導入 について紹介します。

デザインデータ・UIコンポーネントの管理

ここでいう デザインデータ・UIコンポーネント とはデザイナーが使っているツール(Sketch)や、フロントエンドとなるiOSアプリのコードレベル(Swift)の話です。
具体的に管理がうまくいっていない状態とは下記のような状態と言えます。

  • カラーコードやフォント名がコミュニケーションを取るときに飛び交う
  • アプリ全体で フォント の使い方にコンセプトが無い
  • Sketchとプログラムコードのどちらが正しいかわからない
  • 新しいメンバーが入ってきたとき等にデザインのコンセプトを説明できるものが無い

続きを読む