Entries tagged “iOS”

Safariからアプリを立ち上げる時に、インストールされていなかったら案内を出したい

written by shn, on Feb 2, 2012 1:32:00 AM.

タイトルな要望があったときにどうしたら良いのかなぁと調べようにも、どう調べよう? stackoverflowでどう調べればいいか思いつかないや。

アプリがあれば、Safariからアプリに切り替わる。無ければ、切り替わらずにアラートが出る。ということなので、以下のコードを書いた。

$(function() {
  $('a.launch-app').on('click', function(e) {
    $('#alert').hide();

    var timerId = setTimeout(function() {
      $('#alert').show();
      $(window).unbind('pagehide.appchecker');
    }, 500);

    $(window).bind('pagehide.appchecker', function() {
      clearTimeout(timerId);
      $(window).unbind('pagehide.appchecker');
    });
  });

アラートを出さないようにする。(もしくは、実際に遷移させようとする前にアプリがインストールされているか調べる方法はないのだろうか?

カスタムリソースにはNSURLProtocolを使えば良いのじゃないか?

written by shn, on Oct 4, 2011 11:05:00 PM.

「UIWebView の取り扱いによってはjavascript経由でサンドボックス外のファイルシステムにアクセスできてしまうという話と対処法」 で、UIWebViewにfile://スキームのリソースを表示する場合の脆弱性について触れられていた。 ちょうど自分もこのあたりの仕組みが必要だったのでいろいろ試してみたのだけど、結論から言えば、その場合はNSURLProtocolを使えば良いと思う。

CocoaではUIWebViewやその下のNSURLConnectionがアクセスするリソースはNSURLProtocolで抽象化されているので、 独自のスキームを定義し、それを通してアプリケーション内のリソースを表示するようにする。

以下のようなNSURLProtocolのサブクラスを定義する。:

@interface HogeProtocol : NSURLProtocol
@end

@implementation HogeProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
    return [[[request URL] scheme] isEqualToString:@"hoge"];
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
    return request;
}

- (void)startLoading {
    // ファイルから小さいリソースを読むぐらいだったら、dispachしなくても良いのかな...
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    NSString *filePath = [...] ///< self.request URL]から、該当するリソースのpathを
    NSString *mimeType = @"text/html"; ///< ここも

    dispatch_async(queue, ^{
        NSData *data = [NSData dataWithContentsOfFile:data];

        if(!data) {
            [self.client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable:nil]];
            return;
        }

        [self.client URLProtocol:self didReceiveResponse:[[[NSURLResponse alloc] initWithURL:[self.request URL] 
                MIMEType:mimeType
                expectedContentLength:[data length]
                textEncodingName:@"UTF-8"] autorelease] cacheStoragePolicy:NSURLCacheStorageNotAllowed];
        [self.client URLProtocol:self didLoadData:data];
        [self.client URLProtocolDidFinishLoading:self];
    });
}

- (void)stopLoading {
    // stopLoadingが来たらデータの読み込みを中断するのだが、このコードだと中断しようが無い...
}
@end

随所が適当だが、こんな感じのを作って、UIWebViewでhoge:///スキームのリソースを読み込む:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"hoge:///index"]]];

リソース内で、例えば、<img src="sexy.jpg">のように相対パスでリソースをしても、hoge:///sexy.jpgのようなクエリが飛ぶので一安心。

実際には、リソース読み込み部分をカスタマイズして動的なデータにも対応していけば良いのだと思う。

ってほぼ↓のサンプルのコピペだな。

WebにはAppleのリファレンスぐらいしか情報がなかった。