Utilizzo di HTML e immagini locali in UIWebView


164

Ho un UIWebView nella mia app che voglio usare per visualizzare un'immagine che si collegherà a un altro URL.

sto usando

<img src="image.jpg" /> to load the image.

Il problema è che l'immagine non viene caricata (cioè non può essere trovata) anche se viene aggiunta come risorsa nel mio progetto e viene copiata nel pacchetto.

Ho provato a utilizzare NSBundle per ottenere il percorso completo dell'immagine e utilizzarlo e ancora non viene visualizzato nella vista Web.

Qualche idea?


Non sono più in grado di farlo da iPhone OS 3.0. :( Ulteriori informazioni (StackOverflow.com).
Joe D'Andrea,

8
Perché il voto negativo? : /
Jasarien

5
Non è necessariamente che siano cattivi. Forse avevano una ragione legittima? Probabilmente non lo sapremo mai. Se solo avessero la cortesia di spiegare perché hanno votato verso il basso in un commento ...
Jasarien

63
Dovrebbe essere obbligatorio scrivere un commento su un voto in giù.
Robert

@Jasarien: ho bisogno della stessa funzionalità. ma non riesco a capire cosa dovrebbe essere passato in htmlString in [webView loadHTMLString: htmlString baseURL: baseURL] e come metto <img src = "image.jpg" /> la mia immagine in html.
iPhone

Risposte:


291

Utilizzo di percorsi o file relativi: i percorsi per fare riferimento alle immagini non funzionano con UIWebView. Invece devi caricare l'HTML nella vista con l'URL baseUR corretto:

NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];

È quindi possibile fare riferimento alle immagini in questo modo:

<img src="myimage.png">

(da uiwebview rivisitato )


15
[[NSBundle mainBundle] bundleURL] possiamo usarlo come bundleURL
Naveen Shan

2
Tutto ciò che fa per me è darmi una stringa nella mia visualizzazione Web che ho definito per il mio htmlString. cioè tutto ciò che mostra nella pagina è "tour.html"
Chewie The Chorkie

Come sidenote, se si sta cercando di caricare i file JavaScript in contrasto con le immagini, è necessario guardare a questo così: stackoverflow.com/a/3629479/385619
Willster

nel caso di Xamarin e MonoTouch webvie.LoadHtmlString (strig, NSBundle.MainBundle.BundleUrl);
Erik Simonic,

1
Funziona perfettamente nel simulatore, ma non nel mio dispositivo
jose920405,

46

Usa questo:

[webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];

5
Ma la tua risposta è identica alla risposta pubblicata 3 anni fa ... La tua risposta non offre nulla di diverso, non è necessario che sia stata pubblicata perché la risposta accettata copriva già ciò che hai pubblicato.
Jasarien,

13
È una comoda versione di una riga della risposta accettata - nessun danno fatto avendo qui.
MusiGenesis,

9
@Jasarien quella risposta di Adam Alexander è stata l'unica soluzione fino ad agosto 2009. Ma dalla versione 10.6 di Max OS X questa nuova proprietà è bundleURLstata aggiunta in NSBundle. Non è necessario prendere bundlePath e convertirlo in URL. Quindi per le persone che lavorano in versioni successive alla 10.6 questo offre una soluzione migliore.
rineez,

vedere molte attività di recente in questo post di recente ... E nessuno ha notato perché?
Lithu TV,

24

Ho appena incontrato anche questo problema. Nel mio caso, avevo a che fare con alcune immagini che non erano localizzate e altre che erano - in più lingue. Un URL di base non ha ottenuto le immagini all'interno di cartelle localizzate per me. Ho risolto questo facendo quanto segue:

// make sure you have the image name and extension (for demo purposes, I'm using "myImage" and "png" for the file "myImage.png", which may or may not be localized)
NSString *imageFileName = @"myImage";
NSString *imageFileExtension = @"png";

// load the path of the image in the main bundle (this gets the full local path to the image you need, including if it is localized and if you have a @2x version)
NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageFileName ofType:imageFileExtension];

// generate the html tag for the image (don't forget to use file:// for local paths)
NSString *imgHTMLTag = [NSString stringWithFormat:@"<img src=\"file://%@\" />", imagePath];

Quindi, usa imgHTMLTag nel tuo codice HTML UIWebView quando carichi i contenuti.

Spero che questo aiuti chiunque abbia riscontrato lo stesso problema.


