Ios 如何从UIWebView(或WKWebView)访问资源目录中的图像资源
我们有一个本地html要在Ios 如何从UIWebView(或WKWebView)访问资源目录中的图像资源,ios,uiwebview,asset-catalog,Ios,Uiwebview,Asset Catalog,我们有一个本地html要在UIWebView中显示。在这里,我们希望显示在资产目录中定义的图像 我知道,如果我们把图像放在主包中,我们也可以做类似的事情。代码片段如下所示 webView.loadHTMLString("<img src='target_image.png'/>", baseURL: NSBundle.mainBundle().bundleURL) webView.loadHTMLString(“”,baseURL:NSBundle.mainBundle().bun
UIWebView
中显示。在这里,我们希望显示在资产目录中定义的图像
我知道,如果我们把图像放在主包中,我们也可以做类似的事情。代码片段如下所示
webView.loadHTMLString("<img src='target_image.png'/>", baseURL: NSBundle.mainBundle().bundleURL)
webView.loadHTMLString(“”,baseURL:NSBundle.mainBundle().bundleURL)
但是,如果png文件打包在资产目录中,我不确定可以为“target_image.png”指定什么。(此外,我们希望指定pdf以利用Xcode 6中的矢量图像支持)
有人知道如何实现这一点吗?由于资产目录作为单个文件存储在捆绑包中,因此无法获取单个资产的URL 最简单的解决方案是不对将在web视图中显示的图像使用资源目录
如果必须将映像保留在资产目录中,则您唯一的选择是将所需的资产“解包”到应用程序包的文档目录中的不同文件中,然后引用这些文件。有一种方法可以从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
@接口AppDelegate:UIResponder
@结束
@实现AppDelegate
-(BOOL)应用程序:(UIApplication*)应用程序使用选项完成启动:(NSDictionary*)启动选项{
[NSURLProtocol注册表类:[ImageProtocol类]];
//…其他代码
返回YES;
}
@结束
@接口映像协议:NSURLProtocol
@结束
@图像协议的实现
+(BOOL)canInitWithRequest:(NSURLRequest*)request{
NSString*imgName=(NSString*)[[request.URL.absoluteString组件由字符串分离:@/“]lastObject];
AppDelegate*AppDelegate=(AppDelegate*)[[UIApplication sharedApplication]委托];
NSLog(@“imgName=%@”,imgName);
如果([UIImage ImageName:imgName]!=nil){//或检查显式名称“target_image.png”
返回YES;
}
返回否;
}
+(NSURLRequest*)规范请求请求请求:(NSURLRequest*)请求{
返回请求;
}
+(BOOL)requestIsCacheEquivalent:(NSURLRequest*)a到request:(NSURLRequest*)b{
return[超级请求缓存等价物:a到请求:b];
}
-(空)惊人的{
NSString*imgName=(NSString*)[[self.request.URL.absoluteString组件由字符串分离:@/“]lastObject];
UIImage*img=[UIImage ImageName:imgName];
NSString*mimeType=@“图像/png”;
@试一试{
NSData*图像数据=零;
如果([imgName hasSuffix:@.png”]){
imageData=UIImagePngResentation(img);
}else if([imgName hasSuffix:@.jpg]”){
imageData=UIImageJPEG表示法(img,1);
mimeType=@“图像/jpg”;
}
NSString*编码=@“utf-8”;
NSURLResponse*response=[[NSURLResponse alloc]initWithURL:self.request.URL
MIMEType:MIMEType
expectedContentLength:imageData.length
text编码名称:编码];
[self.client URLProtocol:self-didReceiverResponse:response-cacheStoragePolicy:NSURLCacheStorageAllowed];
[self.client-URLProtocol:self-didLoadData:imageData];
[self.client URLProtocoldFinishLoading:self];
}@catch(NSException*exception){
NSError*err=[NSError errorWithDomain:nsurErrorDomain代码:nsurErrorSourceUnavailable用户信息:nil];
[self.client URLProtocol:self-didFailWithError:err];
NSLog(@“%@”,exception.debugDescription);
}
}
-(无效)停止加载{
//无所事事
}
-(void)连接:(NSURLConnection*)连接DidReceiverResponse:(NSURResponse*)响应{
[self.client URLProtocol:self-didReceiverResponse:response-cacheStoragePolicy:NSURLCacheStorageNotAllowed];
}
-(void)连接:(NSURLConnection*)连接didReceiveData:(NSData*)数据{
[self.client-URLProtocol:self-didLoadData:data];
}
-(无效)连接IDFinishLoading:(NSURLConnection*)连接{
[self.client URLProtocoldFinishLoading:self];
}
-(无效)连接:(NSURLConnection*)连接失败错误:(NSError*)错误{
[self.client-URLProtocol:self-didFailWithError:error];
}
@结束
一种方法是将图像转换为base64
并将其输入HTML
if let base64 = UIImage(named: "myImage")?.pngData()?.base64EncodedString() {
webView.loadHTMLString("<img src='data:application/png;base64,(base64)'/>", baseURL: nil)
}
如果让base64=UIImage(名为:“myImage”)?.pngData()?.base64EncodedString(){
webView.loadHTMLString(“,baseURL:nil)
}
实现您自己的NSURLProtocol
并从那里返回资产目录中相应的UIImage,我知道了。这真是个有趣的主意!我从来没有想到过。然而,明显的缺点是,它影响了整个NSURLRequest应用程序,并且对我的应用程序和可能的大多数应用程序都不太实用:(话虽如此,感谢一个新的视角!对我来说,这在-停止加载和-[ImageProtocol task]时崩溃了):无法识别的选择器已发送到实例0x7ad68ab0
,但只需对该行进行注释即可修复。对于我的用例来说,这是一个很好的解决方案。谢谢!@Gereon您说得对。在我的原始代码中,我使用NSURLSERSESSION加载了请求,因此我使用了task。修复了该问题的答案。感谢您提供了一个答案。请编辑您的答案,以将其包括在内对你的代码的解释?这将帮助未来的读者更好地理解正在发生的事情,特别是那些对该语言不熟悉并努力理解概念的社区成员。我在asset中有一个图像,我想将其转换为“src=\”\“宽度=”200\“高度=”200\”>。我该怎么做呢