LocoPartners 開発ブログ

LocoPartners 開発者達によるブログです

Reluxのデザインコンセプトと、Reluxアプリが評価を頂けてる理由

お久しぶりです、デザイナーの唐橋です。

前回の私の記事が2016年5月でしたから、もう半年以上ぶりの更新となりますね(汗)

さて、1月24日に弊社主催のiOS/Androidエンジニア向け勉強会「App Talk Night」を開催いたしました!

私もデザイナー枠で登壇のチャンスをいただいたので、 「Reluxのデザインコンセプトと、Reluxアプリが評価を頂けてる理由」というタイトルで、 トップバッターでお話しをさせて頂きました。

勉強会の様子はLocotoryの記事にもあがっておりますが、 スライドショーの資料だけではわかりにくい部分もあると思うので、 その解説と少しだけ補足をいたしますね。

www.slideshare.net

Reluxのデザインコンセプト

ReluxはPC、SP、アプリ、バナー、ポスター、グッズ、メルマガ、提携関連と、Reluxと一言でいっても多種多様なデザインが存在します。

そんなReluxの世界観を表現するための3つのコンセプトがあります コンセプトがあることによって、 どのデバイスでも同じ世界観を共有でき、 かつ制作的には様々な人間が客観的にReluxのデザインの良し悪しを判断することが出来ます。

1 統一性

トーン&マナーを明確にします。 具体的にはカラー、フォント、写真の使い方、言葉使いのことです。

2 引き算

サイトの機能は、油断していると果てしなく増え続けるものです。 Reluxではその機能は本当に必要なのかよくよく考え、 既存機能でも不要と感じたら機能を減らしていく文化があります。 言葉も同じで、よりシンプルな説明になるように編集部が吟味してくれています。

3 体験

Reluxに訪れた瞬間から旅行は始まってると思います。 そして宿探しというのは、比較検討をしたりと結構大変なものですよね。 そんな宿探しを楽しい体験にしたいと思いながらデザインに落とし込んでおります。 特にアプリですと、ちょっとした工夫や動きでとても楽しい体験に変わります。

Reluxがユーザーに評価を頂けてる理由

アプリのレビューの平均点は、

App Storeが4.3点、Google Playが4.2点とユーザーの方々に高評価を頂いております。

そしてその中で特に多い声が下記の3つの声でした。

  1. シンプルなデザイン
  2. 眺めてるだけで楽しい
  3. 使いやすい

1については広告もおすすめコンテンツもなく、検索に特化したアプリですから本当にシンプルです。 トップページも美しい季節の写真が背景にはり、他の旅行系アプリとの違いが歴然です。

2は「掲載施設様の写真が持ってる魅力」と、「掲載チームが厳選して選んでいる写真」のおかげではあります。 そして私はユーザがその魅力的な写真を感じつつ、比較検討しやすく配置しております。

3は使いやすいといっても、年齢、性別、環境によって印象が違うものです。

そこが「ユーザー体験」の難しいところなのですが、 一つの仮説として「各ページでユーザのするべき行動が明確だから使いやすいのではないか」と考えました。

  • トップページ→行きたいエリア名を入力する
  • 検索結果→様々な施設を比較検討する
  • 施設詳細→施設について詳しく知る
  • 予約フォーム→予約者の情報を入力する

このように各ページにユーザのするべきことが決まっており、 その行動を促進するデザインになっているのです。

まとめ

Reluxアプリが評価を頂けてる理由というのは、 「Reluxのデザインコンセプト」と「ユーザーが求めてるもの」が一致してるからこその賜物だと考えています。

ただそれは、ユーザの求めてるものをReluxが考えに考え、 あくまでユーザー視点でコンセプト設計しているからでもあります。

その結果、ベストアプリの受賞という名誉を頂けたのだと思います。

そんな僕たちと、

一緒にReluxを成長してくれる仲間を随時募集中です♪

旅行が好きなデザイナーの方は、お気軽にお声かけください。

もちろん大学生のデザイナーインターンも募集中ですよ!

https://www.wantedly.com/projects/78014 www.wantedly.com

【重要だけど緊急度が低いタスクに取り組む日】CLEAR@5回目を開催しました

古田です。

すっかり秋ですね。
今年も残り3ヶ月を切っているとか、時が過ぎるの早すぎ。
と毎年思ってる気がします。
残りの日々も精一杯がんばります。

