3

My setup:
I have a webview in my iPhone app, going to www.mysite.com.

Trials
If I set "backgroundcolor uicolor clearcolor" to my webview and draw an uiimage behind my webview, it won't scroll with my webview!

My problem:
I would like the image to with the webview. Also, this image should be stored in the iPhone app and not on the webserver (Of course, if I put the image on the webserver I can simply draw it as background with CSS).

What is the best way to access this image via html/javascript/Objective C, so I can see this local image as background of my website? Is there a way at all?

andreas
  • 7,844
  • 9
  • 51
  • 72
  • This Link contain simple answer [using-html-and-local-images-within-uiwebview][1] [1]: http://stackoverflow.com/questions/747407/using-html-and-local-images-within-uiwebview – Naveen Shan Feb 10 '12 at 10:57

2 Answers2

8

You have a couple of options. You can load the page with a baseURL of

[[NSBundle mainBundle] bundleURL]

or you can use javascript to set the path to your image using the following method.

[[NSBundle mainBundle] URLForResource:@"myimage" withExtension:@"png"]

Edit: Check here Link to resources inside WebView - iPhone. It looks like you will use pathForResource rather than URLForResource.

Edit 2: You may want to use Data URI's to add your own local files to the web site.

YourCode.m

#import "NSString+DataURI.h"
#import "NSData+Base64.h"
...

-(void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSString *imgPath = [[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"];
    NSData *imgData = [NSData dataWithContentsOfFile:imgPath];
    NSString *imgB64 = [[imgData base64Encoding] pngDataURIWithContent];

    NSString *javascript = [NSString stringWithFormat:@"document.body.style.backgroundImage='url(%@)';", imgB64];
    [webView stringByEvaluatingJavaScriptFromString:javascript];
}

The following code I DID NOT WRITE and I am not sure of the origin

NSData+Base64.h

@interface NSData (Base64) 

+ (NSData *)dataWithBase64EncodedString:(NSString *)string;
- (id)initWithBase64EncodedString:(NSString *)string;

- (NSString *)base64Encoding;
- (NSString *)base64EncodingWithLineLength:(unsigned int) lineLength;

@end

NSData.Base64.m

#import "NSData+Base64.h"

static char encodingTable[64] = {
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };

@implementation NSData (VQBase64)

- (id)initWithString:(NSString *)string {
    if ((self = [super init])) {
        [self initWithBase64EncodedString:string];
    }
    return self;

}


+ (NSData *) dataWithBase64EncodedString:(NSString *) string {
    return [[[NSData allocWithZone:nil] initWithBase64EncodedString:string] autorelease];
}

- (id) initWithBase64EncodedString:(NSString *) string {
    NSMutableData *mutableData = nil;

    if( string ) {
        unsigned long ixtext = 0;
        unsigned long lentext = 0;
        unsigned char ch = 0;
        unsigned char inbuf[4], outbuf[3];
        short i = 0, ixinbuf = 0;
        BOOL flignore = NO;
        BOOL flendtext = NO;
        NSData *base64Data = nil;
        const unsigned char *base64Bytes = nil;

        // Convert the string to ASCII data.
        base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
        base64Bytes = [base64Data bytes];
        mutableData = [NSMutableData dataWithCapacity:[base64Data length]];
        lentext = [base64Data length];

        while( YES ) {
            if( ixtext >= lentext ) break;
            ch = base64Bytes[ixtext++];
            flignore = NO;

            if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
            else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
            else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
            else if( ch == '+' ) ch = 62;
            else if( ch == '=' ) flendtext = YES;
            else if( ch == '/' ) ch = 63;
            else flignore = YES;

            if( ! flignore ) {
                short ctcharsinbuf = 3;
                BOOL flbreak = NO;

                if( flendtext ) {
                    if( ! ixinbuf ) break;
                    if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
                    else ctcharsinbuf = 2;
                    ixinbuf = 3;
                    flbreak = YES;
                }

                inbuf [ixinbuf++] = ch;

                if( ixinbuf == 4 ) {
                    ixinbuf = 0;
                    outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
                    outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
                    outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );

                    for( i = 0; i < ctcharsinbuf; i++ )
                        [mutableData appendBytes:&outbuf[i] length:1];
                }

                if( flbreak )  break;
            }
        }
    }

    self = [self initWithData:mutableData];
    return self;
}

#pragma mark -

- (NSString *) base64Encoding {
    return [self base64EncodingWithLineLength:0];
}

- (NSString *) base64EncodingWithLineLength:(unsigned int) lineLength {
    const unsigned char     *bytes = [self bytes];
    NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
    unsigned long ixtext = 0;
    unsigned long lentext = [self length];
    long ctremaining = 0;
    unsigned char inbuf[3], outbuf[4];
    unsigned short i = 0;
    unsigned short charsonline = 0, ctcopy = 0;
    unsigned long ix = 0;

    while( YES ) {
        ctremaining = lentext - ixtext;
        if( ctremaining <= 0 ) break;

        for( i = 0; i < 3; i++ ) {
            ix = ixtext + i;
            if( ix < lentext ) inbuf[i] = bytes[ix];
            else inbuf [i] = 0;
        }

        outbuf [0] = (inbuf [0] & 0xFC) >> 2;
        outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
        outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
        outbuf [3] = inbuf [2] & 0x3F;
        ctcopy = 4;

        switch( ctremaining ) {
            case 1:
                ctcopy = 2;
                break;
            case 2:
                ctcopy = 3;
                break;
        }

        for( i = 0; i < ctcopy; i++ )
            [result appendFormat:@"%c", encodingTable[outbuf[i]]];

        for( i = ctcopy; i < 4; i++ )
            [result appendString:@"="];

        ixtext += 3;
        charsonline += 4;

        if( lineLength > 0 ) {
            if( charsonline >= lineLength ) {
                charsonline = 0;
                [result appendString:@"\n"];
            }
        }
    }

    return [NSString stringWithString:result];
}

@end

NSString+DataURI.h

#import <Foundation/Foundation.h>

@interface NSString(DataURI)
- (NSString *) pngDataURIWithContent;
- (NSString *) jpgDataURIWithContent;
@end

NSString+DataURI.m

#import "NSString+DataURI.h"


@implementation NSString(DataURI)

- (NSString *) pngDataURIWithContent;
{
    NSString * result = [NSString stringWithFormat: @"data:image/png;base64,%@", self];
    return result;
}

- (NSString *) jpgDataURIWithContent;
{
    NSString * result = [NSString stringWithFormat: @"data:image/jpg;base64,%@", self];
    return result;
}

@end
Community
  • 1
  • 1
Joe
  • 56,979
  • 9
  • 128
  • 135
  • I tried a javascript injection, loading this javascript string: [NSString stringWithFormat:@"document.body.style.background='url(%@)'", [[NSBundle mainBundle] URLForResource:@"background" withExtension:@"png"]]; As I explained, the webview loads an external page and should display the local background. Even if the background image url is correct (checked it with logging), this doesn't work at all? Any idea? – andreas Mar 17 '11 at 00:40
  • I used the baseURL option with my code. Did you follow the link I provided in my edit? – Joe Mar 17 '11 at 12:52
  • Yes I have, thank you! But in their example they are talking about including local html files and not external files. How and where to set the bundleURL then? Maybe I'm missing something, but I don't understand how to make it work for external files. – andreas Mar 17 '11 at 13:29
  • 1
    Just added a large edit for you. Create the files for NSData+Base64 and NSString+DataURI in your project. – Joe Mar 17 '11 at 14:35
  • Yes, this is a cool approach! Thanks a lot for that, it works for me. But it's hard to believe that I need to include 100 lines of new code for one single background image. :D – andreas Mar 17 '11 at 14:50
  • I would think that the bundle url would work but I was not able to get it to work either. Hopefully someone will chime in with a working example of a file url. – Joe Mar 17 '11 at 14:54
0

You could simply add this line

webView.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"light.jpg"]];
Shob-Z
  • 891
  • 6
  • 26