@blog.justoneplanet.info

日々勉強

UIWebViewをカスタマイズする

WebViewっぽくならないようにバウンスをさせないようにし、HTTPリクエストにカスタムヘッダーを付加するようにした。たいしてカスタマイズしてない。

#import <UIKit/UIKit.h>
@interface CustomWebView : UIWebView
@end
#import "CustomWebView.h"
@implementation CustomWebView
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {// Initialization code
        // バウンスさせない
        for (id subview in self.subviews) {
            if ([[subview class] isSubclassOfClass: [UIScrollView class]]) {
                ((UIScrollView *)subview).bounces = NO;
            }
        }
    }
    return self;
}

- (void)loadRequest:(NSURLRequest *)request
{
    // カスタムヘッダーの付加
    NSMutableURLRequest *mutableRequest = (NSMutableURLRequest *)[request mutableCopy];
    [mutableRequest setValue:@"iOS.UIWebView" forHTTPHeaderField:@"App-Client"];
    [super loadRequest:mutableRequest];
}
@end

以下のようにオフライン時の画面を表示するメソッドを作ってあげてもいいと思う。

- (void)displayOfflineView
{
    if (self) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"offline" ofType:@"html"];
        [self loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]];
    }
}

webviewを表示した時に圏外の場合、圏内になった時にreloadをしても正しく表示ができないので以下のようなメソッドも加えておく。

- (void)dealloc
{
    if (initialRequest) {
        [initialRequest release];
    }
    [super dealloc];
}
- (void)reload
{
    if (self) {
        if ([self canGoBack]) {
            [super reload];
        }
        else if (initialRequest) {
            [self loadRequest:initialRequest];
        }
    }
}
- (void)loadRequest:(NSURLRequest *)request
{
    [super loadRequest:request];
    if (!initialRequest) {
        initialRequest = [request retain];
    }
}

■カスタムヘッダの付加

ただし、上述の方法ではUIWebView内のリンクをクリックした時にはカスタムヘッダが付加されないので以下のようにする。

- (void) _internalInit {
    super.delegate = self;
    foreignDelegate = nil;
}
- (id) init {
    if((self = [super init])) {
        [self _internalInit];
    }
    return self;
}
- (id) initWithCoder:(NSCoder *)aDecoder {
    if((self = [super initWithCoder:aDecoder])) {
        [self _internalInit];
    }
    return self;
}
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {// Initialization code
        [self _internalInit];
    }
    return self;
}
- (void)dealloc
{
    [super dealloc];
}
// offline画面を表示する
- (void)displayOfflineView
{
    if (self) {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"offline" ofType:@"html"];
        [self loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]];
    }
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/
- (void) setDelegate:(id<UIWebViewDelegate>)aDelegate {
    if(foreignDelegate == aDelegate) {
        return;
    }
	
    [foreignDelegate release];
    foreignDelegate = [aDelegate retain];
    /* Make sure this class is still the real delegate */
    super.delegate = self;
}
- (id<UIWebViewDelegate>) delegate {
    return foreignDelegate;
}
- (void) setCustomHeaders:(NSDictionary *)cHeaders {
    NSMutableDictionary *newHeaders = [NSMutableDictionary dictionary];
    for(NSString *key in [cHeaders allKeys]) {
        NSString *lowercaseKey = [key lowercaseString];
        [newHeaders setObject:[cHeaders objectForKey:key] forKey:lowercaseKey];
    }
    [customHeaders release];
    customHeaders = [newHeaders retain];
}
#pragma mark -
#pragma mark UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)aRequest navigationType:(UIWebViewNavigationType)navigationType {    
    
    BOOL missingHeaders = NO;
    
    /* Take all headers keys, lowercase them */
    NSArray *currentHeaders = [[aRequest allHTTPHeaderFields] allKeys];
    NSMutableArray *lowercasedHeaders = [NSMutableArray array];
    for(NSString *key in currentHeaders) {
        [lowercasedHeaders addObject:[key lowercaseString]];
    }
    
    /* See if there's at least one custom header missing */
    for(NSString *key in customHeaders) {
        if(![lowercasedHeaders containsObject:key]) {
            missingHeaders = YES;
            break;
        }
    }
    
    /* If one is missing, drop current request, and make a new one
     * with custom header */
    if(missingHeaders) {
        NSMutableURLRequest *newRequest = [aRequest mutableCopy];
        for(NSString *key in [customHeaders allKeys]) {
            [newRequest setValue:[customHeaders valueForKey:key] forHTTPHeaderField:key];
        }
        [self loadRequest:newRequest];
        [newRequest release];
        return YES;
    }
    
    //NSLog(@"Loading request with HTTP headers %@", [aRequest allHTTPHeaderFields]);
    
    if([foreignDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) {
        return [foreignDelegate webView:self shouldStartLoadWithRequest:aRequest navigationType:navigationType];
    }
    
    return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
    if([foreignDelegate respondsToSelector:@selector(webViewDidStartLoad:)])
        [foreignDelegate webViewDidStartLoad:self];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    if([foreignDelegate respondsToSelector:@selector(webViewDidFinishLoad:)])
        [foreignDelegate webViewDidFinishLoad:self];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    if([foreignDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)])
        [foreignDelegate webView:self didFailLoadWithError:error];
}

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment