Goalist Developers Blog

読者です 読者をやめる 読者になる 読者になる

「違う、これじゃない!」Amazon EC2のリザーブドインスタンスを誤って購入したときの対処法

リザーブドインスタンス AWS Amazon Goalist

f:id:suzutt:20170126152940j:plain

はい、やってしまいました。犯人は僕(鈴木)です。

弊社ではAWSをめちゃくちゃ使わせて貰っています、300台以上のEC2インスタンスが存在します。うち、30台くらいが常時起動です。

先々月、AWSのコスト削減をしようということで重い腰をあげて、まずは数台分のリザーブドインスタンスを購入しました。
しかし、あろうことか購入するインスタンスサイズを間違えてしまったので、意図したとおりに費用削減されていないことが発覚しました。 その際の対応方法をまとめたので、参考になればと思います。*1

ちなみに、本記事に登場するリザーブドインスタンスの仕様は以下の通りです。

  • 東京リージョン
  • 料金は全前払い
  • 1年契約
  • Standardクラス
  • アベイラビリティーゾーンの指定なし

まずは簡単にAmazon EC2と、リザーブドインスタンスあたりの用語の説明から。(知っている方は読み飛ばしてください。)

Amazon EC2とは

Amazon EC2とは、Amazon Elastic Compute Cloudの略で、Amazonが提供する仮想サーバです。
使用するサーバリソースを柔軟に変更することができ、使用するサーバリソースと使用時間に応じて料金が変わる仕組みです。

aws.amazon.com

ひとつひとつのサーバのことをインスタンスといい、インスタンスにはオンデマンドインスタンスとリザーブドインスタンス等があります。*2

オンデマンドインスタンスとリザーブドインスタンス

オンデマンドインスタンスは、起動時間に対してお金を払います。つまり時間に対する従量課金です。一番ベーシックな使い方かと思います。

リザーブドインスタンスは、簡単に言うと長期間使用することを前提に、オンデマンドインスタンスよりも安い料金で使用することができるインスタンスです。弊社では、常時起動予定のインスンタンス4つに対して、1年間分、全前払いで購入しました。

Amazon EC2 リザーブドインスタンス

インスタンスタイプとインスタンスサイズ

インスタンスの性能は、そのインスタンスがどのインスタンスタイプであるかによって決まります。 例えば、m3.largeというインスタンスタイプの性能は下記の通りです。largeの部分をインスタンスサイズと呼ぶようです。

インスタンスタイプ vCPU ECU メモリ インスタンスストレージ 年間料金(オンデマンド) 年間料金(リザーブド)
m3.large 2 6.5 7.5 1 x 32 SSD $1,690.68 $950.00

詳しくはこちらを。

docs.aws.amazon.com

対応手順

お待たせしました。ここから本題です。

1. リザーブドインスタンス適用状況を確認する

まず、購入したリザーブドインスタンスが正常に使われているかを確かめました。

EC2 マネジメントコンソール>レポート>EC2 リザーブドインスタンスの使用状況 から確認できます。

https://console.aws.amazon.com/ec2-reports/?breadCrumb=EC2Console#ReservedInstanceUtilization:

すると、今回の対象は常時起動のインスタンスなので本来100%になっているはずが、そうではないことに気づきます。5%しか適用されていないものもあります。
(とはいえ、オンデマンドインスタンスに比べると、$100程度は安くなっていることがわかります。)

f:id:suzutt:20170126170036p:plain

2. 適用されていない原因を調査する

以下の順に原因を切り分けました。

  1. 対象のインスタンスを起動していない
  2. 対象のインスタンスとリザーブドインスタンスで、リージョンが異なる
  3. 対象のインスタンスとリザーブドインスタンスで、アベイラビリティーゾーンが異なる
  4. 対象のインスタンスとリザーブドインスタンスで、インスタンスタイプが異なる

今回の場合は、a~cは問題なく、dが問題であることがわかりました。
a~cが原因であればリザーブドインスタンスのパラメータを変更すれば容易に対応できるのですが、今回はそうはいかないようです。

3. 変更可能であれば、対象のインスタンスのインスタンスタイプを購入したリザーブドインスタンスと同じインスタンスタイプに変更する

ちなみに、今回は対象のインスタンスは弊社の基幹となるサーバなので、インスタンスタイプを変更することは難しいことがわかりました。
なので変更はおこなっていません。

4. 適用されていないリザーブドインスタンスのインスタンスクラスを調べる

調べたところ、リザーブドインスタンスの提供クラスによっては変更、交換ができるようなので、これができるかを検討してみました。

どうやら

のようです。

今回購入したリザーブドインスタンスは、、、

「Standard」*3

インスタンスサイズしか変更できないようです。

5. 変更可能であれば、リザーブドインスタンスのインスタンスサイズを変更する

インスタンスサイズを変更できる条件は下記サイトに載っていました。

docs.aws.amazon.com

5.1. インスタンスサイズの大きいリザーブドインスタンスを購入してしまった場合

例えば、以下のケースです。

c3.xlargeではなく、c3.2xlarge を購入していた

c3.2xlargeを2つの c3.xlarge に分割できることがわかったので欲しかった c3.xlarge を手に入れることはできます。 ただし、1つの c3.xlarge が余ってしまいますので、手順6を参照してください。

5.2. インスタンスサイズの小さいリザーブドインスタンスを購入してしまった場合

例えば、以下のケースです。

(1) m3.2xlargeではなく、m3.xlargeを購入していた

m3.xlargeをもう一つ購入することでm3.2xlargeとして使えるかと思いましたが、以下の記載の通り、追加購入すると終了日時が一致しないため変更は無理なようです。

インスタンスサイズの変更は、他の属性詳細 (リージョン、使用タイプ、テナンシー、プラットフォーム、終了日時など) が一致し、利用可能な容量がある場合にのみ許可されることに注意してください。

こちらも手順6を参照してください。

6. 常時起動しているインスタンスを調べる

常時起動しているインスタンスの中に購入したリザーブドインスタンスと同じインスタンスタイプのものがあればめでたく解決なのですが、おそらく「1. リザーブドインスタンス適用状況を確認する」で適用されていないことを確認した時点で多分ないんだろうと思います。

その場合、常時起動しているインスタンスの中に購入したリザーブドインスタンスと性能の近いインスタンスがあれば、リザーブドインスタンスタイプに合わせて変更してしまうのが良いかと思います。

例えば、c3.xlargeのリザーブドインスタンスが余っている場合、常時起動のm3.largeのインスタンスをc3.xlargeに変更すれば、スペックを落とさずに料金を安くすることができます。 この場合、年額$200弱のコストを削減できます。

インスタンスタイプ vCPU ECU メモリ インスタンスストレージ 年間料金(オンデマンド) 年間料金(リザーブド)
m3.large 2 6.5 7.5 1 x 32 SSD $1,690.68 $950.00
c3.xlarge 4 14 7.5 2 x 40 SSD $2,233.80 $1,505.00

まとめ

Amazon EC2のリザーブドインスタンスを誤って購入したときの対処法について説明しました。 いろいろ書きましたが、「3. 対象のインスタンスのインスタンスタイプが変更可能であれば変更する」の時点でAWSのサポートの方に問い合わせるのが一番いいです。最適なリカバリー方法を教えてくれるかと思います。

誤ったものを購入すると面倒くさいことになってしまうのでみなさんもお気をつけください、という注意喚起の記事でした。それでは。

*1:最後にも書きましたが、AWSのサポートの方に問い合わせるのが一番いいです。最適なリカバリー方法を教えてくれるかと思います。

*2:スポットインスタンスなんてのもありますが、よく知らないことと本記事には関係ないので省略します。

*3:3年契約のもののみCovertibleクラスが提供されているようです。今回は、1年契約のため、これを選択することはできませんでした。

Debug View Hierarchy でViewの階層構造を確認する

Goalist Objective-C Storyboard iOS swift アイドル モバイルアプリ デバッグ Xcode

ちわっす。
ブログ書いてるメンバーでもっとPV上げたいね!とか話してるのに
かなりマイナーなネタをここぞとばかりに書く渡部です。

f:id:watabe1028:20170126160206j:plain

画像は特に意味はありません。釣りです。
釣られた人残念。

今日はアプリ開発時のデバッグ時に便利なTipsを紹介します。

「Debug View Hierarchy」をご存知でしょうか?
画面のレイアウトの崩れなどを視覚的に確認できるとっても便利な機能です。

