We have a local html to show in UIWebView
. And there, we want to show images that are defined in Asset Catalog.
I know that we can do similar thing if we had the image flat in the main bundle. The code snippet would be like this.
webView.loadHTMLString("<img src='target_image.png'/>", baseURL: NSBundle.mainBundle().bundleURL)
However, I am not sure what I can specify for "target_image.png" if the png file is packaged in asset catalog. (Furthermore, we want to specify pdf to take advantage of vector image support in Xcode 6)
Does anybody have any idea how to achieve this?
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