本題ですが、先日(10/13)CLEARを実施しました。
CLEARについての説明はこちら

loco-partners.hateblo.jp

毎月1回のペースで続けてますが、早くも5回目。
今回もエンジニア自身でピックアップした課題に取り組みました。

作業風景
移転したばかりの綺麗なオフィスでもくもくもく。 f:id:loco-dev:20161013195302j:plain

ランチタイム
CLEARの日のお昼代は会社が負担するのですが、
好きなの食べていいのになぜか毎回ハンバーガー。。w
f:id:loco-dev:20161013195330j:plain

で何したか

こんな感じでリラックスしながら取り組んでいるCLEARなのですが、
今回は、せっかくなので取り組んだタスクの一部を紹介します。

KPIデータのグラフをSlackへ通知

by 三寳

現在もKPIをSlackに通知する仕組みは存在するのですが、
Reluxのシステムの中に組み込まれており、意図せずReluxに
バグを仕込んでしまうリスクがあります。

今回のKPI通知は、RedashGoogleスプレッドシート
GoogleAppsScriptを連携させて作りました。
いじるのはReluxとは独立した外部サービスのみで、
Relux本体には何の影響も与えない仕組みです。

Redashはクエリを作成すると自動的にエンドポイントを生成
してくれるので、そこからクエリ結果をJSONで取得しています。
そのエンドポイントをGoogleAppsScriptで叩いて、
スプレッドシートにデータを書き込む。
シートの方には集計関数とグラフを作成しておいて、
更新したデータで再描画して、Slackにグラフ画像をPOSTしています。

f:id:loco-dev:20161013205049p:plain

Firebaseを導入してみる

by 赤池

AndroidアプリにFirebaseのAnalyticsRemoteConfigを仕込みました。
SDKの導入は簡単!
ただ、弊社アプリはproductFlavorsで開発用アプリの
パッケージ名を切り替えられる用にしているので、
本番/開発用それぞれアプリを登録する必要がありました。

Analyticsはイベントトラッキング・アプリバージョン・デバイスシェア等、
アプリ分析に必要な最低限の情報が取れます。
GoogleAnalyticsとは違いリアルタイムのユーザー数などは見れませんが、
余計な機能は少なくざっと数字をチェックするには十分という印象。
初回起動数と収益金額を元に算出されたLTVが表示されるのも良いです。

RemoteConfigはアプリのABテスト等が簡単に仕込める機能で、
Firebaseのコンソール上で設定した値を条件に基づいてアプリ側で取得できます。
想像していたより実装に考慮が必要な面はありましたが、
こちらも手軽に導入できるので、
Firebase導入の際には試してみると良いと思います。

GoogleFormからBackLogの課題を作る。

by 北山

弊社では、他部署からエンジニアへの問い合わせをGoogleFormで行います。
その中にはバグ報告もあるため開発作業が発生する案件も。
その際にはタスク管理にBackLogを使っているためチケットを切ってから作業します。

しかし、チケットを切る事を漏れる時もしばしば、、
何とか仕組みで解決できないかと自動化することにしました。
やってみれば簡単で、GoogleFormが送信されたことをトリガーに GoogleAppsScriptよりBackLogAPI経由でチケット切るようにしました。

GoogleAppsScriptのメリットは、実行環境の準備が不要で
Googleのサービスとの連携も容易。
今後も何か新しい仕組みを始めようとする時に、
まずGoogleAppsScriptで実装できるか検討してみようと思います。

まとめ

これらのタスクはエンジニア自身で課題だと思うところを考え、
解決するためにはどんな解決策があるか検討/議論して取り組みます。
自部署やプロダクトだけでなく会社全体を見る視野を得られると共に
課題発見/解決の力も付く取り組みにもなってます。

次はどんな課題を解決してくれるのか、、毎回楽しみです^^

お知らせ!

弊社主催で以下のイベントを開催します。
移転したばかりの綺麗なオフィスなので 是非お気軽に遊びに来てください!

relux-mokumoku.connpass.com

kaizen.connpass.com

技術的負債への取り組み『CLEAR』とは

こんにちは、古田です。

最近はボルダリングやらランニング(Pokemon GO)を始めましたが、、
暑いですね。
夏に始めるもんじゃないと思いつつ継続するために奮闘中です。