UITableViewやUICollectionViewなど、AutoLayoutや複雑な画面のレイヤの確認にもってこいです。
今回は「Debug View Hierarchy」の使い方を書いていきます。

手順

1.「Debug View Hierarchy」の起動
2.気になるオブジェクトを選択
3.オブジェクトの確認、修正

1.「Debug View Hierarchy」の起動

では、サンプル代わりに以前作ったログインサンプルを実行します。
実行すると普通に画面が表示されます。

f:id:watabe1028:20170126160451p:plain

そしてXcodeのこのボタンを押します。

f:id:watabe1028:20170126160508p:plain

本来はブレークポイントを貼ってレイヤを順番に確認することをお勧めしてます。
詳しくはこちら

この画面はピンチイン、アウトで拡大縮小し直感的に使えるはずです。

f:id:watabe1028:20170126160523p:plain

2.気になるオブジェクトを選択

今回はわかりやすくログインボタンを選択します。
選択すると右側にユーティリティエリアにオブジェクトの情報が表示されます。

f:id:watabe1028:20170126160546p:plain

3.オブジェクトの確認、修正

右側のユーティリティエリアでは以下のような項目が確認できます。

Class Name クラスの名前。今回はUIButton。
Address メモリ上のアドレス。

今回はUIButtonなので「State」「Title」「Font」「Text Color」なのでが確認できます。

f:id:watabe1028:20170126160607p:plain

まとめ

画面でつまづいたら「Debug View Hierarchy」を起動しましょう。
ユーザからしたら目に見えるものが全てなので、画面の崩れは致命的です。
なんでオブジェクトがずれるんや?と思ったらレイヤの階層を確認してみましょう。

またもやノンコーディングのネタを書いてしまいました。
面倒くさいわけじゃないんです!
ただただ楽をしたいんです!(冗談)
来週は新メンバーの初投稿があるので乞うご期待!

ささっとカメラアプリを作ってみた@Swift

Goalist Objective-C Storyboard iOS swift モバイルアプリ camera フリー素材 アイドル

コンニチハ。iOSエンジニアの渡部です。
iPhone8の情報がちょいちょい出てきましたね。
そろそろAppleの社員がバーにiPhoneを置き忘れていく時期です。
何それ?な人はググってみてください。

f:id:watabe1028:20170119152445j:plain

画像はフリー素材アイドルさんをお借りしました。

iPhoneユーザで誰もが使う機能、カメラ。
snowのような顔認識やフィルター機能はなかなかハードルが高いですが
カメラ機能を実装するのは結構簡単です。

今日はカメラアプリを作ってみます。

写真を撮って保存するシンプルなカメラです。

手順

1.info.plistでカメラが使えるように設定する
2.必要なオブジェクトを設置
3.ソースをガリガリ

カメラアプリの実行、デバッグは実機でしかできないので注意です。
ソースをガリガリといってもだいたいコピペでできますのでご安心を。
自分はファミマのミニクッキーを食べながら失礼します。

手順にプロジェクト作成は含めません。
今回もSingle View Applicationで作成します。

1.info.plistでカメラが使えるように設定する

これはそのままです。 スクショ通りに追加してください。

f:id:watabe1028:20170119152918p:plain

右側のテキストはカメラ許可を取る際に表示するメッセージです。
ここは好きな文言を設定してください。

2.必要なオブジェクトを設置

Storyboardで設置していきます。

f:id:watabe1028:20170119153153p:plain

UIViewとUIButtonを画像の通りに設定します。
UIViewはわかりやすいようにlightgrayにしてあります。

UIViewをOutletで、UIButtonをActionでソースに紐づけます。

3.ソースをガリガリ

あとはガリガリ書きます。

まずはimport、Outlet、Actionの追加です。
デリゲートの追加も忘れずに。

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCapturePhotoCaptureDelegate {
    
    @IBOutlet weak var cameraView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    /// 撮影ボタン押下時に呼ばれる
    @IBAction func cameraButtonTapped(_ sender: Any) {
    }

カメラ起動をviewDidLoadに記述します。
本当はviewDidAppearの方が適切だと思われますが今回は(面倒なので)おけーです。
viewDidLoadの前にAVCaptureSessionたちも追加します。
これがないと起動しません。

    var captureSesssion: AVCaptureSession!
    var stillImageOutput: AVCapturePhotoOutput?
    var previewLayer: AVCaptureVideoPreviewLayer?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        captureSesssion = AVCaptureSession()
        stillImageOutput = AVCapturePhotoOutput()
        
        // 解像度の設定
        captureSesssion.sessionPreset = AVCaptureSessionPreset1920x1080
        
        let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
        
        do {
            let input = try AVCaptureDeviceInput(device: device)
            
            // 入力
            if (captureSesssion.canAddInput(input)) {
                captureSesssion.addInput(input)
                
                // 出力
                if (captureSesssion.canAddOutput(stillImageOutput)) {
                    
                    // カメラ起動
                    captureSesssion.addOutput(stillImageOutput)
                    captureSesssion.startRunning()
                    
                    // アスペクト比、カメラの向き(縦)
                    previewLayer = AVCaptureVideoPreviewLayer(session: captureSesssion)
                    previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect // アスペクトフィット
                    previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
                    
                    cameraView.layer.addSublayer(previewLayer!)
                    
                    // ビューのサイズの調整
                    previewLayer?.position = CGPoint(x: self.cameraView.frame.width / 2, y: self.cameraView.frame.height / 2)
                    previewLayer?.bounds = cameraView.frame
                }
            }
        }
        catch {
            print(error)
        }
    }

撮影ボタンです。
ボタン押下で撮影します。

     /// 撮影ボタン押下時に呼ばれる
    @IBAction func cameraButtonTapped(_ sender: Any) {
        
        // カメラの設定
        let settingsForMonitoring = AVCapturePhotoSettings()
        settingsForMonitoring.flashMode = .auto
        settingsForMonitoring.isAutoStillImageStabilizationEnabled = true
        settingsForMonitoring.isHighResolutionPhotoEnabled = false
        
        // 撮影
        stillImageOutput?.capturePhoto(with: settingsForMonitoring, delegate: self)
    }

最後に写真の保存です。
今回はベタにJPEG形式で保存してます。

    /// カメラで撮影完了時にフォトライブラリに保存
    func capture(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhotoSampleBuffer photoSampleBuffer: CMSampleBuffer?, previewPhotoSampleBuffer: CMSampleBuffer?, resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Error?) {
        
        if let photoSampleBuffer = photoSampleBuffer {
            
            // JPEG形式で画像データを取得
            let photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer)
            
            let image = UIImage(data: photoData!)
            
            // フォトライブラリに保存
            UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
        }
    }

少しソースが多いですがまるっとコピペでちゃんと動きます。

起動すると・・・ f:id:watabe1028:20170119155143p:plain

先ほど「1.info.plistでカメラが使えるように設定する」で設定したメッセージが表示されます。 もちろん許可してください。

画面はこんな感じ。 f:id:watabe1028:20170119155209p:plain

撮影すると保存の許可を求めるメッセージが表示されます。 これも「1.info.plistでカメラが使えるように設定する」で設定したものです。 f:id:watabe1028:20170119155317p:plain

ちゃんと保存されてます。 f:id:watabe1028:20170119155343j:plain

まとめ

今回はカメラの起動から写真の保存まででしたが
売れるアプリにするには一工夫ないとダメです。
いずれ顔認識や色々なフィルターの記事も書こうと思います。

今まさにプライベートでカメラアプリを作っていたので
いい復習になりました。
ファミマのお菓子最高ですね。では。

Amazon Athena でS3上の求人データファイルにクエリを実行する

AWS Amazon Goalist HR データ データ分析 ビッグデータ

こんにちは、鈴木です。
今回は AWS re:Invent 2016 で発表されたAmazon Athena(以下、Athenaと記載)を触ってみた感想をまとめました。

f:id:suzutt:20170113111346p:plain

aws.amazon.com

具体的にどういうことができるのかについて知りたい場合はAWS公式ブログがわかりやすいので、読むと理解が深まると思います。

Amazon QuickSight についてまとめた記事もあるので、よかったら見てみてください。 developers.goalist.co.jp

Athenaとは

Athenaとは「サーバレスで、S3上の膨大なデータをSQLで分析できる」ツールです。

淡々と書きましたがこれってすごいですよね。

