ラベル iphone の投稿を表示しています。 すべての投稿を表示
ラベル iphone の投稿を表示しています。 すべての投稿を表示

2011-01-21

twitter より (2011-01-20)

  • 18:44  プログラム(コード)よりも、コンテンツを売り物にする傾向は加速するばかりだ。ふと思ったんだけど、自分の撮った写真で時計アプリを作れたらウレシイのかね? ウレシイのならそういうサービスが出てきてもおかしくないな。→ http://t.co/YEpyJWK
  • 19:00  2月末か。日本でも同時期だとしても時期的にビミョーだな。→ http://t.co/AKtZ6Rv
Powered by twtr2src.

2010-12-19

twitter より (2010-12-18)

  • 15:57  iphone の ipod からairplay で apple tv に音を送るとまるで iphone がリモコンのよう。実際は本体なんだけどな。
  • 16:07  apple tv って iphone (または ipod touch) の再生装置としても良いかも(・∀・)b ipod のささるスピーカーでもいいけど、あれだと iphone 自体で離れた場所から操作できない。大抵リモコンがあるけど操作性はやはり iphone そのものが上。
  • 16:10  ってか、アレだな。airplay 対応の再生装置が出てくればそれでも良いのか。
  • 20:00  iOS/Mac 向けアプリ開発者で iPad を持っているなら、おすすめです。→ http://logrepo.blogspot.com/2010/12/ibook-apple.html (iBook で Apple 提供の開発者向けドキュメントが読める)
Powered by twtr2src.

2010-12-08

twitter より (2010-12-07)

Powered by twtr2src.

2010-11-23

iOS アップデート (→ 4.2.1)

一度延期になってしまったが、ようやく iOS のアップデートが来た。早速、iPad、iPhone 3GS、iPod touch (4th)、そして iPhone 3G の順にアップデートを行った。

AirPlay や AirPrint といった新機能もあるけれど、今回のアップデートの肝はなんといっても、iPad と他の iOS デバイスの OS が統合されたことだ。両方を使っていて、微妙な差異にイライラさせられることがなくなる(フォルダとかタスク切り替えとか)。アプリを開発するときにも、現行の OS のバージョンがいくつもあるというのは面倒が多い。

iOS 4.2.1 上の Safari のユーザエージェント

以前にも使った簡単な CGI プログラムで各実機が使うユーザエージェントを調べてみた。

