LocoPartners 開発ブログ

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

Photoshopの便利機能を活用した、Relux流バナー作成方法

こんにちわ、デザイナーの唐橋です。

2017年も早いもので3月になりましたが、まだまだ寒い日が続きますね!

さて今回は、Photoshopの便利な機能、

  • 「アートボード」
  • 「スマートオブジェクト」
  • 「ライブラリ」

を活用した、Relux流バナー作成方法をご紹介したいと思います。

私自身もまだ試行錯誤の段階ですが、 以前より作業が効率的に、そしてファイルの管理がとてもスマートになりました!

それでは、紹介していきます。

1 デザインは複数アートボードで並べてつくる

これまでは1つのファイル内で「マスク」を使用してバナーを並べたり、 1バナーごとに別ファイルで管理していましたが、 現在は1ファイルに複数のアートボードを作成して制作しています。

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

メリット

  • バナーデザインを並べて、俯瞰しながらデザインできる。
  • 1ファイルで済むので、管理が楽になる。
  • アートボード名をファイル名にすると、自動的にjpgで書き出してくれる。

デザインの確認が楽になったのが嬉しいポイントです♪

2 画像はスマートオブジェクトに変換する

スマートオブジェクトは、何度も同じ素材を利用する際は、 とても便利な機能です。

メリット

  • 画像を拡大縮小を繰り返しても、劣化しなくなる。
  • 複数使用しても、1画像分の容量で済む。
  • ひとつのオブジェクトを変更すると、すべてのオブジェクトを変更してくれる。

今回は「富士山の写真」と「スマートフォン」の画像をスマートオブジェクト化しています。 デザインを考えるうえで、何度も拡大縮小しましたが、劣化しておりません。

3 ライブラリでよく使うパーツを管理する

ロゴや色など、よく使用するパーツはライブラリに登録しておくと便利です。

今回はReluxのロゴをライブラリ登録しています。

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

メリット

  • 瞬時に呼び出して使うことができる
  • 元ファイルを開く必要がなくなる
  • Adobe製品内で同じライブラリを使用できる

上書きするとまずいロゴデータなど、「元データ」のaiファイルを毎回開かなくてよくなるので、 精神的にも安定します(笑)

さらにライブラリを、Creative Cloudで管理することで、 デザインチームメンバーと同じ環境を同期することができます。

4 jpgへの書き出しは自動化で!

1の「複数アートボードで並べてつくる」でも少し触れましたが、 アートボード名を「xxx.jpg」というように画像ファイル名にすると、 自動的にフォルダが生成され、そこにjpg画像がリアルタイムで書き出されます。

アートボード名だけでなく、レイヤー名にも適用されるので、 自分の好きなレイヤーごとにjpgに書き出すことも可能です。

もう「スライス」は過去の機能となりつつあります。

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

↑今回はアートワーク名に書き出されるファイル名を記述しています。

まとめ

Relux流バナー作成方法、いかがでしょうか?

私もまだまだPhotoshop勉強中の身ですから、もっと効率よくできないか模索中です。

そしてこういったデザインファイルの効率化に興味のあるデザイナーを大大大募集中です!!!!

一緒にReluxのデザインファイルの管理を考えませんか? ぜひお気軽に遊びにきてください♪

↓↓↓↓↓お問い合わせはこちらから!↓↓↓↓↓

www.wantedly.com

大学生のインターンも募集中ですよ!!

www.wantedly.com

CakePHPer が Laraveler に成りたくて Part.1

こんにちは。

Relux でサーバーサイドを担当している山口です。PHP が大好きです。

弊社では近頃一部の処理に Laravel を採用することになりました。今まで主に CakePHP を利用していたこともあり、未だまだ不慣れな箇所も多いですが学んだことを少しづつ当ブログを通じて発信していけたらと思います。

今回は初回ということで、簡単な API を Laravel 5.4.5 で作成し、テストをパスするまでの過程を紹介します。