唯一必要なエンジニアっぽい技術がSQLだけですから、SQL使えるなら膨大なデータの分析ができるんですよ。
(もちろん、クロール、スクレイプ、データクレンジング、S3上への配置は事前に実施しないといけないですが)
分散処理用のもろもろ環境構築が不要ってことです。

いろいろ書きましたが、一言でいうとGoogle BigQueryのAWS版です。

利用手順

以下の手順で利用できます。めちゃくちゃ簡単です。順に説明していきます。

  1. S3上にデータ保存
  2. データベース(スキーマ)の作成
  3. テーブルの作成
  4. クエリ実行

S3上にデータ保存

2017年1月13日現在、Athenaは東京リージョンでは提供されていません。 Athenaはオレゴンリージョンで利用していますが、東京リージョンのS3のデータを使うことは可能です。

分析可能なデータ形式はこちらをご参照ください。
ちなみに今回、対象データがzip形式でs3上に保存されていたため、その状態では文字化けにより分析できませんでした。展開後、gzip形式で再圧縮することで分析できました。

データベース(スキーマ)の作成

データベースの作成前に、ブラウザ上に表示されるAthenaの画面を説明します。
赤枠で囲った箇所がクエリエディタです。ここにSQLを入力し実行することができます。
青枠で囲った箇所がクエリ実行結果が表示される領域です。

f:id:suzutt:20170113140746p:plain

ここからは、クエリエディタからSQLを実行していきます。
なお、SQLを作成するためのウィザードが用意されているので、ウィザードに沿ってデータベースやテーブルを作ることも可能です。(通常はウィザードを利用するかと思います。)

サンプルとして既にSampledbというデータベースが作成されていますが、今回は新しくデータベースを作成します。 ちなみに、Athenaにおいてデータベースとスキーマは同じ意味です。ドキュメントを見る限りテーブルの名前空間程度の理解でいいかと思います。

以下のSQLをクエリエディタから実行します。

CREATE DATABASE blogdb

テーブルの作成

作成したデータベースにテーブルを作成します。テーブルには、列名、列の型、ファイル形式、分析対象データが格納されているS3上のフォルダのパスなどを定義します。
以下のSQLをクエリエディタから実行します。こちらもウィザードを利用すればSQLを自動生成できます。

CREATE EXTERNAL TABLE IF NOT EXISTS blogdb.xxxx_sampledata (
  `target_date` string,
  `company_name` string,
  `job_type` string 
  ・・・(略)
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = ',',
  'field.delim' = ','
) LOCATION 's3://xxxx/sampledata/';

お待たせしました。以上で準備完了です。

クエリを実行する

それでは、作成したテーブルにSQLを実行してみます。

たとえば、職種大分類(job_type)ごとの求人件数について知りたいなら、以下のようなSQLをクエリエディタから実行します。

SELECT job_type,count(*) count FROM xxxx_sampledata GROUP BY job_type ORDER BY job_type DESC;

実行すると、画面下部に実行結果が表示されます。こんな感じ。

f:id:suzutt:20170113144005p:plain

以上がAmazon Athena でS3上の求人データにクエリを実行する手順になります。

その他の機能

クエリの実行結果をcsv形式でダウンロードすることも可能です。
また、今回はクエリエディタからクエリを実行しましたが、JDBCを使ったDBアクセスもできるようなので、システム間の連携もしやすそうです。

料金

2017年1月12日現在、以下のような料金体系になっています。
S3の対象バケットとAthenaのリージョンが違うと、データ転送量が高くなりそうです。

  • 1TBの読み込みごとに5USD
  • S3の使用料

詳しくはこちらをご参照ください。

まとめ

いかがでしたでしょうか。

使ってみた感想は、

  1. 元々S3上にデータを格納していた方は、データベースとテーブルを作成するだけで使用できるのはお手軽でよい。
  2. 圧縮、パーティション機能、列形式のデータに変換することで30%〜90%くらい安くなるとのことなので、できれば使うべき。 (クエリ実行時に読み込むデータが少なくなるため安くなります)
  3. S3上にzip形式で圧縮したファイルを分析する場合は、gzip形式で圧縮し直さないといけないのが面倒くさい。
    (展開後に圧縮しなくてもよいですが、料金を考えるとgzip形式にするのが普通かと思います。)
  4. テーブル作成時に列ごとに型を定義するのが面倒くさい。
    (たしかQuickSightはいい感じにやってくれたのでAthenaもそうだと嬉しい)