さて、今回は我が部署で6月頃から始めた新たな取り組みをご紹介します。
その名も『CLEAR(クリア)』です。

サービスローンチ以降、スピードにこだわって機能開発を進めてきました。
1名のエンジニアが立ち上げたサービスも、
現在はアプリ含めて10名ほどの技術者・デザイナーで開発しています。
歴史と共に、当然ながら技術的負債も蓄積されてきました。

この負債による負担が、引換に得られるスピードをいよいよ越えてきたので、
通常の開発業務と切り離して時間を取ることにしました。

CLEARとは

1ヶ月に1日を丸っと使います。
約20日勤務のうちで1日なので5%ほどを投資していることになります。
この取り組みには2つの目的があります。

① 重要だが緊急度の低いタスクを推進

技術的負債が原因で影響範囲を把握しづらく不具合が発生しやすくなっています。
結果として必要以上に労力がかかったり不具合対応に追われるために本質的な開発時間が削られます。
また会社の規模が大きくなり他部署とのやりとり(問い合わせ対応やデータ出力など)も増えました。
それらに対して、リファクタリングや作業自動化を行うことで集中できる環境を自分たちの手で整えていくこと。
これが1つ目の目的です。

② 個人QCD管理能力の成長

1日という限られた時間の中で完結させるためにQCD管理が大事です。
事前の準備から正しい工数設定、また当日の集中力も含めて生産性を最大化する工夫を徹底して行います。
完了後には毎回KPTで振り返りながら運用フローも改善しています。
QCDへの意識付けとスキルアップ、これが2つ目の目的です。

このような背景から、
・働く環境を綺麗に整える
・成長するという目標を達成する
という意味を込めてCLEARと名付けられました。

ちなみに、、ロゴも作っちゃいました!

f:id:loco-dev:20160802094116p:plain

改善は1回で終わるものではない。
継続して繰り返し推進していく、という思いが込められています。

どんなことやってるか

事前準備

作業内容はメンバーが自分で決めます。
困っていること・開発効率を下げている要因を元に時間内で出来ることをピックアップします。
他部署からデータ修正の依頼が多ければ、それを機能化してしまうとか。
手動のテストに時間を取られているのであれば、E2Eテストを書くとか。
それらをタスク管理ツールのTrelloへ、タスクカードを作成していきます。
ここまでを1週間前に済ませておきます。

作業開始

開始時刻の少し前に集まって1人1分ずつ意気込みをアウトプット。 f:id:loco-dev:20160731171307j:plain そしてもくもく作業スタートです。 f:id:loco-dev:20160731171322j:plain 思い思いのスタイルで開発しています。

ランチ

お昼ご飯もみんなで取ります。
集中時間を少しでも確保するために出前を注文。 f:id:loco-dev:20160731171247j:plain たまたま最初に頼んだハンバーガーが人気で2回目も同じところに頼みましたw

そして、また各自作業へ没頭していきます。。。

作業終了

テストも込みでその日にやりきるため最後の方はバタバタしますが、、
無事に完了して締めの時間を少し取ります。 f:id:loco-dev:20160731171340j:plain また各自1分程度で振り返りをアウトプットして終了。
皆やりきった感でいっぱいです。(疲れ気味?)

頑張ったあとは、、、

飲み行きましたw f:id:loco-dev:20160731171621j:plain この日は美味しい串焼きをいただきました^^

おわりに

毎回、たった1日とは思えないほどのアウトプットがあります。
また各自が必要だと思ったことに取り組み課題解決していくため
モチベーションも上がるので本当に良い取り組みだなと思っています。

そんな現場主導の取り組みをしている開発体制に興味ある方、
気軽に遊びに来てください〜^^
CLEARについて、その他開発体制で工夫していることなど
是非いろいろなお話させてください。
以上!

Swift Library & Xcode Plugin

なんか最近あれですね。暑いですね。

こんばんは。LocoPartersエンジニアインターンの竜口です。 普段はサーバーサイドを担当していますが、 最近Swiftを触っているので 今回のブログでは、実際に使ってみて良かった SwiftのLibrary と XcodeのPlugin を紹介します。

目次

  • Swift
    • Alamofire
    • AlamofireImage
    • SwiftyJSON
    • Quick
    • Nimble
  • XCode
    • VVDocumenter-Xcode
    • Alcatraz