Larvel でとりあえずコードを書いて試せる環境を用意する

composer の普及や built-in server が組み込まれた PHP の Version を Framework 側が要求するようになったこともあり、最近の PHP Framework はどれも環境を用意するのが非常に楽になりました。Laravel も他のフレームワーク同様に下記の手順を踏むだけで簡単に環境を用意することができます。

# Laravel のインストール
$ composer create-project --prefer-dist laravel/laravel sandbox

~~~ 省略 ~~~

Writing lock file
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postUpdate
> php artisan optimize
Generating optimized class loader
The compiled services file has been removed.
> php artisan key:generate
Application key [base64:yTWzVOqqPVKjXpIxvtgSDLguGC3BDbNbzswrjFi4qaA=] set successfully.
# build-in server の起動
$ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>

上記の URL (http://127.0.0.1:8000) をブラウザで開くと、オシャレなフォントで Welcome と表示され Laravel が動作していることを確認できます。 また、今回 built-in server の起動に利用した artisan コマンドは、他にも migration や各種コードの雛形の自動生成など色々と便利なことを行ってくれます。

もし、composer コマンドの途中でエラーが発生してしまった場合は Installation - Laravel - The PHP Framework For Web Artisans を満たしていないことになるので確認してみましょう。もう少しきちんとした開発環境を用意しないと気がすまない人は Laravel Homestead や Laravel Valet と呼ばれるものもあるのでそちらを試されてみるのも良いかもしれませんね。

Laravel Homestead - Laravel - The PHP Framework For Web Artisans https://laravel.com/docs/5.4/valet

API の仕様を決める

はじめに API の仕様を swagger-editor で作ります。 これは、Laravel とは関係がないので必要のない方は飛ばして頂いて問題ありません。

swagger-editor の install は npm, wget, unzip がインストールされている端末であればあっという間に終わります。 Web の開発をされている方の端末であれば大体はインストールされていると思うので、下記のコマンドを上から順に実行してみてください。

$ npm install -g http-server
$ wget https://github.com/swagger-api/swagger-editor/releases/download/v2.10.4/swagger-editor.zip
$ unzip swagger-editor.zip
$ http-server swagger-editor
Starting up http-server, serving swagger-editor
Available on:
  http://127.0.0.1:8080
  http://192.168.10.254:8080
  http://192.168.33.1:8080
Hit CTRL-C to stop the server

上記の URL (http://127.0.0.1:8080) にアクセスすると swagger-editor の画面が表示されるので、画面内で Swagger Spec V2.0 と呼ばれる決まりに従って json または yaml で仕様書を書いていきます。細かい説明は今回は省略して下記のようにドキュメントを記述しました。

swagger: '2.0'
info:
  version: "1.0.0"
  title: Uniqid API
paths:
  /uniqid:
    get:
      description: uniqid を作成
      produces:
        - application/json
      responses:
        200:
          description: |
            uniqid の作成に成功した場合
          schema:
            properties:
              uniqid:
                description: |
                  uniqid
                type: string

API のテストコードを記述する

それではテストコードからはじめていきたいと思います。 built-in server の起動に用いた artisan コマンドを用いて下記のようにユニットテストの雛形となるコードを生成しましょう。

$ php artisan make:test UniqidControllerTest --unit
Test created successfully.

tests/Unit 配下に UniqidControllerTest.php という下記のファイルが出来上がっているはずです。

<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class UniqidControllerTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testExample()
    {
        $this->assertTrue(true);
    }
}

早速、テストを実行してみましょう。

vendor/bin/phpunit
# 上記で実行出来ない人は下記を試してみて下さい。
vendor/phpunit/phpunit/phpunit

# 実行結果
PHPUnit 5.7.9 by Sebastian Bergmann and contributors.

...                                                                 3 / 3 (100%)

Time: 415 ms, Memory: 12.00MB

OK (3 tests, 3 assertions)

うまく動きましたか?テストをパスした数が 1 ではなく 3 になっているのは予め ExampleTest.php というファイルが存在しているからです。 これで、テストの雛形とテストの実行方法がわかったと思います。

それでは、テストを仕様に沿って記述していきましょう。uniqid() の性質上返される値を特定するのは難しいため、今回は雑ですがレスポンスに uniqid の key が存在するか、そしてステータスコードは 200 かをテストするコードを記述しました。

<?php

namespace Tests\Unit;

use Tests\TestCase;

class UniqidControllerTest extends TestCase
{
    /**
     * Authentication Controller.
     *
     * @return void
     */
    public function testレスポンスにuniqidのkeyが存在する()
    {
        $response = $this->json(
            'GET',
            '/api/uniqid'
        );

        $arrayResponse = (array)json_decode($response->content());

        $response->assertStatus(200);
        $this->assertArrayHasKey('uniqi', $arrayResponse);
    }
}

再度、テストを実行してみると下記のように 1 件のテストに失敗しているはずです。

PHPUnit 5.7.9 by Sebastian Bergmann and contributors.

..F                                                                 3 / 3 (100%)

Time: 459 ms, Memory: 12.00MB

There was 1 failure:

1) Tests\Unit\UniqidControllerTest::testレスポンスにuniqidのkeyが存在する
Failed asserting that an array has the key 'uniqid'.