です。

個人的には1のメリットが大きく、AWS全体でみると、

「あとで分析に使うかもしれないデータ(形式問わず)はS3にぶちこんでおけばOK」

な流れがきている気がします。
とはいえ、サービスによって使えるデータ形式が異なるのでどの形式で保存するかは迷う所です。

すでにAthenaだけでなく、Amazon QuickSight(BIツール)や、Amazon Rekognition(画像分析)などの分析方法があるので、次は何がくるのか楽しみです。
また、現時点ではそのデータを有効利用するサービスがなかったとしても、世の中のニーズにあわせて後々提供してくれるんじゃないかなと期待してしまいます。

個人的に、今年のre:inventでは、さらにS3にデータを貯めたくなるようなサービスが発表されるのではないかと思います。
データを持っている企業がS3上にデータを置いて、ユーザにデータを提供(販売)する用のAPIを簡単に作れたりすると面白いですね〜

引き続き、AWSの情報発信をしていくので、ご期待ください。

コーディングなしで画面を作り込む方法@Storyboard

Goalist iOS swift Storyboard

明けましておめでとうございます。
iOSエンジニアの渡部です。
2017年も継続してブログを書いていきます。

f:id:watabe1028:20170105155205j:plain

最近K-1やRIZINなどで格闘技がまた表に出て来た感がありますが
渡部はムエタイ派です。肘が好き。

前々回、プロトタイプの記事を書きましたが Xcodeで作る場合に
デフォルトのUIKitだと見た目が結構しょぼくなってしまいます。
かといって、デザイナーに頼むのもコーディングするのも面倒です。

そんな時はやっぱりStoryboardを活用します。
Xib時代は使えなかったのですぐに消してましたが、Storyboardは優秀です。

そこで今回はStoryboardの渡部がよく使う小技Tipsを紹介したいと思います。
前回のMAP記事同様、すぐにできます。

サンプルとしてログイン画面を作ります。

手順

1.必要なオブジェクトを配置
2.各オブジェクトの設定をする
3.配色を決める
4.オブジェクトを角丸にする
5.UITextFieldのプレースホルダーの色を変える
6.UIButtonをリンクのような下線をつける

1.必要なオブジェクトを配置

今回はログイン画面ということでこのようにオブジェクトを配置します。

UITextField → ID、パスワードの入力
UIButton  → ログインボタン
UIButton → 利用規約等のリンクボタン

デフォルトだとこんな感じ。

f:id:watabe1028:20170105155300p:plain

ダサいですね。
お客さんには見せられません。

2.各オブジェクトの設定をする

今回はUITextFieldのみ。
ID入力はreturnキーをNextに変更。
ログインIDにはメールアドレスがよく使われるので、今回はキーボードタイプを「E-mail Address」に設定します。

f:id:watabe1028:20170105155341p:plain

パスワード入力は入力文字を隠したいので、「Secure Text Entry」にチェックを入れます。
ここにチェックを入れるだけで勝手に入力文字を隠してくれます。
また、「Secure Text Entry」にすると勝手に英数字のみのキーボードにしてくれます。
returnキーをDoneに変更します。

f:id:watabe1028:20170105155356p:plain

3.配色を決める

配色が結構大事です。
迷ったらパクればいいのです。プロトタイプなんだし。
学ぶとは真似るから来た言葉とどこかの本で読みました。学びましょう!

今回はFacebookっぽく作ってます。
文字は全て白色です。
ボタンは背景白に文字色は青っぽい色を使います。

ここで一つ追加します。
Visual Effect View with Blur → UITextFieldの背景に設置し、すりガラスっぽい見た目を作る
これでUITextFieldの背景ができるのでUITextFieldの枠を設定で消します。
プレースホルダーも「ログインID」「パスワード」を追加します。

f:id:watabe1028:20170105155518p:plain

そうするとこんな感じ。
少しそれっぽくなってきました。

4.オブジェクトを角丸にする

これも結構大事です。
色々なアプリを見てもらうとわかりますが、
オブジェクトを角丸にすることによってかなりイメージが変わります。
最近違う意味で話題になったMERYでもやってた気がします。

角丸ってコーディングするの結構面倒ですが、
Storyboardなら30秒でできます(コピぺで)!

まず、Visual Effect View with Blurから。
このプラスボタンで二つkey pathを用意して、画像の通りに入力。

f:id:watabe1028:20170105155742p:plain

これで終了です。

ちなみに「layer.cornerRadius」の値を変えれば角丸の丸具合を調整できます。

Storyboard上では変化なしですが実行するとわかります。

f:id:watabe1028:20170105155815p:plain

これを他のオブジェクトにも同様に設定します。
この方法はUIViewを継承したクラスなら全てに使えます。多分。

5.プレースホルダーの色を変える

ちょっとしたTipsですが結構便利。
UITextFieldってテキストカラーはすぐ変更できるけどプレースホルダーには設定項目がありません。
プレースホルダーの色を変更するにはこの設定を追加します。角丸と同様です。

f:id:watabe1028:20170105155848p:plain

するとこんな感じに。

f:id:watabe1028:20170105155912p:plain

6.リンクのような下線をつける

これはよく使われてますね。
UIButtonのテキストを編集します。
角丸等と少しやり方が違います。

まず、Titleを「Attributed」にし、入力テキストを全選択します。

f:id:watabe1028:20170105160020p:plain

選択したテキストの上で右クリックし、「Font」「Underline」を選択します。

f:id:watabe1028:20170105160040p:plain

すると下線が入ってリンクっぽくなります。

f:id:watabe1028:20170105160138p:plain

あとは適当に画像やアプリ名などを入れれば完成です。

まとめ

角丸、下線、プレースホルダーの設定変更などを紹介しました。
プロトタイプは早ければ早いだけ良いので、こういったTipsは結構役立ちます。
次回は画面の構成やレイヤーの確認方法などを書きます!

FlexとAngular2を比較してみた

Angular2 TypeScript Flex ActionScript

はじめまして!ゴーリスト開発の盛次(モリツグ)です。

最近社内でAngular2の勉強会を行った時に以下のようなやり取りがありました。

盛次:「Angular2とFlexってどことなく似てるから凄くいい」

鈴木:「良く分からないんで比較してブログ書いてください」

ということで、今回はFlexとAngular2を比較します。
以下のような方に向けた内容となっています。
・Flex?勤務時間の話?という方
・僕も含めた全国に100人はいると思われるFlexファン
・AlexさんがFlexJSを完成させてくれることを2年ぐらい願っている方

Flexとは

詳しくはAdobe FlexまたはApache Flexでググっていただくとして、、、
特徴は以下です
・Flash上で動くのでFlashが動けば同じソースコードでどのOS上でも同じ動作をしてくれる
・HTMLの代わりにMXMLというXMLを拡張した言語でGUIを記述する
・JavaScriptの代わりにActionScript(クラスベースのオブジェクト指向言語)を使う
・2010年にiOSがFlashに対応しないことが確定したため悲しい運命を辿った

FlexとAngular2の類似点

・MXMLの代わりに頻繁に「キモい」といわれるHTMLを拡張した記法を用いてGUIを記述する
・ActionScriptの代わりにTypeScript(クラスベースのオブジェクト指向言語)を使う。

本当にそっくりですね!

では実際にソースコードを比較したいと思います。

見た目(ボタンを押したらHello, world!)

Flex

f:id:t-moritsugu:20161222102938p:plain

Angular2

f:id:t-moritsugu:20161222102937p:plain

イベントの伝搬(Flex:dispatchEvent, Angular2:emit)

Flex

f:id:t-moritsugu:20161222112328p:plain

Angular2

f:id:t-moritsugu:20161222123959p:plain

Alertの呼び出し(Angular2のアラートは一部自作)

Flex

f:id:t-moritsugu:20161222124001p:plain

Angular2

f:id:t-moritsugu:20161222130826p:plain f:id:t-moritsugu:20161222130827p:plain

まとめ

ただひたすらソースコードを貼るという暴挙に出てみました。
Flexの経験があれば何となく雰囲気が伝わったでしょうか。
Flexの経験が無くてもコンポーネントベースで型があるぐらいが伝われば幸いです。
まだまだ「これIDEがやってくれたらいいのに」的な部分も多いAngular2ですが、使っていて物凄く可能性を感じるので広まってくれることを祈ります。

Goalist Engeneer's WAIGAYA #2 を開催しました

Goalist イベントレポート

f:id:suzutt:20161216001643j:plain

こんにちは、鈴木です。

10月に続き、11月にもエンジニアイベントを開催しましたので、そのレポート記事です。

今回は社内のメンバーだけではなくゲストスピーカー3名を迎えての開催となり、とても濃ゆい内容のイベントとなりました。

第一部「ゴーリストエンジニアが考える2020年に売れるサービス」

第一部では、社内エンジニアのみで「ゴーリストエンジニアが考える2020年に売れるサービス」について語り合いました。

それぞれが事前に考えてきた案をベースに話をするのですが、

インターネット黎明期のWebページを彷彿とさせるCTOのプレゼン資料 (下の写真)にざわついたり、

増加が見込まれる観光客向けに観光用の配馬サービス「Umar」なる奇想天外なサービスが挙がったりと

奇妙な盛り上がりをみせました。

f:id:suzutt:20161215155507j:plain

第二部に向けてのいい感じのアイスブレイクになりました。

第二部「ゲストセッション + ゴーリストエンジニアLT大会」

第二部では、ゲストセッションとゴーリストエンジニアのLT大会を開催しました。

渡部哲也:株式会社ゴーリスト モバイルエンジニア

「おまえらのアジャイル開発は間違っている」

から始まる、過去に受託開発をした際の苦労話(大人の事情で資料は公開できません)と、そこからの教訓についての話でした。
お客様の要望が仕様変更にあたるのかどうかをしっかりと線引きしないと大変なことになるようです。。

そして、この発表からの流れでゲストの阿部さんによる開発プロセスマネジメント講座が開催されました。 (リポジトリ、Issue Tracker、開発プロセスの選定について)

開発者の人数、予算などに依存するため、それぞれの環境でのベストプラクティスを見つけ出すのは大変ですが、 社内に一人、開発プロセスマネジメントに詳しい人がいると開発が捗るんだろうなと感じた次第です。

※11月から加入ということで、今回はゲスト枠での発表でした。

石川光佑さん:ちきゅう株式会社 エンジニア

ゴーリストの技術顧問的存在の石川さんです。いつも大変お世話になっています。。

セッションでは、波乱万丈な2016年を振返りつつ、起きた問題とその対処方法についてのお話でした。
CI環境を整備する話や開発の引き継ぎの話など、「大変だよな〜」と個人的にすごく共感しました。

chikyu.net

阿部信介さん:株式会社リゾーム 主任

なんと大都会岡山から上京していただきました。遠いところ、本当にありがとうございました!!

岡山でのエンジニアコミュニティの話や、ローカルにgitとDockerしかインストールせずに開発するという試みについてのお話でした。 ハードモードすぎる。。すごい。。

以下のブログにその経緯が書かれているので、是非ご覧ください。

mao-instantlife.hatenablog.com

池田大輔さん:イベントレジスト株式会社CTO

AWSのイベントでも使われた、あのイベントレジストのCTO 池田さんもいらっしゃいました。

社内の開発環境、チーム編成、プロトタイプを使った開発手法についてのお話でした。 限りなく本番に近いユーザ体験ができるプロトタイプをまず作って、そこから開発フローを回すという手法は是非ゴーリストでも取り入れたいです。

eventregist.com

ゴーリストエンジニアLT大会

最後はゴーリストエンジニアによるLTです。テーマだけ載せておきます。

  • 20代の「エンジニア女子」が絶対やるべきこと☆彡を読んで思ったこと
  • AirBnBのクロール
  • キャラクターデザインについて
  • Amazon QuickSightについて
  • metadata centric architecture(設計手法)

まとめ

今回は社外からゲストをお呼びしたことで全体的に程よい緊張感があり、社内メンバーも真剣に話を聞いていました。ゲストパワーすげーー。

あと、個人的にプロジェクト管理のベストプラクティスを模索中なので、ゲストの方々の開発プロセスマネジメントのノウハウを教えていただけたことは大変勉強になりました。ツールを使ったカンバン方式、いいですね。。ゴーリストでも導入していきたいです。

あと、誰かUmarやってください。。利用したいです。。