2011-11-23

Android端末でJQuery Mobileのページ幅が正しく計算されない

JQuery MobileでつくったページにFacebookのJavaScript SDKを組み込む場合は、Androidのブラウザで画面の向き(Screen Orientation)を変えると、ページ幅が正しく調整されないことがあるので注意したい。
画面を横にしたときに広がったページ幅が、縦に戻しても元に戻らないのだ。この現象は、JQuery Mobileの1.0 RC2でも1.0 finalでも起こる。

 どうやらbodyタグの中にscriptタグがあることが、この問題の原因となっているようだ。 <script style="width:0px;">とやったら、多くの場合にこの現象を防ぐことができることを確認した。ただ、完全に防ぐことに成功したわけではなく、たまにページ幅が正しく調整されないこともある。

2011-11-19

iOS5に組み込まれたTwitter機能をアプリで使う

iOS5には、Twitterとの連携機能が含まれている。これを使えば、ユーザはアプリごとにログインを行わなくて済むようになる。 Twitterとの連携機能を、アプリに組み込むのは簡単だ。Twitter.frameworkへのリンクを追加した後で、おおよそ次のようなコードを書けばよい。
#import <Twitter/TWTweetComposeViewController.h>

- (void)sendTweet
{
    TWTweetComposeViewController *tweetViewCtrl = [[[TWTweetComposeViewController alloc] init] autorelease];
    [tweetViewCtrl setInitialText:@"デフォルトのテキスト"];
    [self presentModalViewController:tweetViewCtrl 
                            animated:YES];
}

2011-11-18

iPhoneアプリでTwitterやFacebookの共有機能を利用

iPhoneアプリの中で、TwitterやFacebookの共有機能を利用したい場合、ShareKitというライブラリを使うと簡単に実装できる。
しかしこのShareKit、iOS5でまともに動作しなくなってしまった。Twitterなどの共有をするためにモーダルダイアログを表示した後、キャンセルボタンを押してもダイアログが消えず、元の画面に戻れなくなってしまったのだ。現時点での最新版、バージョン0.2.1ではこの問題が修正されていない。

調査したところ、iOS5.0からUIViewController.parentViewControllerが、nilを返すようになったのが原因で正常に動作しなくなったのだと分かった。iOS4.3までは、parentViewControllerは、親のUIViewControllerを返していた。

幸いなことにShareKitはソースが公開されており、コードを数行の修正すれば問題を解決できる。修正するべき箇所は、SHK.mファイルの、-(void)hideCurrentViewControllerAnimated:(BOOL)animated の内部だ。これを次のように修正すればよい。
- (void)hideCurrentViewControllerAnimated:(BOOL)animated
{
 if (isDismissingView) {
  return;
 }
 if (currentView != nil) {
  // Dismiss the modal view
  if ([currentView parentViewController] != nil) {
   self.isDismissingView = YES;
   [[currentView parentViewController] dismissModalViewControllerAnimated:animated];
  }
  else if ([currentView presentingViewController] != nil) {
   self.isDismissingView = YES;
   [[currentView presentingViewController] dismissModalViewControllerAnimated:animated];
  }
  else {
   self.currentView = nil;
  }
 }
}

2011-11-17

FacebookアプリとTwitterアプリのUser-Agent

