ホーム > タグ > iPhone

iPhone

Picup を利用して Rails アプリに iPhone / iPad から画像をアップロードする

ご存じ iPhone / iPad のブラウザである Mobile Safari は、HTML5 の機能を多数実装してるわりに、<input type=”file” /> を使ったファイルのアップロードができない。

もちろん専用のネイティブアプリを作成すれば可能だけど、まあ、ほとんどの場合めんどくさいよね。

そこで、多少ユーザを選ぶけど、便利そうなのが William Lindmeier 氏制作の iOS アプリ Picup である。

ここでは、Picup の仕組みと、Rails アプリでの実装例を紹介する。

Picup の仕組み

iOS や MacOS (X?) では、URL スキームにアプリケーションを関連づけられる。Picup の場合 fileupload:// に続けて、アプリに渡したいパラメータをつけて Safari 等で開けば、Picup にパラメータが渡され起動する。

サーバ側では、Picup の Web サイトで配布しているスクリプト (picup.js) を利用して、<input type=”file” /> を、fileupload://… を開くボタンに書き換える (別にこのスクリプトを使わなくても fileupload://… へのリンクを自前で作ってもいい)。

このボタンがクリックされると、POST 先の URL (postURL)、フィールド名 (postImageParam) などのパラメータを渡して Picup が起動される。そして、Picup 上で、ユーザーが、カメラで撮影するか既存の写真を選択し、Done をタップすると、さきほど渡されたパラメータをもとに POST してくれる。

さらに、callbackURL を指定すると、POST 後に任意の URL を Safari で開くこともできる。その際に # 以降にいくつかパラメータが渡されるので、それを利用して、ユーザーを誘導することもできる。

Rails での作例

以下では、Ruby 1.9.2 + Rails 3.0.7 + carrierwave で Picup による写真のアップロードに対応した Rails アプリを作る。

とりあえず初期設定。

$ rails new picup_demo -d mysql -J # Gemfile - gem 'mysql2' + gem 'mysql2', '0.2.7' + gem 'carrierwave' + gem 'jquery-rails' $ bundle $ rails g jquery:install

jquery や後述の picup.js をロードするようにする。

# app/views/layouts/application.html.erb - <%= javascript_include_tag :defaults %> + <%= javascript_include_tag :all %>

写真のモデル・コントローラ・ビューを scaffold でつくる。

$ rails g scaffold photo file:string $ rake db:create $ rake db:migrate

アップローダをつくり、photos.file に設定する。

$ rails g uploader photo # app/models/photo.rb class Photo < ActiveRecord::Base + mount_uploader :file, PhotoUploader end

フォームのフィールドを、type=”file” にする。show で写真を表示する。

# app/views/photos/_form.html.erb - <%= form_for(@photo) do |f| %> + <%= form_for(@photo, html: {multipart: true}) do |f| %> - <%= f.text_field :file %> + <%= f.file_field :file %> # app/views/photos/show.html/erb - <%= @photo.file %> + <%= image_tag(@photo.file.url) %>

この時点で PC の Web ブラウザからアップロードできるか確認しておくとよい。

$ rails s # http://localhost:3000/photos/new へ Web ブラウザでアクセス

Picup のヘルパースクリプトを導入。http://picupapp.com/picup.js.zip をダウンロード、展開し、picup.js を public/javascripts 下に移動する。

type=”file” のフィールドを Picup を開くボタンに置き換える。

# app/views/photos/_form.html.erb <script type="text/javascript" charset="utf-8"> $(function(){ window.name = "Picup_demo_new_photo"; // アップロード後表示されるページから遷移するためにウィンドウ名をつけておく Picup.convertFileInput( "photo_file", // <input type="file" /> の ID { 'referrername': escape('Picup Demo'), // Picup に表示されるアプリケーション名 'purpose': escape('Upload A Photo'), //Picup に表示されるメッセージ 'postImageParam': 'photo_file', // フィールド名、この場合、rails では params[:photo_file] でアクセスできる。 'postURL': 'http://192.168.1.10:3000/photos.json', // post先 'callbackURL': 'http://192.168.1.10:3000/uploaded' // アップロード後に開く URL } ); }); </script> # app/controllers/photos_controller.rb def create - @photo = Photo.new(params[:photo]) + @photo = Photo.new(file: params[:photo_file])