Swift

Alamofire

github.com

機能
  • HTTPネットワークライブラリ
  • HTTPリクエストを書きやすくする
  • 非同期通信
使い方
Alamofire.request(
    .POST, //HTTPメソッド
    "https://hoge.com",  //リクエストURL
    parameters: ["test": "hoge"], //パラメーター
    headers: ["Content-Type" : "application/json"] //ヘッダー
    ).response { (request, response, data, error) -> Void in
        //レスポンス
    }

AlamofireImage

github.com

機能
  • 非同期通信で画像取得
  • 画像のキャッシュ管理もしてくれる
  • 画像取得中のplaceHolderも設定可能
使い方
customCell.placeImg.af_setImageWithURL(
    NSURL(string: "https://hoge/image")!, // URL
    placeholderImage: nil, //プレースホルダーの画像を設定
    filter: nil //取得した画像の加工(角丸等)
)

SwiftyJSON

github.com

機能
  • JSONを扱いやすくする
  • Alamofireと連携して使える  → responseをJSON型で取得できる
使い方
{
    "count" : 2,
    "Hotels" : [
        {
            "Hotel" : {
                "name": "hogeHotel",
                "Price": 300000
            },
            "Hotel" : {
                "name": "hogeRyokan",
                "Price": 500000
            }
        }
    ],
}
let data = JSON(jsonData)
let hotels = data["Hotels"]

hotels.forEach{(id, hotel) in
    print(hotel["name"].string) // return "hogeHotel"
    print(hotel["price"].int)   // return 300000
}

Quick / Nimble

github.com

機能
使い方
let val = 3 + 2
it("is equal"){
    expect(val).to(equal(4)) //失敗 エラー文言:expected to equal <4>, got <5>
}
it("is equal"){
    expect(val).notTo(equal(4)) //成功
}

XCode

Alcatraz

alcatraz.io

機能
使い方

1.インストール

curl -fsSL https://raw.github.com/supermarin/Alcatraz/master/Scripts/install.sh | sh

2.Xcodeを再起動
3.Window > PackeageManager (cmd+shift+9) で表示

VVDocumenter-Xcode

github.com

機能
  • コメントを保管
  • 引数、返り値も自動で保管
使い方

/// と入力するだけで完了

https://camo.githubusercontent.com/58e452b57245cd79c2e59ac7926609be4dffbfd8/68747470733a2f2f7261772e6769746875622e636f6d2f6f6e65766361742f5656446f63756d656e7465722d58636f64652f6d61737465722f7676646f63756d656e7465722d73776966742e676966

Firebaseを軽い気持ちで触ってみたら使い勝手が予想を遥かに超えてきた話

こんにちは。Loco Partnersのエンジニア、鈴木です。

わたくし普段は弊社サービスReluxのサーバーサイドの開発を担当していますが、元々はiOSエンジニアでした。
かれこれ1年近くも実務でのアプリ開発から離れているので、iOSは話題のキャッチアップで精一杯…。
たまには手を動かそう、ということで、話題のFirebaseをさわってみました。

Firebaseとは?

そもそもFirebaseとはなんでしょう?
元々は米国で始まったmBaasであり、2014年にGoogleに買収されたことでその名が広く知れ渡りました。
また先日のGoogle I/Oにてバージョンアップを発表、その中には無料で利用できるプッシュ通知の提供もありました。
年始に同じくプッシュ通知サービスを提供するmBaasであるParseの終了アナウンスがあったため、代替サービスとして注目している人も多いのではないでしょうか。
そんな時勢も相まって、今もっとも注目を集めるmBaasと言っても過言ではありません。

何ができるの?

f:id:loco-dev:20160627162600p:plain Firebaseは実に多くの機能を提供しています。
Authentication、Cloud Messaging、Crash Reporting、Notificationsなどなど、どれも本来であればサーバー開発に大きな工数がかかるもの。
これらの機能が高水準で提供されており、かつ無料で利用できる枠も大きいときたら、個人デベロッパーも企業も試さない手はないでしょう。

Realtime Database

f:id:loco-dev:20160704152603p:plain 今回は数ある機能の中から Realtime Database を試してみました。
便利そう、面白そう、かつフルスクラッチで作ったらとても大変そう、という理由です。
Realtime Database という名前からお察しのことと思いますが、特徴をざっくり箇条書きにするとこんな感じです。

  • 端末から送信されたデータがクラウド上に保存される
  • クラウド上のDBを介して、複数の端末、複数のユーザー間でデータの同期が可能である
  • オフラインでもローカル上でデータ保存され、オンラインになったタイミングで自動でクラウド上にデータ保存される

特に便利なのが最後のオフライン時の挙動。これをフルスクラッチで実現しようと思ったらぞっとしますね…。
たしかGoogle AnalyticsSDKがこんな仕組みだったと思うのですが、同じ技術を用いているのでしょうか。

導入編

それでは導入から見ていきましょう。
まずは登録から。
Googleアカウントと連携できるので、1クリックで完了です。
f:id:loco-dev:20160704154918p:plain

コンソールはこんな感じ。
ほとばしるGoogle感。
f:id:loco-dev:20160704155129p:plain

その後DLしたplistをプロジェクトに追加。 f:id:loco-dev:20160704160506p:plain

最後にCocoapods経由で追加してあげれば導入完了です。簡単ですね。
ちなみにpodfileへの追加分はこんな感じ。

pod 'Firebase'
pod 'Firebase/Database'

作るアプリ

複数端末でのデータ同期、ときたらやはりチャットでしょうか。
サンプルとして簡易的なチャットアプリを作ってみます。
最先端のマテリアルデザインを取り入れた、最高にイケてるUIです。
わかっているので何も言わないでください。
f:id:loco-dev:20160704161411p:plain

ユーザー名とテキストを入れるだけの、簡素なものです。

ソースコード

では実装に入っていきましょう。
AppDelegateに以下を追記します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [FIRApp configure];
    return YES;
}

ViewControllerは以下。

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _nameTextField.delegate = self;
    _messageTextField.delegate = self;
    
    databaseRef = [[FIRDatabase database] reference];
    [databaseRef observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
        NSString *name = [[snapshot.value objectForKey:@"name"] stringByAppendingString:@": "];
        NSString *message =[[snapshot.value objectForKey:@"message"] stringByAppendingString:@"\n"];
        _textView.text = [_textView.text stringByAppendingString:[name stringByAppendingString:message]];
    }];
}

- (IBAction)submitBtn:(id)sender {
    NSString *name = _nameTextField.text;
    NSString *message = _messageTextField.text;

    [databaseRef.childByAutoId setValue:@{@"name":name, @"message":message}];
    _messageTextField.text = @"";
}

- (BOOL)textFieldShouldReturn:(UITextField *)sender {
    
    [sender resignFirstResponder];
    return true;
}

これですべてです。

やっつけコードなのはご容赦いただくとして、やっていることはこれだけです。

  • DBの読み書きをするためのインスタンスを取得
  • DBの変更を監視、変更があった場合の処理をブロック構文で書く(この場合はテキストの追加)
  • 送信ボタンが押下されたら、記入者とメッセージ内容を保存する

DBの読み書きが本当にシンプルに記述できます。

実行結果

それでは実行結果を見てみましょう。
f:id:loco-dev:20160704165655p:plain

コンソールにこんな具合で、リアルタイムにデータが追加されていきます。
ちなみに編集や削除もこちらからできます。debug時にも便利ですね。

今回シミュレータと実機でチャットを試してみましたが、問題なくやりとりできました。
また一方の端末でネットワークの接続を切って更新、ネットワーク再接続、というテストをしてみたところ、期待通り再接続時にもう一方でテキスト内容が更新されました。
意識することなくこれが実現出来るということだけでも Realtime Database のすごさがわかっていただけると思います。

総括

いかがでしたか?
繰り返しになりますが、その導入の簡単さ、記述するソースコードの簡潔さ、オフライン時の挙動の便利さには目を見張るものがあります。
今回はサンプルということで簡素な使い方しかしていませんが、色々とアイディアが膨らむサービスです。
次回は他の機能も試していこうと思います。

Facebook Messengerのchatbotリリースを振り返って

こんにちは、Loco技術Gの古田です。

突然ですが、、、

