2014-11-14 24 views
11

Wir haben einen lokalen HTML-Code in UIWebView. Und dort wollen wir Bilder zeigen, die in Asset Catalog definiert sind.Zugriff auf Bildressource im Asset-Katalog über UIWebView (oder WKWebView)

Ich weiß, dass wir ähnliche Dinge tun können, wenn wir das Bild flach im Hauptbündel hatten. Das Code-Snippet wäre so.

webView.loadHTMLString("<img src='target_image.png'/>", baseURL: NSBundle.mainBundle().bundleURL) 

Aber ich bin nicht sicher, was ich für „target_image.png“, wenn die PNG-Datei im Asset Katalog verpackt angeben. (Außerdem wollen wir pdf spezifizieren, um die Vektorbildunterstützung in Xcode 6 zu nutzen)

Hat jemand eine Idee, wie man das erreicht?

Antwort

14

Da der Asset-Katalog im Paket als einzelne Datei gespeichert ist, gibt es keine Möglichkeit, eine URL zu einem einzelnen Asset zu erhalten.

Die einfachste Lösung besteht darin, den Asset-Katalog NICHT für Bilder zu verwenden, die Sie in einer Web-Ansicht anzeigen.

Wenn Sie die Bilder im Asset-Katalog beibehalten möchten, besteht die einzige Option darin, das/die erforderliche (n) Asset (s) in verschiedene Dateien im Dokumentenverzeichnis des Anwendungspakets zu "entpacken" und dann auf diese Dateien zu verweisen.

2

Es gibt eine Möglichkeit, aus UIWebView auf die Bildressource im Asset-Katalog zuzugreifen. Sie sollten die Unterklasse NSUrlProtocol erstellen, Ihr neues Protokoll registrieren und manuell auf die Anforderung von WebView-Bildern reagieren.

@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 
+0

Implementieren Sie Ihr eigenes 'NSURLProtocol' und geben Sie entsprechende UIImage im Asset-Katalog von dort, sehe ich. Das ist eine sehr interessante Idee! Niemals zu mir gekommen. Der offensichtliche Nachteil ist jedoch, dass es NSURLRequest Anwendung betrifft, und nicht sehr praktisch für meine App und wahrscheinlich die meisten Apps :( Having said that, danke für eine neue Perspektive! – barley

+0

Für mich stürzt dies in '-stopLoading' mit '- [ImageProtocol Task]: unerkannter Selektor an Instanz 0x7ad68ab0' geschickt, aber einfach die Zeile kommentieren, behebt es. Tolle Lösung für meinen Anwendungsfall. Danke! – Gereon

+1

@Gereon Sie haben Recht.In meinem ursprünglichen Code habe ich Anfragen mit NSURLSession geladen Also habe ich die Aufgabe dafür verwendet. Die Antwort wurde korrigiert. – Alexander