iPhoneのFacebookアプリとTwitterアプリはブラウザ機能を持っていて、友達が共有したリンクを開くときはこのブラウザを利用する人も多い。
このアプリのブラウザは、それぞれ独自のUserAgentを持っているようだ。自分のiPhoneで確認してみると、次のようなUser-Agentが取得できた。
  • Twitter for iPhone
    • Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405 Twitter for iPhone
  • Facebook for iPhone
    • Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_0_1 like Mac OS X; ja_JP) AppleWebKit (KHTML, like Gecko) Mobile [FBAN/FBForIPhone;FBAV/4.0.2;FBBV/4020.0;FBDV/iPhone3,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/5.0.1;FBSS/2; FBCR/
User-Agentによってサーバー側で処理を変える場合に利用できそうだ。

2011-11-09

Conversion to Dalvik format failed with error 1 再来



Androidでrelease用にビルドをしたときに限って、「Conversion to Dalvik format failed with error 1」というエラーになる問題が再発生した。以前にこのエラーに見舞われたときは、コンソールで、eclipse.exe -clean という具合に起動オプション付きでeclipseを立ち上げたら解決したが、今回はそれでも解決しなかった。プロジェクトをクリーンしたりFix Project Propertiesを実行したり色々ためしたが駄目だった。

気になったのは、debugのときは正常にビルドできるのに、releaseモードで失敗するということだ。これは何故だろうと思って調べたら、proguardを使っているのがエラーの原因だとわかった。proguardはreleaseモードでのみ動作するため、ここで失敗しているのだ。

proguard.cfgに、名前を書き換えないクラスなどを指定すれば、おそらく正常にビルドできるはず。たとえば、layout.xml内で参照しているクラスなどは、名前を書き換えてはいけないクラスに相当する。
だが困ったことに、このプロジェクトはandroid-support-v4.jarを参照していた。これを参照する場合に、proguard.cfgをどのように記述したらいいのか、さっぱり分からなかった。結局挫折して、proguardを使うのをあきらめた。

CentOS5にmemcachedをインストールする

どうやら昔はyumでmemcachedをインストールできたみたいだが、いまはrpmforgeを追加してもmemcacheが見つからない。そこで、次のようにしてCentOS5にmemcachedをインストールした。

# yum -y install libevent-devel
# wget http://memcached.googlecode.com/files/memcached-1.4.9.tar.gz
# tar -zxvf memcached-1.4.9.tar.gz
# cd memcached-1.4.9
# ./configure
# make
# make install

なぜだか知らないが、wget http://memcached.org/latest でソースをダウンロードした場合は上手くmakeできなかった。

起動時にmemcachedが自動で起動されるように次の設定もした。

# vi /etc/rc.d/init.d/memcached
=====ここからviで追加=====
#!/bin/bash
#
# memcached
#
# chkconfig: 345 80 20
# description: memcached

TARGET=memcached
DST_BIN=/usr/local/bin/${TARGET}
EXEC_USER=apache
CACHE_SIZE=64

start()
{
  echo -n "Starting ${TARGET}: "
  ${DST_BIN} -d -u ${EXEC_USER} -m ${CACHE_SIZE}
  echo
}

stop()
{
  echo -n "Shutting down ${TARGET}: "
  killall ${TARGET}
  echo
}

case "$1" in
  start)
    start
    ;;

  stop)
    stop
    ;;

  restart)
    stop
    start
    ;;

  *)
    echo "Usage: `basename $0` {start|stop|restart}" >&2
    exit 1
esac

exit 0
=====ここまで=====
# chmod 755 /etc/rc.d/init.d/memcached
# chkconfig --add memcached
# chkconfig memcached on
# service memcached start

今回の目的は、Djangoでcacheを利用することだったので、yumで、python-memcachedのインストールも行った。

# yum -y install python-memcached

CentOS5にGITをインストールする

# rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
# wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.i386.rpm
# rpm -i rpmforge-release-0.5.2-2.el5.rf.i386.rpm
# yum -y install git

次のようにして、

# vim /etc/yum.repos.d/rpmforge.repo
==ここから===
#enabled = 1
enabled = 0
===
# yum -y --enablerepo=rpmforge install git

2011-11-04

Apacheのログに処理時間を残す

Apacheのaccess_logに、レスポンスを返すまでの処理時間が記録されるようにするには、httpd.confの設定を少し変更すればよい。
LogFormatで、「%D」と指定することによって、処理時間がマイクロ秒単位で記録される。
Linuxの場合は、
  # vi /etc/httpd/conf/httpd.conf
とやって、

  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" combined

と書く。httpd.confの前後の部分も抜粋すると次のようになる:
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
#
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

# "combinedio" includes actual counts of actual bytes received (%I) and sent (%O); this
# requires the mod_logio module to be loaded.
#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio