Cloudflare で DNS 登録したリクエストのIPアドレスがカンマ区切りになる

heroku + Rails5でアプリケーションを開発し、リクエストを受ける前段に Cloudflare を利用している。
Cloudflare は DNS, Crypto で SSL, CDN の設定を利用している。

しかし、 Cloudflare を使い始めたからか IPアドレスが validation エラーになってしまった。

デバッグして中身を見ていると、IP アドレスが以下のようになっていた。(前半の IP は書き換えてる)

p ip_address = request.env['HTTP_X_FORWARDED_FOR'] || request.remote_ip
# => "100.10.10.150, 103.22.200.116"

カンマの前半が実際のユーザの IP アドレスで、後半が Cloudflare の IP アドレスっぽい。
103.22.200.116 - Japan - Cloudflare - IP address location and data

ユーザの IP アドレスを取得したかったら ip_address.split(",")[0] でいけると思うけど、だいぶ不安だ...。

特定の UITableViewCell だけ separator の線消したい

tableView で この cell だけ separator 消したいよ〜 という時の方法。

ググると、全ての tableView の separator 消して追加したいやつだけ追加するコード書こうとか、全部の tableView の線を消す方法とか出るけど、特定の cell だけ separator 消す というのをしたい。

やり方

import UIKit

class HogeTableViewCell: UITableViewCell {
    static let height: CGFloat = 88

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    convenience init(_ separatorInsetLeft: CGFloat) {
        self.init(style: .default, reuseIdentifier: nil)
        separatorInset = UIEdgeInsets(top: 0, left: separatorInsetLeft, bottom: 0, right: 0)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

separatorInset の left を画面右端にすると、線が見えなくなる。

使い方

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return FooterTableViewCell(view.bounds.width)
    }

これでいける、register nib している場合は init じゃダメだと思うので cell.separatorInset = ... で書けばいけると思う。

RxSwift をやる前にちゃんと Observer パターンを学ぶ

RxSwift やるぞ!と思ったはいいものの、ちゃんと Observer パターンを学んだことがなかったので Swift でゼロから書いてみる。

Observer パターン

観察者が何かを監視していて、その監視対象に更新があった際に観察者に通知が届く仕組み。

Subject が監視対象で、 Observer が観察者。
RxSwift でも PublishSubject とか出てくるし、 Observable とかも Subject に該当するのかな? (まだ RxSwift を理解できてない)

実際に書いてみる

Observer パターン - デザインパターン入門 - IT専科 を参考に Swift にしていく。

1. Observer protocol

観察者のインターフェースの protocol を作る。
id は後述するが、 Observer を削除するときに必要になる key みたいなもの。

protocol Observer {
    var id: String { get }

    // Subject からの通知が届く
    func update(_ string: String)
}

extension Observer {
    func update(_ string: String) {
        print("\(type(of: self)) に届いた新しい値は \(string) です。")
    }
}

2. Subject protocol

observers が mutating なため、 class を継承している。

protocol Subject: class {
    // 観察者リスト
    var observers: [Observer] { get set }

    // 観察者を追加する
    func add(_ observer: Observer)

    // 観察者を削除する
    func remove(_ observer: Observer)

    // 観察者に更新を通知する
    func notify(newString: String)
}

extension Subject {
    func add(_ observer: Observer) {
        observers.append(observer)
    }

    func remove(_ observer: Observer) {
        for (index, registerdObserver) in observers.enumerated() {
            // observer.id が登録済みだった場合削除する
            if registerdObserver.id == observer.id {
                self.observers.remove(at: index)
            }
        }
    }

    func notify(newString: String){
        print("新しい値 \(newString) を observer に通知します。")
        observers.forEach { observer in
            observer.update(newString)
        }
    }
}

3. 具象クラス

Observer は id を UUID で作成して重複しないようにしている。

final class SubjectA: Subject {
    var observers: [Observer] = []
}

final class ObserverA: Observer {
    var id = UUID().uuidString
}

final class ObserverB: Observer {
    var id = UUID().uuidString
}

(本当はシステム的に UUID を id にするようにしたほうがよさそうだけどサボる)

4. 実際に動かす

observerA と observerB が subjectA を監視する。
途中で observerB が監視をやめる。

let subjectA = SubjectA()
let observerA = ObserverA()
let observerB = ObserverB()

subjectA.add(observerA)
subjectA.add(observerB)

subjectA.notify(newString: "New!")
// -> 新しい値 New! を observer に通知します。
// -> ObserverA に届いた新しい値は New! です。
// -> ObserverB に届いた新しい値は New! です。

subjectA.remove(observerB)
subjectA.notify(newString: "New!!!!!!!!!!!!!!!")
// -> 新しい値 New!!!!!!!!!!!!!!! を observer に通知します。
// -> ObserverA に届いた新しい値は New!!!!!!!!!!!!!!! です。

想定通りの動作になった。

全コード

Gist - Swift observer pattern.

感想

実際に書いてみて、 Subject や Observer などの関係性などが理解できてよかった。

とはいえ Observer パターンはそんなに難しくないしゼロから書くほど価値はあまりないしちょっと時間の無駄だった感ある、KVO でやればこんな書かなくて良いしな!!!!!!!

Google Analytics と Firebase を同時に使うとき、 1 つの GoogleService-Info.plist で管理する

GoogleService-Info.plist

何も考えずに Google Analytics と Firebase をアプリに導入しようとすると、それぞれ別で Project を作成して、GoogleService-Info.plist も 2 つ生まれてしまう。
2 つあったとしても読み込む plist はそれぞれ設定できるので問題ないといえばないが、管理などがややこしくなる。

それを 1 つで管理する方法があるので、その方が便利。

ここでは、 iOS アプリに GA と Firebase を組み込んでいきます。

Google Project の作成

iOS アプリにアナリティクスを追加する  |  iOS 向けアナリティクス  |  Google Developers

この手順の「設定ファイルを取得する」項に 設定ファイルを取得 ボタンがあるので押す。

f:id:star__hoshi:20170109093051p:plain

そうすると、 「Create or choose an app」 画面が開く。

Create or choose an app

アプリ名、 bundle id など入れていく。
入れたら Choose and configure services を押す。

f:id:star__hoshi:20170109093202p:plain

Choose and configure services

Analytics を選択し、 Property を作成にして ENABLE ANALYTICS SERVICE を押す。

f:id:star__hoshi:20170109093427p:plain

Generate Configure Service は無視して画面を閉じて良い。

Firebase でインポート

(Firebase に登録していない人は登録が必要。)

Firebase Console を開いて、中央右らへんにある GOOGLE プロジェクトをインポート を押す。

追加ダイアログの選択肢で先ほど作成した sample を選択して FIREBASE を追加 する。

f:id:star__hoshi:20170109093943p:plain

追加すると Firebase Project に追加される。

設定ファイルのダウンロード

左上の歯車から プロジェクトの設定 を選択し、 GoogleService-Info.plist を DL する。

f:id:star__hoshi:20170109094208p:plain

設定ファイルを確認

Firebase からダウンロードした設定ファイルでも、 GA の TRACKING_ID が挿入されている。🎉

...略...
    <key>TRACKING_ID</key>
    <string>UA-44007234-21</string>
...略...

あとは GA も Firebase も普通の手順でやれば OK!!!

APIGateway + Lambda + NodeJS で rest api を作る

AWS 全然使ったことなくて Lambda とか全くわからなかったけど1時間くらいで API 公開まで行けた。
このままだとやり方忘れちゃいそうなのでメモ。

AWS Lambda

Get Started Now

まず AWS にログインして、 Lambda を選んで Get Started Now する。
次に、 blank function を選択する。

そうすると Configure triggers という画面になるが、ここは気にせず Next を押す。

Configure function

Name に適当に名前入れる、とりあえず test とか入れておけば良い。
Runtime は Node.js を選ぶ。

Lambda function code

コードはこんな感じで書く。

exports.handler = function(event, context, callback) {
  console.log('"Hello":"World"');
  const response = {
    statusCode: 200,
    headers: {},
    body: JSON.stringify({ "message": "Hello World!" })
  };

  callback(null, response);
};

API Gateway と連携させる場合、 statusCode や body などが必要。

参考: プロキシリソースのプロキシ統合を設定する - Amazon API Gateway

Lambda function handler and role

ロールはなければ作る。
Create new role from template(s) を選んで、 Role name を適当に入れる。
適当だから admin などにした。

他は無視して Next する。

Review

内容確認して Create function する。
これで Lambda 関数が作られる、簡単!!!!!!!!!!

Test

画面上の方に Test があるので押してみる。
json の中身は変えないで Save and test を押す。

以下の json が返って来れば成功!

{
  "statusCode": 200,
  "headers": {},
  "body": "{\"message\":\"Hello World!\"}"
}

API Gateway

次は Rest API として叩けるように API Gateway と連携させる。

Get Started Now

Get Started Now を押すと サンプル API の作成 など出るが無視して OK を押す。

画面上にある、 ◯ 新しい API をクリック。

API 名 を適当に入れる。
適当だから api にした。

リソースの作成

API のエンドポイントを作る。
画面左上にある アクション > リソースの作成 を選択。

リソース作成画面になるので、リソース名を test とかで リソースの作成 を押す。

そうするとリソースが作られる。
画面には リソースにはメソッドは定義されていません。 などと出てくる。

メソッドの作成

アクション > メソッドの作成 を選ぶと、 メソッドを選ぶ選択肢が出てくる。
GET を選んで ✅ を押す。

GET - セットアップ

統合タイプ: Lambda 関数、 Lambda リージョン は適当に us-east-1 を選ぶ。

そうすると Lambda 関数の入力欄が出るので、そこで先ほど作成した test を入力し、保存 を押す。

Lambda 関数に権限を追加するOK を選択。

メソッドの実行

箱が 4 つ並んでる画面が出てくるが、画面左上の テスト を押す。
メソッドテスト画面に遷移する。

画面下にある ⚡️テスト ボタンを押す。
下記 json が返って来れば OK!

{
  "statusCode": 200,
  "headers": {},
  "body": "{\"message\":\"Hello World!\"}"
}

API のデプロイ

最後にデプロイして外から叩けるようにする。

アクション > API のデプロイ を選択。

  • デプロイされるステージ
    • [新しいステージ]
  • ステージ名
    • test (なんでもよい)

で入力し、 deploy する。

API 実行確認

画面上に URL の呼び出し: https://hoge.execute-api.us-east-1.amazonaws.com/test みたいなの書いてるので、これに先ほど決めたリソース名の /test を追加しアクセスしてみる。

{
  statusCode: 200,
  headers: { },
  body: "{"message":"Hello World!"}"
}

と返って来れば成功!!!!!

感想

めっちゃ簡単に Lambda 使えて最高である、これだけ手軽に使えるとスマホアプリでちょっとサーバでやりたいこととか Lambda でできて良い。

しかも一ヶ月 1,000,000 件リクエストまで無料である、強い。

WKWebView で target = _blank と POST の組み合わせ注意

target = _blank かつ POST リクエストの際に画面が表示されないバグを出してしまったので気をつけないといけない。

WKWebViewでtarget="_blank"なリンクが開かない時の対処法 - Qiita のコメント欄で注意喚起がされている。

target="_blank" を強引にメインのwebViewにロードさせる場合は注意が必要です。
例えばイベントサイトのATNDで参加登録をした時、
メインフレームで参加登録リクエストが投げられ、別ウィンドウでTwitterへの投稿画面が開かれようとします。
このとき、別ウィンドウで開かれようとしているTwitterへの投稿画面を、
参加登録リクエストを送信するはずだったwebViewに読み込ませてしまうと、
肝心の参加登録処理が実行されないままになってしまいます。

つまりどういうこと?

注意1. target = _blank

WKWebView で target = _blank を開くことができないので、下記のように自力で load request を送る必要がある。

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard navigationAction.targetFrame else {
        webView.load(URLRequest(url: url))
        decisionHandler(.cancel)
        return
    }
    decisionHandler(.allow)
}