relux公式Facebookページ(http://www.facebook.com/rlx.jp)のメッセンジャーで、

チャットボットによる旅館・ホテルの検索サービス「reluxトラベルボット」が開始!

(詳しくはこちらのプレスリリースをご覧ください)

http://m.me/rlx.jp こちらのリンクからお試しいただけます。

ということで、今回は開発に至る背景から苦労したところなどなど、

振り返りも兼ねてご紹介しようと思います。

はじまり

きっかけは社長の鶴の一声、、、ではなく。

弊社は新しい技術や仕組みにいち早く取り組もうとする文化があります。

だからFacebook Messenger Platformが公開されたなら、

その可能性を知るためにも Tryしてみよう!

という流れになるのは自然なことでした。

まずリリースをすることを決める。で実装を考えていかないと

これってリリースできるかなとか本当に必要あるのかとか

やらない言い訳はいくらでも出てきてしまいます。

時代の流れというか人々の中心にチャットがあることは明らかであり、

お客様とのコミュニケーションを大事にしている弊社にとっては

うまく活かしていきたいプラットフォームでした。

また、自分で作ろうと思った理由としては2つあり、

1つは元から自分自身でもAIには興味持っていたこと。

もう1つは、LINEなどchatbotの流れが来ているけれど、

具体的な活用イメージを描くためにも直接作りたいという点でした。

設計

他社の事例も参考にしながらユーザーストーリーを作りました。

既に良い事例がいくつも出ていたのでかなり参考になりました。

(参考例)
http://m.me/hiponcho
http://m.me/cnn
http://m.me/techcrunch
http://m.me/alterra.cc

設計で気を付けたことは3つです。

  • 盛り込み過ぎない。必要最低限のミニマムスタート。
  • 実用的か。ちゃんと使ってもらえるものか。
  • reluxらしい機能か。

これを元にまずはGoogleSlide5,6枚の簡単なものを作成しました。

今回はreluxの検索機能コンシェルジュへと繋げる機能としました。

実装

まずは足がかりとして、こちらのイベントへ参加。

connpass.com

最初は何をやっていいか全く分からず当日を迎えましたが、

雰囲気を察して、鸚鵡返しを作ると良さそうだと分かり実装開始。

色々なサイトを参考にしながらHerokuを活用して実現できました。

ここまでは意外とあっさり。

周りの参加者もお昼頃にはそこまで完了している様子。

次に、検索を実現するためにDBを参照する方法を検討。

既存のrelux自体はPHPで書いているので、

PHPでbotAPIを作成するという手もありました。

ただ、本体機能と切り離したい&アクセス数が読めない中で

そのためのリソースを確保するのも難しいと思い、

Lambda + API Gatewayで実現することにしました。

その勉強会ではLambda環境までいかずにタイムアップ。

続きは宿題となりました。

〜〜〜

Lambdaの導入、ここは意外とはまりました。

RDSを参照するためVPCにアクセスできるように設定しつつ、

Messengerへ投稿するために外部へ通信できる必要がありました。

そのためのNAT ゲートウェイをサブネットに設定するのですが、

通信できない状況が続きました。。

試行錯誤を繰り返し環境を構築。(方法はどこかで書けたら書きますw)

Lambda使って鸚鵡返しに成功したことを確認できました。

次はメッセージ内容の保存です。

検索機能ではchatやりとりの中で入力した条件を利用するので、

テキスト内容とメッセージの種類(日付・泊数・人数など)を

保存する先としてAWSのDynamoDBを選択しました。

これはLambdaで標準に使えるaws-sdkを使えば簡単に実装できます。

最後に検索条件に従って宿泊できる施設を検索する機能です。

これもSDKを使えばDBとの接続は難しくありません。

クエリを書く際にはセキュリティに配慮して実装しました。

途中気づいたのが写真付きのパネルは最大10個までという点です。

今回は施設を探すエリアをパネルから選択できるようにしたのですが、

本来relux上のエリア区分は12あります。10では全て選択できません。

統合も検討しましたが、まずはサクッと進めるために

取り扱い施設数が少ないエリアを除くという一時対応としました。

他にも難しいなと思ったのはチャットだから自由な表現ができる点。

同じ意味を伝えるのにも様々な表現がある。

かつ検索フローと関係なく、いつでも好きなテキストを打ててしまう。

全ての言葉に正しく反応することを考え始めると時間がかかるので

検索中それ以外とで状態を定義して、

それぞれに一定の文言を返す様にしました。

申請

Facebook開発者 - 開発者向けFacebook から申請を行います。

一連の操作が含まれている動画を用意する必要があります。

出したはいいのですが、最初の申請では2週間以上待たされました。

変だなと思っているところで社内の人間が他社に聞くと2日程度で完了したとのこと。

普通ではなさそうなので思い切って審査をキャンセルし再度申請したところ2日で通過。。

審査完了したのにOKボタンを押し忘れてたのかな。。。

2週間のロスは痛いですが、無事にリリースできました。

リリース反響

プレスリリース当日は凄まじい勢いで投稿数が増えました。

普段は月に数名というところ、初日で1000名を超える方からアクセスいただきました。

おかげで社内コンシェルジュも大慌て、嬉しい悲鳴でした。

実際やってみることで世の中の注目度を身をもって感じました。

おわりに

世の中の流れに乗るということのインパクトの大きさを感じると共に

初期に参加することによる反響の大きさ、その重要性を改めて実感。

これからサービスや組織が大きくなっても初動スピードは大事にしていきます。

そして、今回は本当にプレイヤーとして存分に楽しませてもらいました。

新しいことにtryするって良いですね〜

ということで、こんなスピード感でいろいろ挑戦したい!

というエンジニアの方がいれば、

ぜひ一度弊社に遊びに来てください。いつでもwelcomeです!

採用情報 | 株式会社Loco Partners

reluxのAndroidアプリコーディング規約

こんにちは。Androidアプリ開発を担当している赤池です。梅雨ですね。梅雨です。

弊社reluxのAndroidアプリは基本的にエンジニア一人体制で開発しています。 一人体制だとチーム開発によるコード統一性の乱れやコンフリクト等が生じない一方、他者にはわかりづいらい自分流の開発スタイルになりがちという問題があります。reluxのAndroidアプリのコードにも他者が見るとクエッションになりそうな箇所が見受けられたので(自分で言う!)、今後の複数人開発に備えコーディング規約の作成を進めています。

背景についての補足

話は変りまして、弊社開発グループでは月に一度「CLEAR」という日を設けております。 日頃なかなか時間を取ることができない品質改善のためのタスクを、この日は自分で好きに選んで行うことができます。 CLEARに関しては別のブログでも触れると思うので詳細は割愛しますが、コーディング規約はこの日のタスクの一つとして着手しました。

まずはじめに見るべきもの

みなさまAndroidアプリのコーディング規約はどうしていますか?独自に定めていますか? 実はAndroidアプリコーディング規約はGoogleがすでに制定しています。 こちらには「ガイドラインや推奨ではなく厳格な決まり」という記述があります。 AndroidのContributorにならないにせよ、従っておいて間違いないでしょう。

Code Style for Contributors | Android Open Source Project

また、GoogleJavaに関するスタイルも定めてます。 前者でカバーしていない部分はこちらを参考にします。

Google Java Style

規約の主な内容

reluxのサーバサイドのプログラムはPHPで書かれています。PHPのコーディング規約はPSRをベースにしているのですが、それとの違いを中心に規約内容をいくつかピックアップしてみます。

フィールド(メンバ変数)の命名規則
//非パブリック・非スタティックは頭にmを
private int mPrivate

//スタティックは頭にsを
private static MyClass sSingleton;

//定数は大文字と_のみ使用
public static final int SOME_CONSTANT = 42;
中括弧について
//中括弧で行を始めてはならない(改行しない)
class MyClass {
    int func() {
        if (something) {
            // ...
        } else if (somethingElse) {
            // ...
        } else {
            // ...
        }
    }
}
// 条件文には中括弧をつける
if (condition) {
      body();  
  }

// 一行で収まる場合はつけなくても構わない
if (condition) body(); 

// これはNG
if (condition)
      body();
インデントについて
//4スペース
for (int i = 0; i < n; i++) {
    doSomething(i);
}

//関数呼び出しと引数を含む場合の改行は8スペース
Instrument i =
        someLongExpression(that, wouldNotFit, on, one, line);
頭字語や略語は単語として扱う
//OK
XmlHttpRequest
//NG
XMLHTTPRequest

//OK
getCustomerId
//NG
getCustomerID

まとめ

以上のように公式の規約に従うことだけで大部分はカバーできるので、あとは特に定めのないものやアプリケーション特有のものに関して付け加えていけばOKかと思います。 弊社ではリーダブルコードを題材にした社内勉強会を行っていますので、それらを参考にしながら仕上げていく予定です。