2014-11-14 7 views
11

Mamy lokalny html do wyświetlenia w UIWebView. I tam chcemy wyświetlać obrazy zdefiniowane w Katalogu zasobów.Jak uzyskać dostęp do zasobu obrazu w katalogu zasobów z UIWebView (lub WKWebView)

Wiem, że możemy zrobić coś podobnego, jeśli obraz jest płaski w głównym pakiecie. Fragment kodu wyglądałby tak.

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

Jednak nie jestem pewien, co można określić dla „target_image.png” Jeśli plik PNG jest pakowany w katalogu aktywów. (Ponadto chcemy określić pdf, aby skorzystać z obsługi obrazów wektorowych w Xcode 6)

Czy ktoś ma pojęcie, jak to osiągnąć?

Odpowiedz

14

Ponieważ katalog zasobów jest przechowywany w pakiecie jako pojedynczy plik, nie można uzyskać adresu URL do pojedynczego zasobu.

Najprostszym rozwiązaniem jest NIE używać katalogu zasobów do zdjęć wyświetlanych w widoku internetowym.

Jeśli przechowywanie obrazów w katalogu zasobów jest niezbędne, jedyną opcją jest "rozpakowanie" wymaganych zasobów w odrębne pliki do katalogu dokumentów pakietu aplikacji, a następnie odniesienie do tych plików.

2

Istnieje sposób na dostęp do zasobu obrazu w katalogu zasobów z interfejsu UIWebView. Należy utworzyć podklasę NSUrlProtocol, zarejestrować nowy protokół i ręcznie odpowiedzieć na żądanie obrazów 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 
+0

Wdrażaj własne 'NSURLProtocol' i wracaj do odpowiedniego katalogu UII w katalogu zasobów, widzę. To bardzo ciekawy pomysł! Nigdy nie przyszedłem do mnie. Jednak oczywistą wadą jest to, że wpływa ona na aplikację NSURLRequest szeroką i niezbyt praktyczną dla mojej aplikacji i prawdopodobnie większości aplikacji :( Powiedziawszy to, dziękuję za nową perspektywę! – barley

+0

Dla mnie to zawiesza się w '-stopLoading' z '- [ImageProtocol task]: nierozpoznany selektor wysłany do instancji 0x7ad68ab0', ale po prostu komentowanie linii naprawia to świetne rozwiązanie dla mojego przypadku użycia.Dzięki! – Gereon

+1

@Gereon Masz rację.W moim oryginalnym kodzie załadowałem żądania z NSURLSession więc użyłem do tego zadania. Naprawiono odpowiedź. – Alexander

Powiązane problemy