1
L'utilizzo file://era quello di cui avevo bisogno.
So Over It,

Bello, esattamente quello di cui avevo bisogno
Rubberduck,

8

prova a utilizzare la stringa di immagini base64.

NSData* data = UIImageJPEGRepresentation(image, 1.0f);

NSString *strEncoded = [data base64Encoding];   

<img src='data:image/png;base64,%@ '/>,strEncoded

6

Ho avuto un problema simile, ma tutti i suggerimenti non sono stati d'aiuto.

Tuttavia, il problema era il * .png stesso. Non aveva un canale alfa . In qualche modo Xcode ignora tutti i file png senza canale alfa durante il processo di distribuzione.


Cosa hai fatto per uscirne? Hai trovato una soluzione? Sto affrontando lo stesso problema. UIWebView non mostra immagini in quanto non aveva alcun canale alfa.
spaleja,

1
Ho usato Gimp per aggiungere un canale alfa ai miei file png. Vedi docs.gimp.org/en/gimp-layer-alpha-add.html

3

Puoi aggiungere una cartella (ad esempio WEB con sottocartelle css, img e js e file test.html) al tuo progetto selezionando Aggiungi file a "MyProj" e selezionando Crea riferimenti a cartelle . Ora il seguente codice si occuperà di tutte le immagini, i CSS e i JavaScript indicati

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WEB/test.html" ofType:nil];
[webView  loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];

3

In Swift 3:

webView.loadHTMLString("<img src=\"myImg.jpg\">", baseURL: Bundle.main.bundleURL)

Questo ha funzionato per me anche quando l'immagine era all'interno di una cartella senza alcuna modifica.


2

Dopo aver letto un paio di capitoli in Cookbok Programmazione iOS 6 e iniziato a imparare la programmazione obiett-c e iOS, vorrei solo aggiungere che se si caricheranno risorse da un bundle personalizzato e lo useranno in una visualizzazione Web , può essere realizzato in questo modo:

NSString *resourcesBundlePath = [[NSBundle mainBundle] pathForResource:@"Resources" ofType:@"bundle"];
NSBundle *resourcesBundle = [NSBundle bundleWithPath:resourcesBundlePath];
[self.outletWebView loadHTMLString:[html description] baseURL:[resourcesBundle bundleURL]];

Quindi, nel tuo html puoi fare riferimento a una risorsa usando il bundle "personalizzato" come percorso di base:

body {
    background-image:url('img/myBg.png');
}

1

Versione rapida della risposta di Lithu TV:

webView.loadHTMLString(htmlString, baseURL: NSBundle.mainBundle().bundleURL)

1

Versione rapida di Adam Alexanders Obiettivo C risposta:

let logoImageURL = NSURL(fileURLWithPath: "\(Bundle.main.bundlePath)/PDF_HeaderImage.png")

0

Se si utilizzano collegamenti relativi alle immagini, le immagini non verranno visualizzate poiché tutte le strutture di cartelle non vengono conservate dopo la compilazione dell'app iOS. Quello che puoi fare è convertire la tua cartella web locale in un bundle invece aggiungendo l' estensione del file ' .bundle '.

Quindi, se il tuo sito Web locale è contenuto in una cartella " www ", questo dovrebbe essere rinominato in " www.bundle ". Ciò consente di conservare le cartelle di immagini e la struttura delle directory. Quindi caricare il file ' index.html ' in WebView come stringa HTML con ' baseURL ' (impostato su www.bundle path) per abilitare il caricamento di collegamenti immagine relativi.

NSString *mainBundlePath = [[NSBundle mainBundle] resourcePath];
NSString *wwwBundlePath = [mainBundlePath stringByAppendingPathComponent:@"www.bundle"];
NSBundle *wwwBundle = [NSBundle bundleWithPath:wwwBundlePath];
if (wwwBundle != nil) {
    NSURL *baseURL = [NSURL fileURLWithPath:[wwwBundle bundlePath]];
    NSError *error = nil;
    NSString *page = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil];
    NSString *pageSource = [NSString stringWithContentsOfFile:page encoding:NSUTF8StringEncoding error:&error];
    [self.webView loadHTMLString:pageSource baseURL:baseURL];
}

0

Queste risposte mi hanno aiutato, in particolare il file: \\ xxxxxxx.xxx, ma ho dovuto fare una soluzione alternativa per visualizzare l'immagine.

Nel mio caso, ho un file HTML sul mio server che scarico nella directory dei documenti. Voglio che venga visualizzato con un grafico locale in un UIWebView che non sono riuscito a lavorare. Ecco cosa ho fatto:

  1. Copia il file da NSBundle nella directory dei documenti locali
  2. Fai riferimento al file nel mio documento HTML come "file: \\ nomefile.png"

Quindi all'avvio copia il file nella directory dei documenti:

-(BOOL)copyBundleFilesToDocumentsDirectoryForFileName:(NSString *)fileNameToCopy OverwriteExisting:(BOOL)overwrite {
        //GET DOCUMENTS DIR
        //Search for standard documents using NSSearchPathForDirectoriesInDomains
        //First Param = Searching the documents directory
        //Second Param = Searching the Users directory and not the System
        //Expand any tildes and identify home directories.
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDir = [paths objectAtIndex:0];

        //COPY FILE FROM NSBUNDLE File to Local Documents Dir
        NSString *writableFilePath = [documentsDir  stringByAppendingPathComponent:fileNameToCopy];

        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSError *fileError;

        DDLogVerbose(@"File Copy From Bundle to Documents Dir would go to this path: %@", writableFilePath);

        if ([fileManager fileExistsAtPath:writableFilePath]) {
            DDLogVerbose(@"File %@ already exists in Documents Dir", fileNameToCopy);

            if (overwrite) {
                [fileManager removeItemAtPath:writableFilePath error:nil];
                DDLogVerbose(@"OLD File %@ was Deleted from  Documents Dir Successfully", fileNameToCopy);
            } else {
                return (NO);
            }
        }

        NSArray *fileNameParts = [fileNameToCopy componentsSeparatedByString:@"."];
        NSString *bundlePath = [[NSBundle mainBundle]pathForResource:[fileNameParts objectAtIndex:0] ofType:[fileNameParts objectAtIndex:1]];
        BOOL success = [fileManager copyItemAtPath:bundlePath toPath:writableFilePath error:&fileError];

        if (success) {
            DDLogVerbose(@"Copied %@ from Bundle to Documents Dir Successfully", fileNameToCopy);
        } else {
            DDLogError(@"File %@ could NOT be copied from bundle to Documents Dir due to error %@!!", fileNameToCopy, fileError);
        }

    return (success);
}

-7

La mia soluzione complessa (o tutorial) per rss-feed (get in RSSItems) funziona solo sul dispositivo:

#define CACHE_DIR       [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]

for (RSSItem *item in _dataSource) {

    url = [NSURL URLWithString:[item link]];
    request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"GET"];

    [NSURLConnection sendAsynchronousRequest:request
                                       queue:queue
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

                               @autoreleasepool {

                                   if (!error) {

                                       NSString *html = [[NSString alloc] initWithData:data
                                                                              encoding:NSWindowsCP1251StringEncoding];

                                       {
                                           NSError *error = nil;

                                           HTMLParser *parser = [[HTMLParser alloc] initWithString:html error:&error];

                                           if (error) {
                                               NSLog(@"Error: %@", error);
                                               return;
                                           }

                                           HTMLNode *bodyNode = [parser body];

                                           NSArray *spanNodes = [bodyNode findChildTags:@"div"];

                                           for (HTMLNode *spanNode in spanNodes) {
                                               if ([[spanNode getAttributeNamed:@"class"] isEqualToString:@"page"]) {

                                                   NSString *absStr = [[response URL] absoluteString];
                                                   for (RSSItem *anItem in _dataSource)
                                                       if ([absStr isEqualToString:[anItem link]]){

                                                           NSArray *spanNodes = [bodyNode findChildTags:@"img"];
                                                           for (HTMLNode *spanNode in spanNodes){
                                                               NSString *imgUrl = [spanNode getAttributeNamed:@"src"];
                                                               if (imgUrl){
                                                                   [anItem setImage:imgUrl];
                                                                   break;
                                                               }
                                                           }

                                                           [anItem setHtml:[spanNode rawContents]];
                                                           [self subProcessRSSItem:anItem];
                                                       }
                                               }
                                           }

                                           [parser release];
                                       }

                                       if (error) {
                                           NSLog(@"Error: %@", error);
                                           return;
                                       }

                                       [[NSNotificationCenter defaultCenter] postNotificationName:notification_updateDatasource
                                                                                           object:self
                                                                                         userInfo:nil];

                                   }else
                                       NSLog(@"Error",[error userInfo]);
                               }
                           }];

e

- (void)subProcessRSSItem:(RSSItem*)item{

NSString *html = [item html];
if (html) {

    html = [html stringByReplacingOccurrencesOfString:@"<div class=\"clear\"></div>"
                                           withString:@""];

    html = [html stringByReplacingOccurrencesOfString:@"<p class=\"link\">"
                                           withString:@""];

    html = [html stringByReplacingOccurrencesOfString:@"<div class=\"page\">"
                                           withString:@""];

    html = [html stringByReplacingOccurrencesOfString:@"</div>"
                                           withString:@""];

    NSArray *array1 = [html componentsSeparatedByString:@"<a"];
    if ([array1 count]==2) {
        NSArray *array2 = [html componentsSeparatedByString:@"a>"];

        html = [[array1 objectAtIndex:0] stringByAppendingString:[array2 objectAtIndex:1]];
    }

    NSURL *url;
    NSString *fileName;
    NSString *filePath;
    BOOL success;
    if ([item image]) {

        url = [NSURL URLWithString:
                      [hostString stringByAppendingString:[item image]]];
        NSData *imageData = [NSData dataWithContentsOfURL:url];

        fileName = [[[url relativePath] componentsSeparatedByString:@"/"] lastObject];

        filePath = [NSString stringWithFormat:@"%@/%@",
                              CACHE_DIR,
                              fileName];

        //save image locally
        success = [[NSFileManager defaultManager] createFileAtPath:filePath
                                                               contents:imageData
                                                             attributes:nil];

        //replace links
        html = [html stringByReplacingOccurrencesOfString:[item image]
                                               withString:filePath];

        [item setImage:fileName];

        //Передадим обновление интерфейса, снабдив индексом обновляемой ячейки
        [[NSNotificationCenter defaultCenter] postNotificationName:notification_updateRow
                                                            object:self
                                                          userInfo:[NSDictionary dictionaryWithObject:@([_dataSource indexOfObject:item])
                                                                                               forKey:@"row"]];
    }

    //finalize html
    html = [NSString stringWithFormat:@"<html><body>%@</body></html>",html];

    fileName = [[[item link] componentsSeparatedByString:@"/"] lastObject];
    filePath = [NSString stringWithFormat:@"%@/%@",
                CACHE_DIR,
                fileName];
    success = [[NSFileManager defaultManager] createFileAtPath:filePath
                                                      contents:[html dataUsingEncoding:NSUTF8StringEncoding]
                                                    attributes:nil];

    [item setHtml:
     (success)?filePath:nil];//for direct download in other case
}

}

su Visualizza controller

- (void)viewDidAppear:(BOOL)animated{

RSSItem *item = [[DataSingleton sharedSingleton] selectedRSSItem];

NSString* htmlString = [NSString stringWithContentsOfFile:[item html]
                                                 encoding:NSUTF8StringEncoding error:nil];
NSURL *baseURL = [NSURL URLWithString:CACHE_DIR];

[_webView loadHTMLString:htmlString
                 baseURL:baseURL];

}

classe di articoli rss

#import <Foundation/Foundation.h>

@interface RSSItem : NSObject

@property(nonatomic,retain) NSString *title;
@property(nonatomic,retain) NSString *link;
@property(nonatomic,retain) NSString *guid;
@property(nonatomic,retain) NSString *category;
@property(nonatomic,retain) NSString *description;
@property(nonatomic,retain) NSString *pubDate;
@property(nonatomic,retain) NSString *html;
@property(nonatomic,retain) NSString *image;
@end

parte di qualsiasi html con immagine

<html><body>
<h2>blah-blahTC One Tab 7</h2>
<p>blah-blah НТС One.</p>
<p><img width="600" height="412" alt="" src="/Users/wins/Library/Application Support/iPhone Simulator/5.0/Applications/2EAD8889-6482-48D4-80A7-9CCFD567123B/Library/Caches/htc-one-tab-7-concept-1(1).jpg"><br><br>
blah-blah (Hasan Kaymak) blah-blah HTC One Tab 7, blah-blah HTC One. <br><br>
blah-blah
 microSD.<br><br>
blah-blah Wi-Fi to 4G LTE.</p>
</p>
</body></html>

immagine salvata per il nome htc-one-tab-7-concept-1 (1) .jpg

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.