MBProgressHUD を使ったローディング表示

iOS アプリがサーバーと通信している間ローディング表示を出すために、 MBProgressHUD を導入することにした。

MBProgressHUD の基本的な使い方。 まずサブビューに追加し、

self.hud = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:self.hud];

メッセージをセットして表示。

self.hud. labelText = @"Logding...";
[self.hud show:YES];

閉じるときは

[self.hide hide:YES];

で OK。

MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];

でも表示できるけど、中で勝手にサブビューに追加されるのが気に入らない。 ViewController 内で使いまわしたいので、メンバとして保持するようにしている。

MBProgressHUD が提供するのは、ローディング表示して閉じるだけ。 似た名前の SVProgressHUD みたいに、成功や失敗を表示する気の利いた機能は提供していない。 その代わりカスタムビューをセットできるから、自分で画像なり表示しろ、って感じだ。

SVProgressHUD っぽく使いたいので、自分は下記のようなカテゴリを作っている。

#import "MBProgressHUD.h"

@interface MBProgressHUD (Utils)

- (void)showWithStatus:(NSString*)string;
- (void)showSuccessWithStatus:(NSString*)string;
- (void)showErrorWithStatus:(NSString*)string;

@end
#import "MBProgressHUD+Utils.h"

@implementation MBProgressHUD (Utils)

- (void)showWithStatus:(NSString *)string
{
    self.labelText = string;
    self.mode = MBProgressHUDModeIndeterminate;
    [self show:YES];
}

- (void)showErrorWithStatus:(NSString *)string
{
    FAKIcon *icon = [FAKIonIcons ios7CloseIconWithSize:28];
    [icon addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor]];
    UIImage *image = [icon imageWithSize:CGSizeMake(28, 28)];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    self.labelText = string;
    self.mode = MBProgressHUDModeCustomView;
    self.customView = imageView;
    [self hide:YES afterDelay:2.0];
}

- (void)showSuccessWithStatus:(NSString *)string
{
    FAKIcon *icon = [FAKIonIcons ios7CheckmarkIconWithSize:28];
    [icon addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor]];
    UIImage *image = [icon imageWithSize:CGSizeMake(28, 28)];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    self.labelText = string;
    self.mode = MBProgressHUDModeCustomView;
    self.customView = imageView;
    [self hide:YES afterDelay:2.0];
}

@end

成功・失敗で表示するアイコンは FontAwesomeKit のものを使用。

使い方はこんな感じ。

[self.hud showWithStatus:@"Loading..."];
[self.hud showSuccessWithStatus:@"Success"];

俺の割烹

俺のフレンチ、俺のイタリアンの系列店『俺の割烹』が福岡市の中洲にオープンしていたらしい。 グルメ雑誌チェックしているのに気付かなかった。 そもそも、なんで中州に? 疑問は沸くけど、行かないわけにはいくまい。

f:id:griefworker:20140321154719j:plain

開店直後の 16 時に予約した。思い立ったのが3日前だったので、この時間しかとれなかった。 外はまだ明るい。

f:id:griefworker:20140321155743j:plain

メニュー。おすすめから攻めることにした。

f:id:griefworker:20140321155941j:plain

お通しの豆腐。 塩で食べるのは初めてだったけど、濃厚で美味。

f:id:griefworker:20140321155951j:plain

ドリンクの注文は必須みたいなので、柚子サワーを注文。 甘いお酒しか飲めないもんで。

f:id:griefworker:20140321160421j:plain

生うに伊勢海老ゼリーかけ。 うにが甘い。伊勢海老のゼリーは風味が濃い。

f:id:griefworker:20140321161155j:plain

活ごまサバ。 タレが想像していたのと違った。完全なゴマダレ。

f:id:griefworker:20140321161237j:plain

のし鮑。 のし、って何のことだろうと思っていたら、こいつが来て驚いた。

f:id:griefworker:20140321161258j:plain

鮑とうにのグラタン風って感じ。 火を通した鮑がやわらかい。

f:id:griefworker:20140321161850j:plain

宮崎牛の炭火焼。 想像以上のボリューム。 たたきみたいで、さっぱりとした醤油タレが良くあう。 赤身の部位で食べ応えアリ。 もみじおろしのピリリとしたアクセントもいい。

もうだいぶお腹いっぱいなので、最後は

f:id:griefworker:20140321165458j:plain

カニクリームコロッケ。 カニの身がたっぷり入っていて旨かった。 1個じゃ足りない。 さっきまで満腹に近かったのに、もっと食べれると思えるほど。 満腹中枢を破壊する一品。

注文しているうちに金銭感覚が狂っていって、会計は7000円オーバー。 最近の食事では一番使ったと思う。 生うに伊勢海老ゼリーかけ、宮崎牛の炭火焼、あとカニクリームコロッケが気に入った。 これらはまた食べたい。

関連ランキング:割烹・小料理 | 中洲川端駅呉服町駅天神駅

rbenv で構築した Ruby 環境で Pow を使う

サブドメインがからんだ実験を行いたいけど、そのためにわざわざドメインを取得するのはお金がもったいない。そんなわけで Rack サーバーの Pow を試すことにした。

インストールは

curl get.pow.cx | sh

で一発。

あとは

cd ~/.pow
ln -s ~/Project/rails_sample_project

という風に、$HOME/.pow 下に Rails プロジェクトフォルダにシンボリックリンクを作成すれば、http://rails_sample_project.dev にブラウザでアクセスしたとき Rails アプリが起動する。

…するはずなんだけど、Bundler::GemNotFound が発生してしまった。rbenv で Ruby 2.1.0 を global に使うようにしているけど、どうも Pow はシステムの Ruby を使っているみたいだ。

Pow が rbenv を使うようにしないといけない。そのためには ~/.powconfig を作成して、

export HOME=/Users/tnakamura
export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:/usr/local/bin:$PATH"

を記述する。

これで OK なハズなんだけど、自分のマシン(MacBook Pro & OS X Marvericks) だとそれだけじゃダメだった。Github 上の Pow のイシューを漁っていたら、どうやらマシンを再起動しろ、というコメントを発見。試しに再起動してみたら、Pow が rbenv を使ってくれるようになった。一件落着。

Git のコミットメッセージの先頭に issue の番号を書くようになった話

今まで、コミットと issue を関連付けるとき、コミットメッセージに

README を作成。close #10

という風に、末尾に issue の番号を書いてた。

「issue の番号をコミットメッセージの先頭に書いた方が、 コミット履歴を見たとき関連付いている issue の番号が先頭に並んで見やすいだろうな」とは思いつつも

close #10 README を作成。

という書き方が生理的に受け入れられなくて、今までずっと末尾に書くスタイルでやってきた。

じゃあなんで issue の番号を先頭に書くようになったかというと、つい先日、たまたま見た GitBucket のコミット履歴で

(refs #115) Display finger print on the ssh key setting page

という書き方を見て軽い衝撃を受けたから。「この手があったか!」って思った。 括弧で囲んでいるだけの違いなんだけど、見た目がタグっぽい。自分にとってはコロンブスの卵だった。

それからというもの、issue とコミットを関連付けるときはこのスタイルをマネして

(close #10)README を作成。

みたいに書いている。

wkhtmltopdf-binary-11 は Heroku 上で canvas を描画してくれない

wkhtmltopdf-binary -11でインストールされる wkhtmltopdf だと、Heroku 上で canvas を描画できなかった。(2014/03/16 時点)

Mac OS X だと描画できるのに、なぜ Heroku ではできないんだ、って思ってたけど、ソースコードを読んで納得。Mac OS XLinux で、呼び出している実行ファイルが違った。

wkhtmltopdf-binary と wkhtmltopdf-heroku では canvas を描画できることを確認。どちらも wkhtmltopdf 本体のバージョンは古いけど。

PDF を出力できる Rails アプリを作成して Heroku で動かす

Rails アプリに PDF 出力を実装して、それを Heroku で動かすまでの作業メモ。

プロジェクトを作成

rails new pdf_sample --skip-bundle

gem は vendor/bundle にインストールしたいから、bunele install はスキップして後でやる。

Heroku には git を使ってデプロイするので、git リポジトリも作成しておく。

git init
git add .
git commit -m "Initial commit"

wicked_pdf と wkhtmltopdf-binary-11 をインストール

PDF 出力には wicked_pdf を使う。

wicked_pdf は wkhtmltopdf に依存しているので、wkhtmltopdf-binary-11 も使う。 bundler で wkhtmltopdf-binary-11 をインストールすれば、wkhtmltopdf 本体もインストールされる寸法。

wkhtmltopdf-binary は wkhtmltopdf 本体のバージョンが低いので、wkhtmltopdf-binary-11 を選択した。

ruby "2.0.0"

gem "wkhtmltopdf-binary-11"
gem "wicked_pdf"

gem "sqlite3", group: [:development, :test]
gem 'rails_12factor', group: [:production]

sqlite3 は Heroku 上では使わないので、開発中またはテストのみインストールする。

あとは

bundle install --path vendor/bundle --without production

を実行して gem のインストール完了。

コントローラーを作成

bundle exec rails g controller home index

でひな形を生成し、PDF を表示するコードを記述。

class HomeController < ApplicationController
  def index
    respond_to do |format|
      format.html { redirect_to root_path(format: :pdf, debug: 1) }
      format.pdf do
        render pdf: "index",
          encoding: "UTF-8",
          layout: "pdf.html",
          show_as_html: params[:debug].present?
      end
    end
  end
end

PDF 用のレイアウトを作成

app/views/layout 下に pdf.html.erb を作成する。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">  
    <title>PdfSample</title>
    <%= wicked_pdf_stylesheet_link_tag "application" -%>
    <%= wicked_pdf_javascript_include_tag "application" %>
  </head>

  <body>

  <%= yield %>

  </body>
</html>

PDF 用のビューを作成

app/views/home 下に index.pdf.erb を作成する。中身は index.html.erb をまんまコピペ。

<h1>Home#index</h1>
<p>Find me in app/views/home/index.pdf.erb</p>

ルーティングを修正

今回は home#index をルートに割り当てる。

PdfSample::Application.routes.draw do
  root 'home#index'
end

ローカルで確認

bundle exec rails server

でアプリを起動し http://localhost:3000/?format=pdf にアクセス。

f:id:griefworker:20140313204229p:plain

PDF のビューアーで表示されたら成功。

あとは、これまでの修正を git リポジトリに忘れずコミットしておく。

git add .
git commit -m "PDF 出力を作成"

Heroku 上で確認

あらかじめ Heroku にアプリを作成しておき、git リポジトリの remote に追加。

そして

git push heroku master

でデプロイ。 データベース使わないからマイグレーションは不要。 しばらく待って、デプロイが無事成功したら、Heroku 上のアプリにアクセスしてみる。

f:id:griefworker:20140313204244p:plain

Heroku 上でも PDF ビューアーで表示されたら、めでたしめでたし。

2014/03/16 追記

canvas を描画したい場合は、wkhtmltopdf-heroku または wkhtmltopdf-binary を使った方がいい。

AFNetworking 2.x の AFHTTPRequestOperationManager でベーシック認証に対応する

ベーシック認証のユーザー名とパスワードは、AFHTTPRequestSerializer にセットすればいい。

AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:url];
manager.requestSerializer = [[AFHTTPRequestSerializer alloc] init];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:userName password:password];

AFHTTPClient から AFHTTPRequestOperationManager への移行は、思っていたよりスンナリ終わったな。