注意2. WKWebView で POST パラメータが空っぽ

webView.load(URLRequest(url: url)) では POST のパラメータが消えてしまう。
実際に iOS Simulator + Safari Debug で確認した。

これをアプリ側でどうにかするためには、

  1. request が POST か判定
  2. POST だったらネイティブ側で Request を発行し HTML を取得 (API を叩く感じ)
  3. その返り値を WKWebView にセットする

つらい。

参考: WKWebViewでNSURLRequestをPOSTするとヘッダーが消える問題(解決) « TORQUES LABS

なので

  • 社内サービスで調整できる場合
    • Web の人に iOS でアクセスきた時は target = _blank 外してくれという話をする
  • 社外サービスでどうしようもない時
    • がんばってネイティブ側で HTML 取得する

という対策をとる必要がある。

そもそも

アプリで WebView を使うのやめようぜ!!!!!!!!!!!!!!!!!!!

2016年振り返り

今年あったことを書き起こしていったら怪文書のようになってしまった。

2016 年振り返り

まとめ

2016年初めに「去年は仕事以外何もしなかったから、今年はひたすらアウトプットし続けるぞ」と誓った記憶がある。
振り返ってみると、そこそこアプリを作ったし GitHub に9割がた草も生えた。

f:id:star__hoshi:20161225211440p:plain

個人開発、チーム開発、転職など色々あったが良き一年だった。

2016年あったこと

1月

SEKITORI 〜 ニコ生で座席を確保する という iOS アプリを開発していた。
Swift で初めてリリースしたアプリ。

この時ニコ生見るのにひたすらハマっていた。

2月

Alcatraz Search | Search Alcatraz more better. という Web アプリを作った。
Xcode Plugin を探しやすくしたかったが、Xcode 8 で Plugin が使えなくなったので価値がなくなった。

実際は何のために作ったかというと React を使ってみたかった、という以外にない。

React + Redux + TypeScript でWebアプリを作った感想・勉強法と Angular との比較 - Qiita という記事を書いて、結構バズって嬉しかった。

3月

ピーちゃん 〜 Unofficial esa.io Client. という esa.io の iOS クライアントアプリを開発した。

このときくらいから会社の先輩と一緒にサービスを作り始める。

4月

会社の先輩と始めたサービスを本格的に作り始める。
一緒に開発している先輩が Android で、私は Rails + iOS 担当で、アドバイザー的な人が一人いて3チームでスタートした。

このときから Rails を学び始め、仕事で Java を使っていたが Rails 最高じゃん... という気持ちになる。

5月

会社のオフィスが移転した。
移転したオフィスがひどくて、この会社は従業員に気持ちよく働いてほしいという気持ちがないんだと思い、今までの会社に対する不満のタカが外れ転職活動を始める。

会社の先輩と作っているサービスは、既存サービス調査が甘く、開発開始から3か月くらいたって超強豪がいることを知りピポッドする。

この後はどういうサービスにするかブレまくり、毎週ピポッドすることになる。

6月

26 歳になる。

転職活動が本格化し、週2回で仕事終わりによその会社の話を聞きに行く。
家で開発する体力が削られだいぶつらかった。

開発中のサービスはブレまくり毎週のようにやることが変わっていった。
でもそうやっていろいろな可能性を探してくのは楽しいし、必要なことだと思って毎週何時間も話し合ってた。

7月

内定が出る。
いま内定が出ている会社に行くのか、それとも現職に残るのか、もっと他の会社に行くのか考える。
現職に留まるのはないな、と思いとりあえず上司に転職する旨を話し了承を得る。
いろいろ考え、 Classi というサービスの会社に入社する。

開発中のサービスは、先月と同様どうするか話し合い作ってみては壊し、作ってみては壊すという感じ。

8月

9月13日くらいが最終出社日に決まる、最後の仕事はインターン受入れで、辞めるやつがインターン受入れしていいのか...という気持ちだったが、まあ最後まで頑張ろうと思い受入れの準備をする。
受入れで Swift やりましょうという話になり、初めて仕事で Swift を書く。

開発中のサービスは依然として作っては壊し作っては壊す。
その過程で Rails についていろいろ学び、 Rest とは... と悩むことになる。

ハッカソンOPanimED というアプリを開発し、勢いでそのままリリースする。

9月

インターンの受入れをして、職務を終える。9月後半は有給モードに入る。
退職エントリ を書いたら、内輪向けに書いたはずがブクマたくさんついてビビった。

転職先で iOS やるので Objective-C も勉強しておこう、と思い勉強して アプリを1本リリース する。

会社の先輩と話していたサービスは寿司を食べながらやることが固まり、ドメイン取ったりする。

10月

10月中旬から転職先で iOS エンジニアとして働くがそんなに知識もないので、10月前半はひたすら iOS + Swift の学習をする。

転職先は椅子が悪くなったこと以外すべて前職より良くなっており逆に困惑する。

11月

仕事で新規アプリを作ることになり開発を始めるが、既にリリース済みのアプリでクラッシュが多発しそれを調べたりするので進捗が出ずエモい気持ちになる。
また、ObjC だの Swift だの開発方法だの色々とあり、転職先の良くない点も理解する。

ポケモン新作が発売された こともあり、Rails は完全に手付かずになってしまう。

12月

仕事ではクラッシュ問題が解決され進捗が出るようになる。
転職先は良い面もあれば悪い面もあるけど、楽しく働けているし貢献できるように頑張るぞいという気持ちになる。

12月前半はポケモンばかりやっていたが、12/21 に前職のサービス作ってた人たちと会い、やっていきの気持ちを取り戻す。

2017年

2016年の反省として、個人的なアウトプットは色々としたが、勉強会に出たりなどはしてないので来年は登壇したい。
また、書籍も全然読まなかったので今年はインプットもやっていきたい。
仕事もやるし、家でも開発するし、本も読みたいしで、多分本を読むというのがおそろかになる気がするが、どれも頑張る気持ちで2017年やっていきたい。

会社の先輩と作っているサービスは年初にリリースするぞという感じで、そのサービスがウケるかわからないけど、
「作ってダメだったけど勉強になってよかったね」では悔しいのでなんとかして軌道に乗せたい。

来年一年間もどうぞよろしくお願いします。

Rails5 で WebSocket を ActionCable でなく Firebase でやった話

Ruby on Rails Advent Calendar 12日目です!

私は仕事では iOS を Swift を書いていて、個人開発でサーバサイド APIRails で書いています。

そこで WebSocket を使いたいと思い ActionCable でやろうとしてたのですが、 Firebase でもいけるんじゃねと思いやってみたらかなり良かったため、その話をします。

ただ書いている途中で知ったのですが、悲しいですが現状この方法は Firebase から推奨されておらず後で使えなくなる可能性がありますので、利用しない方が良さそうです。。。 😢

f:id:star__hoshi:20161211184034p:plain

要件: タイムラインを形成したい

Twitter を想像してもらえれば良いです。
ユーザが何かを投稿して、それをみんなで見る、そのタイムラインを形成したいという要件でした。

ただし今回は、そのタイムラインに即時性はあまり重要でなく、それよりも断続的に投稿され続ける情報をリアルタイムで眺められるようにしたい、というのが実際にやりたかったことです。

仕組み

ユーザ(クライアント)が POST
    ↓
Rails が受け、 POST 内容を DB に書き込む
    ↓
DB に書き込んだ情報を Firebase に投げる
    ↓
Firebase が受け、クライアントに反映
    ↓
クライアントが Firebase から情報を受け画面に表示

という流れでやっています。
ユーザが Post するのは Rails サーバに対してですが、タイムラインを表示するためにクライアントは Firebase から情報を取得する、という流れになっています。

この流れのメリット

実装の簡略化

Rails 側は WebSocket 周りを何も気にすることがなく、普通に Rest API を作成し、その処理の一部に Firebase に情報を横流しする、というフローが増えるだけです。

クライアント実装が楽に

クライアント側は Firebase SDK を使えば良いため Socket 周りの実装を自力でやる必要がありません。
オフライン時の処理や再接続なども Firebase さんがいい感じにやってくれています。

また、Firebase SDKiOS/Android/JS など幅広く対応されており知見も共有できます。

お金も安い

Firebase Pricing
100 人まで同時接続、データベースは 1 GB まで無料で利用できます。

有料になったとしても $25 per month で 10,000 人 まで同時接続数を増やせますし、同時接続の初期制限値 10,000 を解除できるよう努力しております。 と言っているため今後もっと増えるのではないでしょうか。

スタートアップなどではまず このサービスには価値があるのか というのを検証したいと思うので、ある程度までは無料でまかなえるのは良いのではないでしょうか。

実装

Firebase の設定

Firebase Analytics を iOS / Android アプリに導入する手順のまとめ などを参考に、 Project を作成しましょう。

作成したら Project の作成 -> サービスアカウント -> データベースのシークレット からシークレットを取得します。 このシークレットが冒頭に述べた非推奨となっているところです。

秘密鍵json で管理する方法に変わっているようですので、その鍵で通信できれば同様の方法でいけると思いますが、未検証です。。

Rails 側の設定

gem 'firebase' を Gemfile に書き、 bundle install しましょう。

そしたら、 firebase に送信したい場所で以下を書きます。

  def create
    # DB 登録処理など

    base_uri = 'https://project-xxxxxxxxxx.firebaseio.com/'
    secret_key = 'yyyyyyyyyyyyyyyy'
    firebase = Firebase::Client.new(base_uri, secret_key)
    timeline = {title: "timeline"}
    firebase.push('timeline', timeline)
    render :create, status: :created
  end

わかりやすく create メソッドの中でやっていますが、本来ならば worker などをを使い非同期でやるべき処理です。

結果

f:id:star__hoshi:20161211184252p:plain

データを反映することができました。

最後に

データベースのシークレットを使う方法が非推奨となっており、大変残念な記事となってしまいました 😢。
が、 WebSocket の一つの手段として Firebase は有用だと思います。

特に、サービス立ち上げに時間をかけたくない時など、要件があれば検討してみてください。

さよなら So-net、今までありがとう

この記事は interlinkアフィリエイトなど全く利用していない、 PR でも何でもない個人の日記です。

最近の回線速度

Testing download speed........................................
Download: 0.56 Mbit/s
Testing upload speed..................................................
Upload: 13.44 Mbit/s

この数字本当にふざけてるし、通信速度制限かよという感じでアニメもろくに見れず、画像の表示にも時間がかかり、ひたすら頭にきていたので試しにプロバイダを interlink に変えてみた。

interlink は 2 ヶ月無料で違約金もなし、まずサービスを体験してみてよかったら継続してほしい、もし辞めたくなったらいつでも辞めてね、という健全なサービス体系である。

interlink 自体は ソフトバンク光はクソ - 日報2016-09-12 r7kamura さよなら、エキサイト - 日報 などで知った。

変えた結果

Testing download speed........................................
Download: 32.01 Mbit/s
Testing upload speed..................................................
Upload: 33.31 Mbit/s

何も文句はありません、今までみたいに動画が読み込めないということもないだろうし、快適なインターネット生活を送れるだろうと思う。

プロバイダを乗り換えてまだ 1 時間しか経っていないため今後不満などでてくるかもしれないが、不満が出たらまたブログに書く。

愚痴

ISP 並びに携帯キャリアなどの通信業界は、顧客と真摯に向かい合ってサービス提供してほしい。

  • キャッシュバックで客を釣るが受取期限がある
  • 契約月以外で解約すると違約金が発生する
  • 初月無料オプションなどをつけさせ、解約忘れで料金を取る

など、こんなことで金を儲けようとしないでほしい。

