3

私のアプリは、iPhone/iPad で書籍を閲覧するための電子書籍リーダーです。ユーザーは、デバイスに保存された書籍を .epub ファイル (zip コンテンツ) としてダウンロードするオプションを利用できます。これにより、オフラインで書籍を表示できるようになります。ページの内容は html です。

ただし、ビデオなどの一部のアセットは、この .epub コンテンツには含まれていません。ユーザーがそのようなページに移動すると、.ePub にない外部アセットを検出し、「このコンテンツはオフライン時は利用できません」というテキストを含む単純なプレースホルダーを表示する必要があります。

これらのビデオは、iFrame html タグまたは object タグに埋め込むことができます。

現在、NSURLProtocol 抽象クラスから継承するクラスがあり、それを使用してこの要件を処理しています。これらの 3 つのメソッドの実装があります。

+ (BOOL) canInitWithRequest:(NSURLRequest *)request

- (void)startLoading

- (void) sendResponse:(NSData *)data mimetype:(NSString *)mimetype url:(NSURL *)url

私の問題は、「このコンテンツはオフラインのときは利用できません」という単純な .png があることですが、iFrame の領域が画像よりも小さい場合があるため、見苦しくなります。フィットするようにスケーリングするにはどうすればよいですか?または、より良いアプローチがありますか?コンテンツが利用できないというこのメッセージを表示できる限り、画像である必要はありません。startLoading メソッドの現在のコード:

- (void) startLoading
{
    …
    NSString *bundlePath = [NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] bundlePath],@"PxeReaderResources.bundle"];
    NSString *pathToPlaceholder = [NSString stringWithFormat:@"%@/%@",bundlePath,@"OfflinePlaceholder.png"]; //my placeholder image
    NSLog(@"Path to placeholder is: %@", pathToPlaceholder);

    data = [[NSFileManager defaultManager] contentsAtPath:pathToPlaceholder];

    … 

    [self sendResponse:data mimetype:@"application/octet-stream" url:self.request.URL];
}

- (void) sendResponse:(NSData *)data mimetype:(NSString *)mimetype url:(NSURL *)url
{
    NSDictionary *headers = @{@"Content-Type" : mimetype, @"Access-Control-Allow-Origin" : @"*", @"Cache-control" : @"no-cache"};
    NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headers];

    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [self.client URLProtocol:self didLoadData:data];
    [self.client URLProtocolDidFinishLoading:self];
}

ご提案ありがとうございます。

4

2 に答える 2

1

外部アセットの代わりに、シンプルなカスタム html div タグを送信できました。これがコードです-これが誰かの助けになることを願っています. 注: このコードはすべて、NSURLProtocol から継承するカスタム クラスにあります。

#define EXTERNAL_REQUEST_KEY @"ExternalRequest"

+ (BOOL) canInitWithRequest:(NSURLRequest *)request
{
     NSString* filePath = [[PxePlayer sharedInstance] getBaseURL]; //gets base path to the epub zipped folder

    if ([Reachability isReachable])
    {
        return filePath != nil && [@"file" caseInsensitiveCompare:request.URL.scheme] == NSOrderedSame;
    }
    else
    {
        if ([request.URL.scheme isEqualToString:@"https"] || [request.URL.scheme isEqualToString:@"http"]) //these schemes won't work if offline
        {
            [NSURLProtocol setProperty:@YES forKey:EXTERNAL_REQUEST_KEY inRequest:(NSMutableURLRequest*)request]; //marking those request so that we will only provide placeholder for these requests
        }
        return filePath != nil && ([@"file" caseInsensitiveCompare:request.URL.scheme] == NSOrderedSame ||
                               [@"https" caseInsensitiveCompare:request.URL.scheme] == NSOrderedSame ||
                               [@"http" caseInsensitiveCompare:request.URL.scheme] == NSOrderedSame);
    }
}

- (void) startLoading
{
    ...

    if ([NSURLProtocol propertyForKey:EXTERNAL_REQUEST_KEY inRequest:self.request])
    {   
        custMimeType = @"text/html";

        data = [self prepareDataForPlaceholderForExternalAsset];
    }

    ...

    if (data)
    {
        //Now ready to send the placeholder as custom response
        [self sendResponse:data mimetype:custMimeType url:self.request.URL];
    }
}

//method to create a simple div tag as NSData
- (NSData*) prepareDataForPlaceholderForExternalAsset
{
    NSString *placeholder =
    @"<div style=\"background-color:#efefef; border:1px solid #999999; text-align:center; width:100%; height:100%\"> \
        <font font-family=\"Helvetica Neue\" font-weight=\"Medium\" size=\"5\" color=\"#b3b3b3\"> \
          <div style=\"display:inline-block; margin-top:5%\"> \
            This content is unavailable when offline or printing \
          </div> \
        </font> \
      </div>";

    return [placeholder dataUsingEncoding:NSUTF8StringEncoding];
}

- (void) sendResponse:(NSData *)data mimetype:(NSString *)mimetype url:(NSURL *)url
{
    NSDictionary *headers = @{@"Content-Type" : mimetype, @"Access-Control-Allow-Origin" : @"*", @"Cache-control" : @"no-cache"};
    NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url statusCode:200 HTTPVersion:@"HTTP/1.1" headerFields:headers];

    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [self.client URLProtocol:self didLoadData:data];
    [self.client URLProtocolDidFinishLoading:self];
}
于 2015-09-18T04:07:43.053 に答える
0

リソースの読み込みを傍受しようとする代わりに、JavaScript を使用 (挿入) して DOM を走査し、これらのオブジェクト/iframe タグを探して、「オフラインでは使用できません」というメッセージに置き換えることができます。ページがロードされたらこれを行うか、WebView に渡される前に HTML の解析と変更を試みることができます。

于 2015-09-17T16:58:11.367 に答える