Как получить доступ к ресурсу изображения в каталоге активов из UIWebView (или WKWebView)
У нас есть локальный html для отображения в UIWebView
. И там мы хотим показать изображения, которые определены в Каталоге активов.
Я знаю, что мы можем сделать подобное, если бы изображение было плоским в главном комплекте. Этот фрагмент кода будет таким.
webView.loadHTMLString("<img src='target_image.png'/>", baseURL: NSBundle.mainBundle().bundleURL)
Однако я не уверен, что я могу указать для "target_image.png", если png файл упакован в каталог активов. (Кроме того, мы хотим указать pdf, чтобы использовать поддержку векторных изображений в Xcode 6)
Кто-нибудь знает, как это достичь?
Ответы
Ответ 1
Поскольку каталог активов хранится в пакете как один файл, нет способа получить URL-адрес для особого актива.
Самое простое решение - НЕ использовать каталог активов для изображений, которые вы увидите в веб-представлении.
Если сохранение изображений в каталоге активов имеет важное значение, единственным вариантом является "распаковать" требуемый актив в отдельные файлы в каталог документов пакета приложений, а затем ссылаться на эти файлы.
Ответ 2
Существует способ доступа к ресурсу изображений в каталоге активов из UIWebView.
Вы должны создать подкласс NSUrlProtocol
, зарегистрировать новый протокол и ответить вручную на запрос изображений WebView.
@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