IPアドレスは適当に書き換えて。 ここまででとりあえずアップロードはできる。 (アップロード後表示されるページは RoutingError になっちゃうけど、/photos を見ると、正しくアップロードできているのが確認できる)

アップロード後、アップロードされた写真のページへ遷移させたいので、create のレスポンスに、そのページの URL を含ませる。

# app/controllers/photos_controller.rb format.html { redirect_to(@photo, :notice => 'Photo was successfully created.') } format.xml { render :xml => @photo, :status => :created, :location => @photo } + format.json { + imgur_like_response = { + rsp: { + stat: "ok", + image: { + original_image: photo_url(@photo) + } + } + } + render :json => imgur_like_response + }

{rsp: …} となっているハッシュは、imgur に画像をアップロードした際のレスポンスを模したものである。いままで触れなかったが、Picup は postURL の指定がない場合、imgur.com に画像をアップロードする。その際、レスポンスに含まれる original_image の値は、アップロード後開かれる URL の # 以降に remoteImageURL=… の形で渡される (imgur.com からのレスポンスでは他にもいろいろな情報が付与されているが、無視されている)。

# public/uploaded.html <!DOCTYPE html> <html> <head> <title>Picup Demo</title> <script> <!-- var redirect = function() { var keys_values = window.location.hash.substring(1).split("&"); var params = {}; for(var i = 0; i < keys_values.length; i += 1){ var key_value = keys_values[i].split("="); params[key_value[0]] = key_value[1]; } if (params.remoteImageURL) { window.open(unescape(params.remoteImageURL), 'Picup_demo_new_photo'); window.close(); } }; redirect(); //--> </script> </head> <body> <h1>アップロード完了</h1> <a href="javascript:redirect();">自動的に移動しない場合はここをタップしてください。</a> </body> </html>

これが、アップロード後開かれるページである。URL の # 以降の remoteImageURL=… の値を読み出し、もともとフォームを表示していたタブ (Picup_demo_new_photo) で開き、このページ自身は閉じるようにしている。いちおうこれで、PC のブラウザからアップロードした際と似た挙動を実現できる。

なお、<input type=”file” /> の置き換えを、UA が Mobile Safari であることを確認した上で (Apple 公式の DetectingWebKit を使えば簡単) 行えば、PC のブラウザでも Mobile Safari でもほぼ同じように使える。

気になるところ

先述のとおり Picup.convertFileInput には postImageParam オプションで、送信されるファイルのフィールド名を指定できる。ここは、Rails の規約に従って photo[file] としたいところだが、実際に試してみると、Rails にはフィールド名が photo%5bfile%5d として渡されてしまい、params[:photo][:file] のようなかたちではアクセスできない。無用なエスケープがされちゃってるんですね。ちょっと残念。

あと、POST のレスポンスをもうすこし利用できるとうれしい。imgur のレスポンスに特化してるのがもったいない。

iBooks で日本語の辞書を引くように EPUB ファイルを変換するスクリプト

iPhone / iPad などの iBooks で、EPUB ファイルを読むとき、文字列を選択して辞書を引ける。ただ、ここで引ける辞書は (なぜか) EPUB の言語に依存するので、英語の本で辞書を引くと、英英辞書を引くことになる。

英和辞書を引くためには、EPUB 内のファイルを編集し、言語を日本語 (ja) にする必要がある。この手順は下記ページに詳しい。

ただ、この手順、結構めんどくさいので Ruby でスクリプト書いた。

Ruby (1.8.7 か 1.9.2) と RubyGems (1.8 の場合) があるなら、

gem install zipruby

で、必要な gem を導入して、上記スクリプトをダウンロード。スクリプトのあるディレクトリで、

ruby change_lang_of_epub.rb (変換したい EPUB ファイル)

とすれば、(元のファイル名).ja.epub というファイルが生成されます。

ruby change_lang_of_epub.rb (変換したい EPUB ファイル) (言語コード)

とすれば、日本語 (ja) 以外の言語コードも指定できます。

Ruby はこの手のスクリプトがさくっと書けてよかですね。

iPhone 等で任意の Webclip アイコンを設定するブックマークレット

iPhone をはじめとする iOS デバイスでは、Web ページのブックマークをホーム画面に置くことができる (これを Webclip と呼ぶ) 。このとき、下記のような要素が head 要素にあれば、指定したアイコンで表示される (ない場合はページを縮小した画像が表示される) 。

<link rel="apple-touch-icon" href="(アイコンのURL)"/>

しかし、多くのサイトではこの画像が設定されていないし、あったとしても気に入らない場合もある。

そこで、ユーザーが任意の画像を Webclip アイコンに設定するためのブックマークレットを作った。

使い方は・・・

  1. アイコンにしたい画像のURLをコピーしておく
  2. アイコンを設定したいページを開く
  3. 上のブックマークレットを実行
  4. 画像の URL を貼り付けして OK をタップ
  5. 通常通りホーム画面へ追加

ただ、なぜか、iPhone 用のリンクをタップ後のこのページでは動作しません。ほかのページでも実行出来ない場合があるかも。原因わかりました。追記参照。

ちなみに、アイコンは、Iconfinder あたりで探すのがおすすめ。

なお、コードを見やすいように書き下したのがこちら。

javascript:(function(){ u = prompt('Image URL'); h = document.getElementsByTagName('head')[0]; e = document.createElement('link'); e.setAttribute('rel', 'apple-touch-icon'); e.setAttribute('href', u); h.appendChild(e); })()

link要素を追加してるだけですね。

追記 (2010-10-01)

このページでリンクタップ後に実行出来ない問題について、Mobile Safari のデバッグコンソールをオンにして、再現してみたところ、下記のようなエラーが。

JavaScript エラー:1行目 Refused to execute a JavaScript script. Source code of script found within request.

実行しようとするスクリプトが URL 中に含まれてるとブロックされるようです。最近よくきく、クライアント側での XSS 対策というやつですね。これはたしかに有効かも。ということで、実行できないのは正しい動作で、別のページでは問題なく動くはず。

HatebuSearch を Retina Display 対応にしました

ねんがんの iPhone 4 をてにいれたぞ」ということで。

iPhone / iPod touch 向け、はてブ検索Webアプリ「HatebuSearch」を Retina Display 対応にしました。

対応しました、といってもほとんどHTMLなので、Webclipとアイコン5つのサイズを縦横2倍づつにして、CSSで以前のサイズを指定しただけ(つまり画像のサイズを16×16→32×32にして、CSSで width: 16px; height: 16px; を指定)。

作業に1時間もかからなかった割には、かなりきれいになって満足。すこしは画像の容量増えるかと思ったけど、全部で5.6KB→6KBならまったく問題ないでしょ。

参考

サクっと配達状況確認 アップデート (1.1)

iPhone / iPod touch 向け荷物配達状況確認フロントエンド「サクっと配達状況確認」をちょっとだけアップデートしました。

追加した機能は配達業者および問い合わせ番号の保存。一度問い合わせを行ったら、次に表示したときに、前に入力した情報を表示します。毎回コピペしなくていいので、便利ですよ。

また、これに関連して、入力した情報(と保存している情報)をクリアするボタンも追加しました。

なお、保存にはCookieなどでなくlocalStorageを利用しています。私が問い合わせ番号等を知ることはありません。

ちなみに今回、iPhone 4 用にアイコン変えようと思ったものの、元となる素材の解像度が足らず断念。自分で描く技術ないし。どうしよう。

それにしてもこのブログ、もはやリリース情報だけになりつつあるなあ・・・。

iPhone / iPod touch 向け、はてブ検索Webアプリ「HatebuSearch」をリリース

iPhone / iPod touch から自分のはてなブックマークにアクセスする場合、iPhone / iPod touch 向けのはてブのページでも、公式アプリでも、ブックマークの検索ができず不便なので、 はてブ検索Webアプリ「HatebuSearch」を開発。本日、リリースしました。

HTML5の機能を生かした、速くて軽い動作が売りです。

こちらは紹介動画。

はてなから取ってきたデータは端末に保存するため、一度データを取ってこれば通信なしで検索ができ、素早くブックマークにアクセスできます。

ただし、端末に保存されたブックマークは自動ではアップデートされないので、たまに(時間と通信料が気にならないときに)左上の「更新」をタップして、ブックマークを更新してください。

なお、iPhone以外でもWin版Safari、Chromeでも動作確認してますが、まあ、PC使ってるなら、公式のはてブのページを使えばいいと思います。Androidは持ってないからわからん!

バグや要望等あれば、twitterで @labocho つきでつぶやく、この記事にコメント、 labocho[at]penguinlab.jp 宛にメールなどの方法で伝えていただくと対応できるかもしれません。

iPhone向けサイト、HTML5でのWebアプリ開発については、そのうち記事を書きたいと思ってます。

「サクっと配達状況確認」をリリース

佐川急便/クロネコヤマト/日本郵便の3社の、iPhone / iPod touch 向け荷物配達状況確認フロントエンド「サクっと配達状況確認」をリリースしました。

ネットで買い物すると、届くのが待ち遠しくて、配達状況をよく確認するのですが、毎回、各社のページを検索→重いトップページを開く→入力というのが面倒になってきたので作成しました。

tracking-ss

使い方は見ればわかると思いますが、配達業者を選択して、各社の問い合わせ番号を入力、確認をクリックすれば、各社の確認結果のページへリダイレクトします。ハイフンやスペースが入ってしまっても、自動で除去します。

iPhone / iPod touch のホーム画面に置いとくと便利かもしれません。

今回、ホーム画面用のアイコンは「Flavour Extended: The Ultimate Icon Set For Web Designers – Smashing Magazine」をほぼそのまま利用さしてもらいました。ありがたい。

なお、PCや他のスマートフォンでも使えると思いますが、見た目と動作は保証しません。

iPod/iPhone用手袋を作ってみました。

Engadget Japanese で紹介されていたiPhone用手袋「DOTS」

手袋したまま iPod nano を使えたらいいのになあと思ってたので、これは欲しいと思った。

でも、なんか写真をみてると、手袋に手芸で使うスナップボタンを付けただけのように見えたので、以前、iPodケース(カモノハシ型)を作った時にあまったスナップボタンで試してみたら・・・動くじゃないか。

今回使ったスナップボタン
今回使ったスナップボタン

スナップボタン(金属製の頭がついてるやつ)は手芸店などで普通に売ってて、10コ入りで200円弱くらい?これを今使ってるユニクロの手袋に付けてみた。私は iPod nano を操作する時は、右手親指しか使わないのでそこだけ。

iPod対応手袋
作業時間10分くらいで完成

付け外しする必要はないので、スナップボタンは頭側(メス側)だけ付けました。若干、親指に金属があたる違和感があるけど、まあ問題なし。指ほど自然には操作できないけど、実用上は十分です。

スナップボタン使ったことない人のために書いとくと、装着には専用の止め具とカナヅチ(か、木づち)が要ります。止め具はスナップボタンとセットで売ってるのを買うと便利。

興味ある方はぜひお試しあれ。

ただし、手袋に穴あくし、外すのは困難だから安いやつでね。

ホーム > タグ > iPhone

検索
フィード
メタ情報

ページの上部に戻る