インターネットを契約したい人は大概がインターネットに接続したいだけで、そこにウイルスソフトやら動画視聴サービスやらのオプションなどは求めていない。

そんなことより繋がらない電話窓口、わけのわからない FAQ 、使い勝手の悪い管理画面をなんとかしてくれ。

土管屋は土管屋に徹してほしい、私からは以上です。

転職しようか迷っているキミへ

転職 Advent Calendar 2016 17 日目です!
この記事を公開しているのは12/8なので完全にフライング、今日読んでもらいたい相手がいるので公開しますが、問題あれば消します。

記事を書くきっかけ

友人とメシを食べて、転職するかどうするか〜みたいな話をしていた。
自分は今年の10月に転職したばかりなので、迷っているのは話し相手の方である。

いろいろ話した後に歩きながら「転職活動それ自体のメリット」など話せば良かったなと思ったので、相手に伝えるとともに自分の思いを公開する。

転職活動のメリット

転職というと職場環境が変わり最高 という話もあるが、それとは別に 転職活動という行為それ自体 が自分自身にとって大変良かった。

転職活動をすると、自分の市場価値を図ることができる。

  • 現時点の自分の価値は果たしてどれだけのものなのか?
  • 自分が培ってきたスキルや仕事への姿勢などは、他社ではどのように評価されるのか?

という 現実 を知る良い機会になる。

自分の経験

私は2014年にとある会社に新卒入社して、しばらく働いてこりゃ厳しいと思って、2015年2月くらいに転職活動をした。
厳しい理由は 転職することにした に書いてある。

転職活動では、個人開発でアプリをいくつか出していて、ダウンロードも結構あったしユーザ評価も良かったのでそこらへんを武器にいけるかな〜と思ってやっていた。
でも残念ながらその時は自分を求めてくれる会社にはめぐり合えず、5社くらい面接受けたけど全部落ちた。

(そのあと会社で「スマホアプリの開発案件あるんだけどやらないか」という話があり、それならもうちょっと頑張るかと思って転職活動は辞め仕事を頑張ることにした。)

転職活動で得たモノ

転職活動としては失敗だったけど自分としては得るものがたくさんあって、ざっくり以下のようなことを得ることができた。

  1. 個人でアプリを作っていて、DL が n 万あるのでまず話は聞いてくれる
    • 個人で n 万DLとかは割とインパクトがあり、話のきっかけとしても言いやすい
  2. ただし、今の自分は客観的に見て求められる人間ではないという現実
    • 個人開発のインパクトはあるが、アーキテクチャとかは何もなかったのでボロボロ
    • 業務について聞かれても、業務で得たものは他社ではあまり役に立たないことが多かった
      • その会社 での業務には必要な情報だが、 その会社以外 では役に立たない知識が多かった
  3. 自分のことを理解してもらえたのかという不安
    • 話終わった後に、こういうこともやってたし話せばよかった など思ったりする
    • アウトプットがなく実績も示せない

上記の現実を突きつけられたあとは、汎用的なスキルやアーキテクチャなどを学んだり Qiita やブログにノウハウを投稿したり GitHub にソースをプッシュしたりと、そこらへんを念頭に置き勉強などをした。

そして2016年5月にまた転職活動をしたのだが、いろいろやっていたおかげかいい感じに転職先が決まり、とある会社に勤めている。

何が言いたいかというと

2015年に転職活動に失敗していなければ今の会社に転職できていたか怪しい。

転職するかは置いておいて 自分の現時点での立ち位置自分が客観的に求められる人材なのか というのを確かめるために転職活動をするのは良いことだと思う。
転職活動をするだけなら損はない。(可処分時間は使うことになるけど)

その結果内定などが出たら、現職との比較や他の会社も見て、自分がどうしたいか考えれば良いと思う。

これを読んでいるキミはエンジニアではないかもしれないし、アウトプットなどはピンとこないと思うけど、今後どういう人生を歩むかの良い機会になると思う。

とりあえず気軽にその一歩を踏み出してはどうでしょうか。