/Users/kenya/loco/relux_api/tests/Unit/UniqidControllerTest.php:26

これは、テストに対応する実装が存在しないからですね。 次はこのテストをパスするために API の実装を行っていきます。

API の実装

artisan コマンドを用いて下記のようにコントローラーの雛形となるコードを生成しましょう。

$ php artisan make:controller UniqidController --resource
Controller created successfully.

app/Controller 配下に UniqidController.php という下記のファイルが出来上がっているはずです。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UniqidController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

今回は index() の部分しか必要がないのでそれ以外は削り、下記のように実装を行いました。

<?php

namespace App\Http\Controllers;

class UniqidController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $responseValue = [
            'uniqid' => uniqid(),
        ];

        return response()->json($responseValue);
    }
}

Routing を設定する

最後に作ったコントローラーを動かすために Routing を設定します。この設定ファイルは routes/api.php になるので下記の一行を足します。 コントローラー名@アクション名を第2引数に設定することで Laravel 側で UniqidController の index アクションにつなげてくれるようになっています。

Route::get('/uniqid', 'UniqidController@index');

動作を確認する

実装が完了しました。再度テストを実行してみましょう。

PHPUnit 5.7.9 by Sebastian Bergmann and contributors.

...                                                                 3 / 3 (100%)

Time: 421 ms, Memory: 12.00MB

OK (3 tests, 4 assertions)

テストを通過しました!(雑ですが…

ブラウザからも http://127.0.0.1:8000/api/uniqid にアクセスして確認してみましょう。 下記のように結果が返ってくることが確認できたら成功です。

うまく動かない場合は最初に行った server の起動を行えているか再度確認してみてください。

{
  "uniqid": "58905d5e13920"
}

お疲れ様でした。今回はここまでとなります。 簡単な処理と説明ではありますが何となく Laravel を利用した API 作りのイメージを持っていただくことが出来たのではないでしょうか。

冒頭でも述べさせていただいたように自身も未だまだ Laravel に不慣れなので、連載を通じて Laravel について知り、皆さんのお役に立てるような記事を書けていけたらなと思っておりますので今後共宜しくお願いします。

最後になりますが、弊社では PHP が大好きな方や、「山口に俺が Laravel を教えてやるよ!」という技術的に熱い人を大募集しています。 会社見学とかも気軽に行えるので良かったら下記のリンクから気軽にお申込み下さい。

www.wantedly.com

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 のすごさがわかっていただけると思います。

総括

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