// Classes/MainViewController.m:
- (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSDictionary *headers = [request allHTTPHeaderFields];
    BOOL hasWhateverAddedHeader = NO;
    
    for (NSString *key in [headers allKeys]) {
		if([key isEqualToString:@"X-Access-From-Cordova"]) {
			hasWhateverAddedHeader = YES;
			break;
		}
	}
    
    if (!hasWhateverAddedHeader) {
        NSMutableURLRequest *newRequest = [request mutableCopy];
        [newRequest addValue:@"true" forHTTPHeaderField:@"X-Access-From-Cordova"];
        [theWebView loadRequest:newRequest];
        [newRequest release];
        return NO;
    } else {
        return YES;
    }
}

無理くり。ヘッダはCordovaLibではなくアプリの方いじるだけで行けました。

// Classes/Cleaver/CDVViewController.m:
    if (startFilePath == nil) {
        loadErr = [NSString stringWithFormat:@"ERROR: Start Page at '%@/%@' was not found.", self.wwwFolderName, self.startPage];
        NSLog(@"%@", loadErr);
        self.loadFromString = YES;
        appURL = nil;
    } else {
        appURL = [NSURL fileURLWithPath:startFilePath];
    }
+    appURL = [NSURL URLWithString:@"http://kowabana.jp"];

iPhone版はローカルファイル前提になってるのでCordovaLibを無理矢理変える。

のを直してプルリク送った。採用されよ。

phonegap-plugins/Android at master · phonegap/phonegap-plugins · GitHub

javaのpull requestはじめてだ。

cordova1.9.0からそれまではctxって名前だったcontextオブジェクトがcordovaって名前になっててちょっと変わったので変更する必要有り。

masterではLegacyContextって名前でproxy的Contextが入ってるので1.9.1では動くようになるだろうけど、今後contextはcordovaって方向らしいので。

BUILD FAILED
/Users/komagata/android-sdks/tools/ant/build.xml:622: The following error occurred while executing this line:
/Users/komagata/android-sdks/tools/ant/build.xml:642: '${renderscript.opt.level}' is not a permitted value for com.android.ant.RenderScriptTask$OptLevel

Android Tools Rev20にアップデートしたらこのようにbuildできなくなった人のためにおいておきます。

renderscript.opt.level=O0

% git diff ant.properties 
diff --git a/framework/ant.properties b/framework/ant.properties
index 243b691..5ddf4f2 100644
--- a/framework/ant.properties
+++ b/framework/ant.properties
@@ -31,4 +31,4 @@
 #  'key.store' for the location of your keystore and
 #  'key.alias' for the name of the key to use.
 # The password will be asked during the build when you use the 'release' target.
-
+renderscript.opt.level=O0

cordovaを使う時にhamlとsassとcoffeeを使いたかったのでguardでそれぞれをwatchするようにした。

普段は何らかのWebサーバーが立ち上がってて出力を直接返すからこういう風にそれぞれの静的ファイルを必要とすることって意外と少ないですね。

$ gem install guard-haml guard-sass guard-coffeescript

Terminal — zsh — 80×24

このようなディレクトリ構成にする場合。

# Guardfile
haml_options = { format: :html5, attr_wrapper: '"', ugly: true } 
guard "haml", input: "haml", output: "www", haml_options: haml_options  do
  watch %r{^haml/.+\.haml}     
end
guard "sass", input: "sass", output: "www/stylesheets"
guard "coffeescript", input: "coffeescripts", output: "www/javascripts", bare: true

GUIのCodeKitってヤツを試したんだけど、ちょっとカスタマイズしたくなるとやっぱりCLIが便利ですね。

今日、Cordovaでようやく具体的なアプリを書き始めて今回のアプリにはCordova使えないことがほぼ確定してしまった。

冷静に考えれば当たり前っぽいけど、

「サーバー上にあるHTML・Javascriptなどのリソースはローカル上のリソース(アプリ内)にアクセスできない」

Cordova(元PhoneGap)を選択したのは、Web版・Android版・iPhone版の殆どを共通のソースで作れるハズという仮説に基づいていたが、それが瓦解した・・・。

3種類が共通のソースでできず、新規に書く必要がある状況ではカクカクした動きになってしまうCordovaを使うメリットは無い。

需要の無い問題を解決してしまった!

今月中にリリースとか思ってたけどこれはヤバイ。

投稿できないビューワー専用にしてでも、機能最低限版を作らねば。

となると、ネイティブよりTitaniumの方が早くできそうだ。殆ど選択肢は無い・・・。

怖話はスマホ向けWebサイトです。今のスマホのHTML5 Audioではサウンドノベル風に音を鳴らすのが難しいのでcordovaでアプリ版を作っています。

しかし、サーバー側で普通のブラウザからのアクセスなのか、cordovaからのアクセスなのか区別がつかない。数ページ程度だったらquery stringにでも何か付けてアクセスするようにすればいいけど、怖話はサイト全体に渡ってどちらからもアクセスされる可能性があるのでcookieが使えないガラケーのようなquery string引き回しなどはやりたくない。

StackOverflow駆け込み寺に問い合わせたところ、10minで答えが来た

「cordovaのソース弄ってヘッダ追加すれば?」

なるほどですねー!

% git diff
diff --git a/framework/src/org/apache/cordova/DroidGap.java b/framework/src/org/apache/cordova/DroidGap.java
index 5e2586d..dfbdb44 100755
--- a/framework/src/org/apache/cordova/DroidGap.java
+++ b/framework/src/org/apache/cordova/DroidGap.java
@@ -562,7 +562,9 @@ public class DroidGap extends Activity implements CordovaInterface {
                 };
                 Thread thread = new Thread(runnable);
                 thread.start();
-                me.appView.loadUrl(url);
+                HashMap headers = new HashMap();
+                headers.put("X-Access-From-Cordova", "true");
+                me.appView.loadUrl(url, headers);
             }
         });
     }

X-Access-From-Cordovaという勝手なヘッダを付けて、以前のエントリー通りcordovaをbuildして自分のプロジェクトに放り込む。

サーバー側(Rails)に下記helperを追加。

# app/helpers/application_helper.rb
module ApplicationHelper
  def cordova?
    request.headers['X-Access-From-Cordova'] == 'true'
  end
end

神様仏様StackOverflow大明神様 <3 <3 <3

README通りで問題無い。

commons codecをdownload

% cd ~/Downloads
% curl -OL http://ftp.meisei-u.ac.jp/mirror/apache/dist//commons/codec/binaries/commons-codec-1.6-bin.tar.gz
% tar zxf commons-codec-1.6-bin.tar.gz

cordova android版をbuild

% git clone https://github.com/apache/incubator-cordova-android.git
% cd incubator-cordova-android/framework
% cp ~/Downloads/commons-codec-1.6/commons-codec-1.6.jar libs/
% android update project -p . -t android-15
% ant jar
% ls cordova*.jar
cordova-1.7.0.jar

やったネ。