How to access image resource in asset catalog from UIWebView (or WKWebView)

Since the asset catalog is stored in the bundle as a single file, there's no way to get an URL to a singular asset.

The simplest solution is to NOT use the asset catalog for images you'll show in a web view.

If keeping the images in the asset catalog is essential, your only option is to "unpack" the required asset(s) into distinct files to the documents directory of the application bundle, and then reference those files.


There is a way to access image resource in asset catalog from UIWebView. You should create NSUrlProtocol subclass, register your new protocol and manually respond for WebView images request.

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@end

@implementation AppDelegate
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        [NSURLProtocol registerClass:[ImageProtocol class]];    
        //... other code
        return YES;
    }
@end

@interface ImageProtocol : NSURLProtocol
@end

@implementation ImageProtocol

    + (BOOL)canInitWithRequest:(NSURLRequest *)request {
        NSString *imgName = (NSString *)[[request.URL.absoluteString componentsSeparatedByString:@"/"] lastObject];
        AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
        NSLog(@"imgName = %@",imgName);
        if ([UIImage imageNamed:imgName] != nil) {// or check for explicit name "target_image.png"
            return YES;
        }
        return NO;
    }

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

    + (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b{
        return [super requestIsCacheEquivalent:a toRequest:b];
    }

    - (void)startLoading {
        NSString *imgName = (NSString *)[[self.request.URL.absoluteString componentsSeparatedByString:@"/"] lastObject];
        UIImage *img = [UIImage imageNamed:imgName];
        NSString *mimeType = @"image/png";
        @try {
            NSData *imageData = nil;

            if ([imgName hasSuffix:@".png"]) {
                imageData = UIImagePNGRepresentation(img);
            } else if ([imgName hasSuffix:@".jpg"]) {
                imageData = UIImageJPEGRepresentation(img, 1);
                mimeType = @"image/jpg";
            }

            NSString *encoding = @"utf-8";
            NSURLResponse *response = [[NSURLResponse alloc] initWithURL:self.request.URL
                                                        MIMEType:mimeType
                                           expectedContentLength:imageData.length
                                                textEncodingName:encoding];

            [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
            [self.client URLProtocol:self didLoadData:imageData];
            [self.client URLProtocolDidFinishLoading:self];
        } @catch (NSException *exception) {
            NSError *err = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil];
            [self.client URLProtocol:self didFailWithError:err];
            NSLog(@"%@",exception.debugDescription);
        }
    }

    - (void)stopLoading {
    // do nothing
    }

    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
        [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    }

    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.client URLProtocol:self didLoadData:data];
    }

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
        [self.client URLProtocolDidFinishLoading:self];
    }

    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
        [self.client URLProtocol:self didFailWithError:error];
    }

@end