Apple 製デバイスの OS のバージョンとユーザエージェント文字列の対応
Device OS User-Agent
Mac Snow Leopard 10.6.5 (10H574) Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; ja-jp) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4
iPhone 3G iOS 4.2.1 (8C148) Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5
iPhone 3GS iOS 4.2.1 (8C148a) Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5
iPad iOS 4.2.1 (8C148) Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5
iPod touch (4th) iOS 4.2.1 (8C148) Mozilla/5.0 (iPod; U; CPU iPhone OS 4_2_1 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5

すぐに気付くことは、Mac 用の Safari のバージョンが一番高い(5.0.3)こと。WebKit のバージョンもやはり Mac 用のものが新しい(533.19.4)。意外だったのは、iPhone 3GS だけ OS の番号(ビルド番号かな)が異なっているということだ。3GS のみ 8C148a と末尾に a が付いている。他の iOS デバイスはすべて 8C148 だ。

ともあれ、このアップデートで、ようやく iPad の Safari と他の iOS デバイスの Safari が同じバージョンになった。これまでは、iPad の方が少し古く、CSS3 のサポート状況に若干の違いがあったのだ(→「ウェブページのスタイルを iPad に最適化する方法」参照)。今後のアップデートは足並みを揃えてもらいたいものだ。

関連リンク

関連記事

2010-11-19

twitter より (2010-11-18)

  • 19:38  そろそろかな。iOS アップデート。iTunes のアップデートが来たし。→
Powered by twtr2src.

2010-11-07

「Back」ボタンの実装 - セッション管理 (Blogger Glass)

iPhone アプリらしい外観には「Back」ボタンが必要だ。Safari の「戻る」ボタンを使ったのではアプリらしくない。そして「Back」ボタンを実装するためには画面の履歴を記録しておくための仕組みが必要だ。

履歴を記録する仕組みは大きく 2 つの部分に分かれる。履歴そのものを(文字列のリストとして)記録しておくための部分と、そのリストをクライアント(ブラウザ)ごとに持つための部分だ。前者の実装は「リングバッファを作る」で説明した。また、後者を実現するためのセッション管理の肝となる部分も「Cookie の使い方」で説明ずみだ。

今回は、これまでに実装した「かけら」を Blogger Glass に組み込みセッション管理を実現するとともに、セッションデータとして履歴を保持させることで、「Back」ボタンを実現する。

セッション管理

session モジュールに定義した Session クラスは Cookie を用いたセッション管理を実現する。また、セッション固有のデータを data 属性として保持している。このセッション固有データは GAE のデータストアサービスで保存される。

セッションの作り方(ID の生成、ブラウザとの Cookie の授受)は「Cookie の使い方」に書いたコードをほぼそのまま流用している。

セッション管理のほとんどは Session オブジェクトの初期化時に完了している。この初期化時には、リクエストハンドラから RequestResponse のオブジェクトがわたってくることを想定しており、ブラウザとの Cookie の授受も、この 2 つのオブジェクトを通して行っている。

セッション管理の利用者(リクエストハンドラ)側では、Session オブジェクトを初期化し、セッション固有データとしての data 属性を読み書きするだけで良い。

セッション固有のデータ

現在のところ、セッション固有データとして保持するのはリクエスト履歴のみで、これは URL (文字列)のリストになるため、データストア用のモデルは以下のようになる。

(src/model.py より)
class SessionData(db.Model):
    history = db.StringListProperty()

セッション管理をリクエストハンドラに組み込む

Session クラスを使ってセッション管理(とセッション固有データの保存)には以下のようなコードを書く。この関数自体は util モジュールで定義している。

(src/util.py より)
def save_url(request, response):
    history = RequestHistory()
    sess = session.Session(request, response)
    history.import_history(sess.data.history)
    logging.info("Hisotry: %s" % history)
    history.push(request.uri)
    sess.data.history = history.export_history()
    sess.data.put()

リクエストハンドラの get メソッド等で以下のような関数を呼び出す。

back リクエストの追加

セッション固有データとして保存された履歴をたどって、前の画面に戻る動作を実現するのは back リクエストを受けるハンドラになる。

back リクエストの基本的な処理は、(セッション固有データから)リクエスト履歴を 2 つ読み取り、2 つ目のリクエスト URL にリダイレクトする、というものだ。履歴の 1 つ目は back リクエストを送ってきた画面(つまり「Back」ボタンが配置されている画面)であり、戻るのはそのさらに 1 つ前(履歴の 2 つ目)のリクエスト URL になる。ただし、画面によってはユーザ体験として戻る意味のない画面もあり(例: メニュー画面)、そこはスキップし、さらに前の画面に戻るようにしてある。また、戻るべき履歴が空の場合は、いつもトップ画面に戻る。

セッション固有データからの履歴の読み取りは util モジュールで定義した以下の関数で行う。

(src/util.py より)
def load_url(request, response):
    sess = session.Session(request, response)
    history = RequestHistory()
    history.import_history(sess.data.history)
    from_url = history.pop()
    back_url = history.pop()
    if not back_url:
        back_url = '/'
    sess.data.history = history.export_history()
    sess.data.put()
    return (from_url, back_url)

その他の変更点

以下のコミットを参照。

次の一手

「Back」ボタンが完成したので、「iPhone アプリらしく #2 - 実装 (Blogger Glass)」で(画面には配置しておきながら)未実装のままにしておいた部品のうち、残っているのは「Labels」となる。これは、「ポスト画面」で表示中の記事に付けられたラベル一覧を表示する画面に移るためのものだ。

これを実現するには、「Back」ボタンと同様にセッション固有のデータに保存しても良いし(保存先は memcache で十分か)、ブログ ID とポスト ID をキーとしてグローバルデータとして保存するのでも良い。とりあえず、セッション固有データとして保存する方式で作ってみようか。

関連リンク

関連記事

2010-10-30

iPhone アプリらしく #2 - 実装 (Blogger Glass)

Blogger Glass: List view

前回(「iPhone アプリらしく #1」)、画面のデザイン(おもに意匠)を示してから、途中寄り道をしていたりもしたが、ようやく iPhone アプリらしい画面が動くようになった(一部、未実装の機能あり)。

Blogger Glass は(今のところ) Ajax はもちろん、JavaScript すら使っていない、純粋に画面遷移だけによるとても古臭いウェブアプリだが、それでも画面を整えてやることでグッと iPhone アプリらしく見えてくる。

実装方針

デバイスによって画面テンプレートとスタイルの切り替える

iPhone アプリらしい画面を Mac 用のものと共通にしようとするのは骨が折れるばかりだとわかった。同じ iOS デバイスの iPad にしたところで、画面の大きさがここまで違うと同じ画面を使い回すのはユーザ体験を低下させかねない。iPad のアプリの多くが「HD」と銘打って(iPhone と兼用ではなく) iPad 専用となっているのもうなずける。思い切って、画面を作るためのテンプレートとスタイルシートは iPhone 専用のものを作ることにした。

Blogger Glass を作り始めたときから、画面の構造(テンプレート)は画面ごとに用意していた。画面が増えてきたときに共通部分をくくり出すことにしたが、取り出せたのは、head 要素の他は画面の上部と下部に表示させることにした一部の情報用の領域のみ(図の App Header と App Footer)。

iPhone 用の画面を作っているときに気付いたが、この共通情報は、ブログなどのウェブサイトの構造を引きずったものだ。ウェブアプリには向かない、むしろ不要と言って良いものだった。そんなわけで、iPhone 用の画面構造(テンプレート)では、App (Header|Footer) をばっさり削った。以下に示す通り、iPhone 用にも base.html は存在するものの、共通化されているのはほぼ head のみになっている。

(src/templates の構造)
templates/
+-- base.html
+-- iphone/
|   +-- base.html
|   +-- list.html
|   +-- menu.html
|   +-- post.html
|   +-- search.html
|   +-- settings.html
+-- list.html
+-- menu.html
+-- post.html
+-- search.html
+-- settings.html

画面の構造が変われば、スタイルシートも変わる。idclass を駆使し、複雑なセレクタ指定を使えば、すべての画面に対して 1 つのスタイルシートファイルで対応することもできる。が、それは巨大なファイルになるし、複雑さを軽減させようとテンプレートを分けたのにスタイルシートで複雑さを増やしていたのでは片手落ちと言うものだろう。だから、スタイルシートも画面ごとに分けることにした。

ただし、共通部分の多い画面(一覧画面と検索結果画面等)ではスタイルシートファイルを @import することで、同じスタイルの定義が複数の場所に散らばることの避けた。もっとも、こういう方針を厳守しているかと問われると、実は心もとなかったりする。CSS って書き方(文法)に自由度がありすぎて、統一した様式で書くのって難しいんだよ。

(src/stylesheets の構造)
stylesheets/
+-- default.css
+-- ipad.css
+-- iphone/
|   +-- common.css
|   +-- list.css
|   +-- menu.css (iphone/list.css を import; 一部独自スタイルで上書き)
|   +-- post.css
|   +-- search.css (iphone/list.css を import)
|   +-- settings.css
+-- mac.css (default.css を import)

実装

デバイスに応じて画面の構造(テンプレート)とスタイルを切り替える仕組みが、新たに追加した device モジュールだ。

device モジュール

このモジュールでは、クライアントに想定してる各種デバイスを表すクラスといくつかのユーティリティ関数を定義している。

リクエストハンドラからは、ユーティリティの 1 つ、ファクトリ関数を呼び出してリクエストデバイスを表現するオブジェクトを取得する。ファクトリ関数を以下に示す。

(src/device.py より)
def get_device(user_agent, view):
    if user_agent.find('iPad') > -1:
        dev = iPad(view)
    elif user_agent.find('iPhone') > -1 or user_agent.find('iPod') > -1:
        dev = iPhone(view)
    else:
        dev = Mac(view)
    return dev

これを呼び出すリクエストハンドラのコードは以下のようになる。

(src/main.py より)
        user_agent = self.request.headers['User-Agent']
        view = self.viewinfo.type
        self.viewinfo.device = device.get_device(user_agent, view)

ViewInfo オブジェクトに格納された device オブジェクトは、画面を定義しているテンプレートの切り替えと、画面テンプレートの中でスタイルを定義している CSS ファイルの参照に使用される。

(src/util.py より)
def render_template(handler):
    view = handler.viewinfo.type
    path = handler.viewinfo.device.template
    return template.render(path, {
            'app': handler.appinfo,
            'view': handler.viewinfo,
            })
(src/templates/iphone/base.html より)
<!DOCTYPE HTML>
<html lang='{{ app.lang }}'>
<head>
  [...snip...]
  {% for css in view.device.stylesheets %}
  <link type='text/css' rel='stylesheet' href="{{ css }}">
  {% endfor %}
</head>

各種デバイスを表すクラスを示す。

(src/device.py より)
class Device(object):
    def __init__(self, device, view):
        self.is_ios_device = False
        self.stylesheets = None
        self.template = None
        self.template = get_template(device, view)
        self.stylesheets = get_stylesheets(device, view)

class iPhone(Device):
    def __init__(self, view):
        Device.__init__(self, 'iphone', view)
        self.is_ios_device = True

is_ios_device 属性は、専用テンプレートを使っている iPhone では不要だ。他のデバイス(Mac) とテンプレートを共有している iPad でまだ使っているため残してある。実際に、テンプレートとスタイルシートの切り替えを実現しているのは、基底クラス(device.Device) の初期化中に呼び出されている以下の 2 つの関数だ。

(src/device.py より)
def get_template(device, view):
    if device == 'iphone':
        name = ("templates/%s/%s.html" % (device, view))
    else:
        name = ("templates/%s.html" % view)
    return os.path.join(os.path.dirname(__file__), name)

def get_stylesheets(device, view):
    style_dir = 'stylesheets'
    if device == 'iphone':
        common_style = ("/%s/%s/common.css" % (style_dir, device))
        view_style = ("/%s/%s/%s.css" % (style_dir, device, view))
        return [common_style, view_style]
    else:
        return [("/%s/%s.css" % (style_dir, device))]

これを見ればわかるように、切り替えといっても大袈裟なものではなく、デバイス名と画面のタイプをそのままディレクトリの構造とファイル名にしているだけ。

この部分を実装し始めた当初は、テンプレートもスタイルシートもパス名を自由に設定できるような作りにしていた。一言でいえば、デバイス名と画面タイプをキーとする二重のディクショナリだ。で、その二重ディクショナリにセットする値(つまりファイル名)を書いていて、何かひどく間違ったことをやっている気になった。

確かに、ひとつひとつファイル名を設定できた方が自由度が上がる。極端な場合を想像すれば、アプリ外部の URL を(テンプレートはともかくスタイルシートなら)使うことだってできる。しかし、それは過剰な(そして何より不要な)自由度ではないだろうか? そう思えてきた。

このとき頭の中にひとつの言葉が浮かんできた。それは "Convention over Configuration"、そう Rails の基本理念の 1 つだ(→ 「誰が Redmine を起動したのか?」の「Convention over Configuration (設定よりも規約)」を参照)。

デバイス名と画面タイプ(の名前)でファイルが特定できるなら、それをそのままファイルシステムにマップすれば良い。iPhone 用の一覧(list)画面なら iphone/list.html と決めれば良い。誰でもすぐに思い付く自然な規約(convention)だろう。むしろ直感的と言って良いほど。

(プログラマにとって)大事なことを思い出せたおかげで、コードはグッとシンプルなものになった。中途半端に(デバイス名による)条件分岐が残っているのは、今回採用したテンプレートとスタイルシートを画面ごとに分割する方式に則っているのが iPhone の場合だけだから。ま、そのうち、直すとしよう(iPad 用の画面を作るときかな)

jQTouch

今回の更新から、「iPhoneアプリケーション開発ガイド」で紹介されている jQTouch というライブラリを使っている。といっても、使っているのは jQTouch の配布にふくまれているボタン等の背景画像のみだ(iPhone 用の画面で使用)。

やはり外部で配布されているものなので、画像を src/images ディレクトリにコピーするような乱暴なことはやらず、配布物の構造そのままに src/lib に置くことにした (GData ライブラリと同様に bgithub のリポジトリには入れていない)。このため、iPhone 用のスタイルシートからは /lib/jqtouch/themes/jqt/img/button.png のような URL でアクセスしている。

スクリーンショット

この iPhone 対応版はすでに appspot に配備ずみ。ボタンの機能等で未実装部分が一部、残っているが、主要機能は iPhone/iPod touch で動かすことができる。以下は、実際に GAE アプリとして動かした様子を iPod touch (Retina ディスプレイ搭載) で撮ったスクリーンショットだ。

iPod touch によるスクリーンショット
一覧画面
画面上部左にはメニュー画面を開くためのボタンを配置。 画面下部は一覧のページ切り替えのためのボタンを配置。 また、ページ切り替えのボタンはページに応じて有効、無効が変化する。 無効の場合は、ボタンの文字がグレーで表示される。
メニュー画面
画面上部左にはメニューを開く前の画面に戻るたけのボタンを配置(機能は未実装)。 メニューの項目はログインの状態によって変化する。
設定画面
画面上部左にはメニューを開く前の画面に戻るたけのボタンを配置(機能は未実装)。 「Save Settings」等、HTML フォームのボタンについてはスタイル(文字の大きさ等)を検討中。
記事画面
画面上部左にはメニューを開く前の画面に戻るたけのボタンを配置(機能は未実装)。 画面下部左にはラベル一覧画面を開くボタンを配置(機能は未実装)。
検索結果画面
画面上部左にはメニューを開く前の画面に戻るたけのボタンを配置(機能は未実装)。 その他は一覧画面と同様(下部のページ切り替えボタン等)。

今後の展開

もちろん、未実装の部分(機能しないボタンとか)を実装しなければならない。「Back」ボタンなどは簡単に見えて、実装するには戻り先となる前の画面の情報を覚えておかなければならないため、それほど単純なものではない。GAE のデータストアサービスを使うか、あるいは(まだ使い方を調べていないけど) memcache サービスの方が良いのか。「Labels」(ラベル一覧画面を開く)も、ラベルの一覧をどこに保持しておくかで同様の課題がある。ま、見かけほど簡単じゃないと思ったから後回しにしているわけだけどね。

実用的になってくると毎日使うことになり、使えば使うほど「あら」も「ぼろ」も見えてくる。見えれば、「あら」は埋めたくなるし、「ぼろ」は繕いたくなる。やることはまだまだあるってことだ。

iPhone に専用画面で対応したんだから iPad にも同じようにしたい。記事の中身を読むという点では iPad の方が読みやすいんだから。

あと、iPhone 用としてはオフラインで記事を読めるようにしたい。ネットにつながらなかったり、つながっても遅かったりすると、やはりオフライン機能が欲しくなる。HTML5 のオフラインアプリケーションキャッシュ(「iPhoneアプリケーション開発ガイド」6 章で解説されている)を使えば可能かもしれない。しかし、そこまで考えるなら、もういっそのこと Objective-C で書き直すべきかもしれない。GData クライアントは Objective-C 版 (gdata-objectivec-client) もあるしな。

参考文献

関連リンク

関連記事

2010-10-25

iOS デバイスに対応する (基礎編) - Blogger Glass

Blogger の提供するスタイルにあれこれ変更を加え始めたのは何より iPhone (と iPad) で見やすくしたかったからだ。それが高じてブログの記事を表示する GAE アプリを作るまでに至った。ある程度の実用性を備えた今こそ、iOS デバイスの対応を始めるときだ。

iOS デバイスへの対応と言っても、これまでのように単にスタイルを最適化する程度で終わりたくない。ブログコンテンツを表示するためのアプリと呼べるものに仕上げたいのだ。最終的には Blogger Glass を iOS デバイス用のウェブアプリと呼ぶにふさわしいモノにするつもり。何をどこまで作り込めばそう呼べるかはまだわからない。そもそも BG 自体まだ機能的に不足しているし、実装ずみの機能も洗練されているとは言えないしな。課題は(見えないものもふくめて)多いが、まずは一歩を踏み出そう。そうすれば次に進むべき方向も見えてくるから。

今回は基礎編。まずは以前の成果(スタイル定義)を流用して、現在、Blogger (の LOG+REPO) を iOS デバイスで開いたときと同等の外観を実現する。それには主に以下の 2 つの作業が必要だ。

  • Viewport の設定
  • デバイスごとの CSS ファイルの用意

それでは順番に見ていこう。

viewport の設定

(「iPhoneアプリケーション開発ガイド―HTML+CSS+JavaScript による開発手法」p.17)
特に指定がない場合、iPhone 版の Safari ではページの横幅が 980 ピクセルであるとみなされます(図2-3)。多くの場合はこの設定でも問題はありませんが、iPhone の小さな画面に特化したコンテンツを作成するためには横幅を明示する必要があります。

さて、この横幅の指定は meta タグによって「viewport」を設定することで行う。viewport の設定(の meta タグ)は(iOS デバイスの Safari)以外のブラウザでは無視されるということだ(→「iPhoneアプリケーション開発ガイド」p.18)が、そこはウェブアプリなのだからリクエストデバイスに応じて追加するようにしたい。

それが以下の部分だ。app オブジェクトの is_ios_device 属性が True のときだけ viewport 設定のmeta タグを追加している。

(src/base.html より)
<title>{{ app.title }}</title>
{% if app.is_ios_device %}
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
{% endif %}
<link type='text/css' rel='stylesheet' href="{{ app.stylesheet }}">

app オブジェクトは、各リクエストハンドラからわたってくる info.AppInfo クラスのインスタンスだ。このオブジェクトに情報を詰めているのが、util.fill_appinfo 関数で、リクエストデバイスの識別を行う util.get_device 関数を利用してデバイスごとの情報を生成している。それにはデバイス専用の CSS ファイルもふくまれている。

(src/util.py より)
def fill_appinfo(appinfo, request_url, user_agent):
    [...snip...]
    device = get_device(user_agent)
    if device == 'iphone':
        appinfo.is_ios_device = True
        appinfo.stylesheet = '/stylesheets/iphone.css'
    elif device == 'ipad':
        appinfo.is_ios_device = True
        appinfo.stylesheet = '/stylesheets/ipad.css'
    else:
        appinfo.is_ios_device = False
        appinfo.stylesheet = settings.get('stylesheet')

デバイスの識別はユーザエージェント文字列中のデバイス名によるもので、3 つのタイプを返す(iphone、ipad、そして mac)。iOS デバイス以外は mac 扱いにしている。

(src/util.py より)
def get_device(user_agent):
    if user_agent.find('iPad') > -1:
        device = 'ipad'
    elif user_agent.find('iPhone') > -1 or user_agent.find('iPod') > -1:
        device = 'iphone'
    else:
        device = 'mac'
    return device

デバイスごとの CSS ファイルの用意

デフォルトスタイルの時と同様に、Style Repository で LOG+REPO 用に提供している各デバイス用のスタイルをほぼそのまま流用した。

iPhone 用では実験的に少し色を変更してあるが、これはすぐに変更することになる(後述)。

Blogger Glass が生成する HTML は HTML5 に準拠することを目指している。headersection、そして footer のような区画分けのための要素を使っているのも、そのためだ。今回、iPad 用のスタイルを用意していて、現在の iPad 上の Safari (OS: 3.2.2 (7B500)) ではこれら区画分けの要素に単独で指定したスタイルが効かないことがわかった。具体的には以下のような定義が無効になる。

(区画分け要素のスタイル)
header {
    background-color: #eeffcc;
}

同じ定義が iPhone および iPod touch (どちらも OS 4.1 (8B117)) では有効になる。iPad の OS がアップデートされれば解決されるだろう。

ま、わたし自身が十分に HTML5 のスペックを読み込んでいないため、BG の HTML5 準拠も手探りだからな。BG が生成する HTML の構造もまだまだ変わる。スタイルもそれに合わせて変えなくてはならない。今のスタイルも暫定版でしかない。

もっと iPhone らしく

さて、以上が iOS デバイス対応の基礎編だ。ここから先は、デバイス対応というよりも、むしろ BG の iOS デバイス専用ウェブアプリ化になる。その手始めとして、今、実験中のスタイル定義によるスクショを示す。iPod touch による表示だ。

これは「iPhoneアプリケーション開発ガイド」の p.19 〜 23 の書かれている手法を適用したものだ。少しリストと見出しのスタイルをいじるだけで、ずいぶん iPhone アプリらしくなる。

ゴールを、iPhone でも使えるモノから iPhone で専ら使うモノに変えると、機能のデザインも(とくにユーザ体験に関して)いろいろと変わってくる。たとえば、ラベル検索による絞り込みも、Mac (上の Safari)で使うことが前提なら、詳細検索画面を作って複数のラベルを指定させて、なんていう拡張を考える。けれど iPhone に特化するなら、まずラベルを 1 つ選択して検索し、その結果表示画面でさらにもう 1 つラベルを選択して(2 つのラベルによる複合検索で)絞り込む、というような使い方を考える。

iPhone では一度に表示できる情報が限られているし、モバイル機器であるためユーザとの対話は短いほど望ましい(ユーザは椅子に座ってじっくりと iPhone の画面を眺めているとは限らない)。そういった機器の特性はユーザ体験のデザインに大きく影響する。ウェブアプリとして実現されていたとしても、iPhone 用を標榜するなら、iPhone アプリらしくあらねばならない。単にスタイルを変えるだけで済む問題ではないってことだ。

参考文献

関連リンク

関連記事

2010-09-28

twitter より (2010-09-27)

Powered by twtr2src.

2010-09-23

twitter より (2010-09-22)

Powered by twtr2src.

2010-09-11

twitter より (2010-09-10)

  • 08:07  うぉー、なんかスゲェ。手のひらに乗るコンピュータか。って感心した後にふと思った。iPhone もそうじゃん、って。→ http://jp.makezine.com/blog/2010/09/chumby_hacker_boards.html
  • 08:09  古い iPhone (や iPod touch) を差して自宅サーバにできるようなドックとか発売されないかな。
  • 08:42  この iPad スタンド、たったいま Amazon で発注した。買っといて言うのもなんだけど、こういうものを必要に感じてしまうところが iPad の弱点だよな。→ http://www.ideaxidea.com/archives/2010/09/xstand.html
  • 08:47  前にも書いたけど、iPad は画面への映り込みのせいで机の上などに水平に置いて使うことが難しい。やはり、画素数そのままで(増える分には文句はない)サイズを小さくしたモデルを出してほしいよ。軽くなるなら小さくなくても良いゾ。 → http://bit.ly/arTYR0
  • 08:57  カッコイイな、コレ。→ http://www.cultofmac.com/groves-bamboo-iphone-case-is-a-work-of-art-review/57347
  • 16:39  Google Instant、おもしろいわ。co.jp からはまだ使えないけど、.com からなら日本語でも Instant な検索になる。suggest と組み合わせたところが秀逸なアイデアかもな。検索語の候補を矢印で切り替えると結果もリアルタイムで切り替わる。いいわ、これ。
Powered by twtr2src.

2010-09-10

twitter より (2010-09-09)

Powered by twtr2src.

2010-09-09

iPhone シミュレータをウェブページの作成に活用する

おそらく、iPhone や iPad 向けのウェブページを作っている人はみんなとっくに気付いていて、当たり前のように実践しているに違いない。最近になるまで気付かなかったわたしが間抜けなのだ。それは、ウェブページの見た目(やウェブアプリの動作)の確認に iPhone シミュレータを使うという方法だ。

もちろん、実機で確認する方が確実だし、最終的には必須でもある。しかし、ページを作っている最中にちょっと確認するのであれば、シミュレータを使うのもありだろう。何より、Mac の中で完結できるから、手軽さで実機を使うことに優る。また、Mac の Safari でユーザエージェントを切り替えたり、ウィンドウサイズを iPhone や iPad に合わせるよりも簡単だ。

起動、そしてデバイスの切り替え

まずはシミュレータのありか。

/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications

このシミュレータは iOS SDK にふくまれているものなので、iOS SDK をインストールしていない Mac ではどんなに探しても見つからない。ちなみに、iOS SDK のダウンロードだけなら無料でできる(開発者としての登録は必要)。

通常、iPhone シミュレータは Xcode の中から起動するから、単独のアプリだとは気付きにくいけれど、上記の場所に iPhone Simulator.app として存在している。Finder からダブルクリックすれば、通常のアプリと同様に起動する。

iPhone シミュレータという名前だが、iPad シミュレータにもなる。それには、メニューから「ハードウェア」>「デバイス」で目的のデバイスに切り替える。バージョン 4.1 では iPad、iPhone、そして iPhone 4 の 3 つから選べる。また、シミュレートする iOS のバージョンも別途選べるようになっている。ただし、デバイス専用のバージョンを選ぶとデバイスも同時に切り替わる(例: 3.2 は iPad 専用)。

ちょっとおもしろいのは、iPhone 4 を選んだときだ。iPhoen 4 の画素数そのままに巨大なウィンドウが表れる。iPhone のときの 4 倍(タテ、ヨコ、それぞれ 2 倍)だ。まあ、これでは Retina ディスプレイのシミュレートとしては不足だけどね。肝心の解像度(326ppi)を再現できていないのだから。

使い方は iPhone (や iPad) と同様。ただし、タッチスクリーンではないから、タップはクリック、スワイプはドラッグになる。また、マウス単独では不可能なマルチタッチのピンチオープン、クローズには Option キーを併用したドラッグとなる。Magic TrackPad の場合はそのままのジェスチャになればウレシイんだが、残念だけどそうはなっていない。

シミュレータの Safari でページを見る

シミュレータと実機の比較
シミュレータ
(iPhone)
実機 (3GS)

これは、実際にシミュレータと実機でこのブログを開いたときのスクショだ。それぞれを見ればわかるが、見た目の差はないと言って良い。フォントの種類もサイズも同一。行の高さも、折り返す位置も同じ。

ウェブアプリとなると実行速度や搭載メモリの差、さらには特性の差(センサー類は使えない)が差異として表れるかもしれないが、ウェブページの見え方を検証するのであれば、シミュレータも十分に役立つ。

関連リンク

関連記事

2010-09-05

twitter より (2010-09-04)

  • 18:08  はてブには twitter でつぶやいた URL を流し込んでいる。ときどき見返すんだが、iPad できるならそれが手軽にできるようになるか。 / はてなブックマーク for iPad 公開! http://htn.to/goJLcn
  • 18:22  9/8 だそうな。イベントからちょうど一週間後ってことか。4.0 は不安定だからな(on 3GS)、バグフィックスに期待大。→ http://ipodtouchlab.com/2010/09/ios-41-release.html
Powered by twtr2src.

2010-08-27

twitter より (2010-08-26)

  • 07:53  新 iPod touch が良いなあ。白い iPhone 4 が出てこないから、iPod で Retina ディスプレイを体験したい。 → http://ipodtouchlab.com/2010/08/apple-special-event-fall-2010.html
  • 19:54  つーか、これは写真を公開するアプリの方が気を付けるべきことだな。GPS情報を取り除くかどうかを選べるようにすべきだろう。 → http://bit.ly/9I7M89
  • 20:14  あるいは、カメラの側でメタ情報を暗号化するとか。
  • 20:16  画像ビューアなんかも、メタ情報があるならきちんと表示するようにした方が良いのかもな。そんなものがあるなんて知らない人もいるだろうし。
  • 20:20  デジタルな世界での暗号化って、金庫というよりむしろ家の鍵ぐらいのカジュアルなものであるべきなのかも。だとしたら、もっと手軽に扱えるべきだね。もちろん、暗号自体は、家の鍵なんかと違って堅牢なものでないと困るけど。
Powered by twtr2src.

2010-08-26

角が丸いのは Mac の伝統!

ちょっと長いけど、二人のやり取りがおもしろいので引用する。引用中、Steve はもちろん Steve Jobs、Bill は QuickDrawHyperCard を書いたことで知られる Bill Atkinson だ。ちなみに、この記事(原文)を書いたのは Andy Hertzfeld (オリジナル Macintosh の開発者の一人で、Folklore.org の製作者)。

(レボリューション・イン・ザ・バレー; p.60「角丸長方形だらけ!」より)
しかし、ここで何かが Steve Jobs の頭に浮かんだ。 「まあ、円と楕円はよくできてたな。でも角の丸い長方形はどうだ? それも今できるのか?」。

「いや、そんなことはできませんよ」と Bill は食ってかかった。 [...snip...]

「角の丸い長方形なんて、そこら中にあるだろ! この部屋を見回してみろ!」。確かに、たくさんあった。 [...snip...]

[...snip...] 「OK。参りました」と Bill は認めた。 「思っているほど難しいかどうか、やってみますよ」。 [...snip...]

翌日の午後、Bill は満面の笑みを浮かべて Texaco Towers に戻ってきた。 彼のデモは、見事に角の丸い長方形を、ほとんど普通の長方形と変わりない、猛烈な速さで描くようになった。 彼はその新しい命令を [...snip...]「RoundRects」と名付けた。 次の 2、3 ヶ月の間に、RoundRects はユーザーインターフェースのさまざまな部分に浸透し、まもなく必要不可欠なものとなった。

正直言って、技術者ではない Jobs が Macintosh (初代) の開発に直接的に貢献したとは思えないんだけど、こういう話を聞くと、なるほど Jobs がいなかったら Mac はこうなっていなかったんだな、とわかる。この「角の丸い長方形」の話なんて、Mac どころかその後の GUI の発展にも影響しかねないものだ。もし、あのとき Jobs の頭に「角の丸い長方形」が浮かばなかったら……、もし、Bill が Jobs との議論に勝っていたら……。

ウェブページでも角を丸く

角の丸い長方形は、今も初代 Macintosh の子孫たちに受け継がれている。Mac OS X のウィンドウたちは、たいてい四隅が(少なくとも上部の二つの隅は)丸い。iPhone のアプリアイコンも角が丸い。標準のボタンやリストもやはり角が丸い。改めて見回せば、丸い角はデジタルなモノの中にあふれている。まるで、角の丸いことがデジタルなモノの特性であるかのようだ。デジタルな道具に遺伝子があるなら、そこには「角は丸い」と書かれているにちがいない。

ならば、ウェブページでも角は丸くあるべきだろう。かつてのように、背景画像と table 要素を組み合わせて作らなければならなかった時代ならともかく、今では CSS3 だけで簡単に記述できる。もう、角を丸くしない理由がないじゃないか。Mac の伝統なんだよ。デジタルな遺伝子に書き込まれているんだよ。

2010-08-25

ウェブページのスタイルを iPad に最適化する方法

増えたデバイス

かつては、Mac (や PC) だけがウェブブラウザだった。今では iPhone に加えて、iPad が「普段使いのブラウザ」として加わった。Mac 向けに作ったページをそのまま開くこともできるけど、やはりデバイスに最適化されたデザインのページは見やすい。このブログも iPhone や iPad ですっきりと表示させたい。多少の手間はかかるけど、やるだけの価値はある。

iPad はウェブブラウザのリファレンスプラットフォームだ

以前にも、このブログを iPhone 対応させたことがあった(テンプレートを変えたために今ではその効果は失われている)。あのときは、単にサイドバーを非表示にしただけだった。今回は、レイアウト全体を見直してみよう。

iPad で見ることを前提に、幅を 768 ピクセル、および 1024 ピクセルで、レイアウト(メインとサブの 2 列構成)をデザインする。1024px仕様を手直しすることで、Mac 用のデザインを仕上げる。iPhone 用のものは、768px仕様からサイドバーを非表示にすることで作る。こうすることで、iPhone、iPad、そして Mac の 3 つのデバイスで、ほぼ同じ見た目にすることができる。

ともあれ、3 種類のデバイスに対応するのだから、デバイスごとにスタイルを指定しなければならない。まずはその方法を(前の iPhone 対応のときより少し詳しく)調べてみた。

デバイスごとにスタイルを指定する

CSS2 には、画面や印刷といった「表示の媒体」(メディア)に合わせてスタイルを指定する機能がある。 CSS3 では、これが拡張され、媒体(メディア)ごとの特性(幅、高さなど)に応じてスタイルを指定できるようになっている。 これがメディアクエリーと呼ばれる機能だ。 Mac 用の Safari はもちろん、iPhone/iPad 用のものもメディアクエリーをサポートしている。 このため、CSS スタイルを適切に記述してやれば、ひとつのウェブページを、開くデバイスに合わせて見た目が切り替わるようにすることができる。

デバイスを識別する

メディアクエリーを使いスタイルを切り替える場合、識別の鍵になるのは画面の幅だ。iPhone なら画面の最大幅が 480 ピクセル(横向きにしたとき)、iPad なら 1024 ピクセル(同じく横向き)になる。

通常、画面幅を鍵にして 2 つのデバイスごとにスタイルを指定する場合、以下のようになる。

(画面幅で切り替え; 2 デバイス)
@media only screen and (max-device-width: 480px) { ... }
@media only screen and (min-device-width: 481px) { ... }

前が画面幅が小さいデバイス(例: iPhone)向けのスタイル、後がそれ以外のデバイス向けになる。

デバイスが 3 つならどうなるか?

(画面幅で切り替え; 3 デバイス)
@media only screen and (max-device-width: 480px) { ... }
@media only screen and (min-device-width: 481px) and (max-device-width: 1024px) { ... }
@media only screen and (min-device-width: 1025px) { ... }

only というキーワードは、(メディアクエリーを知らない)古いブラウザに、この記述全体を無視させるための仕掛け。メディアクエリーをサポートしているブラウザは単に only を無視するので付けたところで影響はないが、(古いブラウザを使う人がまだいるかもしれないので)付けておく方が安全だ。

参考までに、iPhone 3G/3GS、iPad の画面幅についてまとめておく。

機種
iPhone 3G/3GS 320 480
iPad 768 1024
iPhone 4 640 960

iPhone 4 のピクセル数は 3G/3GS の 4 倍(縦横が2倍)だが、(iPhone 4 の Safari は)画面幅のメディアクエリーに関して旧機種と同様に振る舞うらしい。このため、iPhone 4 を 3G/3GS と区別するためには、画面幅ではなく -webkit-device-pixel-ratio という特性を使うようだ(→ 詳細は「iPhone 4 の CSS を切り替える方法」を参照)。いかんせん、iPhone 4 をまだ手に入れていないから試しようがない。

2010-08-24

Google Font API を使ったフォントの表示

(Google Font API - Google Code より)
The Google Font Directory provides high-quality web fonts that you can include in your pages using the Google Font API.

しばらく前になるが、Google がフォントの提供を始めた(今のところ、まだ beta 扱い)。フォントファイルを提供するだけではなく、ウェブページからリンクするサービスを用意することで、ページの表示時にブラウザがフォントを動的にダウンロードできるようにしたのだ。

使い方

ウェブページ用に使う方法

公式ドキュメント( "Getting Started - Google Font API" ) に書かれている方法は、HTML 中の LINK 要素を使い、Google Font API の URL に対してフォント名を指定するというものだ。以下の記述を HTML の HEAD 要素の中に記述する。

<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine">

スタイルの定義では、他のフォントと同じように扱うことができる。

font-family: "Neuton", Verdana, "HiraMaruProN-W4", serif;

このように指定すれば、英数字の部分については、Google Font API の Neuton または (Google Font API が使えないなどの場合は) Verdana が使われ、日本語部分に対しては「ヒラギノ丸ゴ ProN」が使われる。もし、3 つとも使えないなら、デフォルトの serif フォント(ひげつき) が使われる。

Mac 上の Safari で試すと、こんな風になる。英字部分には Tangerine、日本語部分には「ヒラギノ丸ゴ ProN」が使われていることがわかるだろう。「Making ...」の部分には影がかかっているけど、これは CSS の text-shadow で付けたのであって、Google Font API とは関係ない。

では、外部 CSS を使っている場合はどうすれば良いのか? その場合は、@import で Google Font API の URL を(フォント名とともに)指定すれば良い。具体的には、CSS ファイルの先頭に以下のように記述する。

(外部 CSS の場合の記述例)
 1: /* Google Font API ( http://code.google.com/apis/webfonts/ ) */
 2: @import url('http://fonts.googleapis.com/css?family=Lobster');
 3: @import url('http://fonts.googleapis.com/css?family=Neuton');
 4: @import url('http://fonts.googleapis.com/css?family=Droid+Sans+Mono:regular');

この例では Lobster、Neuton、および Droid Sans Mono の 3 つのフォントが利用可能になる。

iPhone で表示させたサンプル

Google Font API の 公式FAQ には iPhone、iPad、iPod、それに Android はサポートしていない、と明記されている。しかし、今回試してみた限りでは問題なく表示できた。試したのは iPhone 3GS (iOS 4.0.2) と iPad (iPhone OS 3.2.2) だ。

これ(→)は、iPhone で iMac の Apache 経由でページを開いた状態でスクショにしたものだ。

ブログタイトルの部分が Lobster フォント、記事のタイトル(「iPhone 対応」の iPhone という文字)が Neuton フォントによる表示になっている。

2010-08-20

twitter より (2010-08-19)

Powered by twtr2src.