UIWebView 내에서 HTML 및 로컬 이미지 사용


164

내 앱에 다른 URL로 연결되는 이미지를 표시하는 데 사용하려는 UIWebView가 있습니다.

나는 사용하고있다

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

문제는 이미지가 내 프로젝트에서 리소스로 추가되어 번들에 복사 되어도 이미지가로드되지 않는다는 것입니다 (즉, 찾을 수 없음).

NSBundle을 사용하여 이미지의 전체 경로를 가져 와서 사용해 보았지만 여전히 웹보기에 표시되지 않습니다.

어떤 아이디어?


더 이상 iPhone OS 3.0에서이 작업을 수행 할 수 없습니다. :( 추가 정보 (StackOverflow.com).
Joe D' Andrea

8
왜 다운 투표? : /
Jasarien

5
반드시 그들이 악한 것은 아닙니다. 그들은 합당한 이유가 있었을까요? 우리는 아마 알지 못할 것입니다. 그들이 왜 그들이 의견에 투표를했는지 설명하는 예의를 가지고 있다면 ...
Jasarien

63
투표에 대한 의견을 작성해야합니다.
Robert

@Jasarien : 동일한 기능이 필요합니다. 그러나 [webView loadHTMLString : htmlString baseURL : baseURL]의 htmlString에 전달되어야하는 내용과 <img src = "image.jpg"/> 내 이미지를 html에 넣는 방법을 이해할 수 없습니다.
아이폰

답변:


291

상대 경로 또는 파일 사용 : 이미지를 참조하는 경로는 UIWebView에서 작동하지 않습니다. 대신 올바른 baseURL을 사용하여 HTML을보기에로드해야합니다.

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

그런 다음 이미지를 다음과 같이 참조 할 수 있습니다.

<img src="myimage.png">

( uiwebview에서 다시 방문 )


15
[[NSBundle mainBundle] bundleURL] 우리는 이것을 bundleURL로 사용할 수 있습니다
Naveen Shan

2
이 모든 것은 웹뷰에서 htmlString에 대해 정의한 문자열을 제공하는 것입니다. 즉, 페이지에 표시되는 모든 것은 "tour.html"
The Chorkie

참고로, 이미지가 아닌 자바 스크립트 파일을로드하려는 경우 다음 사항도
고려해야

Xamarin 및 MonoTouch의 경우 webvie.LoadHtmlString (strig, NSBundle.MainBundle.BundleUrl);
Erik Simonic

1
작업 완벽한 시뮬레이터,하지만 내 장치
jose920405

46

이것을 사용하십시오 :

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

5
그러나 귀하의 답변은 3 년 전에 게시 된 답변과 동일합니다 ... 귀하의 답변은 전혀 다릅니다. 수락 된 답변이 이미 게시 한 내용을 포함했기 때문에 게시 할 필요가 없습니다.
Jasarien

13
허용 된 답변의 편리한 한 줄 버전입니다. 여기서 해를 입히지 않아도됩니다.
MusiGenesis

9
Adam Alexander가 대답 한 @Jasarien은 2009 년 8 월까지 유일한 솔루션이었습니다. 그러나 Max OS X 버전 10.6부터이 새로운 속성 bundleURL이 NSBundle에 추가되었습니다. bundlePath를 사용하고 URL로 변환 할 필요가 없습니다. 따라서 10.6보다 높은 버전을 사용하는 사람들에게는 이것이 더 나은 솔루션을 제공합니다.
rineez

최근에이 게시물에서 많은 -ve 활동을보고 있습니다.
Lithu TV

24

나는이 문제에 부딪쳤다. 제 경우에는 현지화되지 않은 일부 이미지와 여러 언어로 된 일부 이미지를 다루었습니다. 기본 URL이 현지화 된 폴더 안에 이미지를 가져 오지 못했습니다. 나는 다음을 수행하여 이것을 해결했다.

// 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];

그런 다음 내용을로드 할 때 UIWebView HTML 코드에서 imgHTMLTag를 사용하십시오.

나는 이것이 같은 문제에 부딪힌 사람에게 도움이되기를 바랍니다.


1
file://내가 필요한 것이 사용 되었습니다.
So Over It

니스, 정확히 내가 필요한 것
Rubberduck

8

base64 이미지 문자열을 사용해보십시오.

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

NSString *strEncoded = [data base64Encoding];   

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

6

나는 비슷한 문제가 있었지만 모든 제안이 도움이되지 못했습니다.

그러나 문제는 * .png 자체였습니다. 알파 채널이 없었습니다 . 어떻게 든 Xcode는 배포 프로세스 중에 알파 채널이없는 모든 png 파일을 무시합니다 .


당신이 이것에서 벗어나기 위해 무엇을 했습니까? 해결책을 찾았습니까? 나는 같은 문제에 직면하고있다. 알파 채널이 없었기 때문에 UIWebView가 이미지를 표시하지 않습니다.
spaleja

1
Gimp를 사용하여 png 파일에 알파 채널을 추가했습니다. docs.gimp.org/en/gimp-layer-alpha-add.html

3

"MyProj"에 파일 추가 를 선택 하고 폴더 참조 생성을 선택하여 폴더 (예 : 하위 폴더 css, img 및 js 및 파일 test.html이있는 WEB)를 프로젝트에 추가 할 수 있습니다 . 이제 다음 코드는 참조 된 모든 이미지, CSS 및 자바 스크립트를 처리합니다.

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

3

스위프트 3에서 :

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

이미지가 수정없이 폴더 안에있는 경우에도 효과가있었습니다.


2

iOS 6 Programming Cookbok에서 두 장을 읽고 objective-c 및 iOS 프로그래밍을 배우기 시작한 후 사용자 정의 번들 에서 리소스를로드 하고 웹보기에서 사용 하려는 경우 추가하고 싶습니다. 다음과 같이 수행 할 수 있습니다.

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

그런 다음 html에서 "custom"번들을 기본 경로로 사용하여 리소스를 참조 할 수 있습니다.

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

1

Lithu TV의 답변의 신속한 버전 :

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

1

Adam Alexanders Objective C 답변의 신속한 버전 :

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

0

이미지에 대한 상대 링크를 사용하는 경우 iOS 앱이 컴파일 된 후 모든 폴더 구조가 유지되지 않으므로 이미지가 표시되지 않습니다. ' .bundle '파일 이름 확장자를 추가 하여 로컬 웹 폴더번들 로 변환하는 것이 가능 합니다.

따라서 로컬 웹 사이트가 " www " 폴더에 포함 된 경우 이름이 " www.bundle "로 바뀌어야 합니다. 이미지 폴더와 디렉토리 구조를 보존 할 수 있습니다. 그런 다음 ' index.html '파일을 ' baseURL '(www.bundle 경로로 설정)을 사용 하여 HTML 문자열로 WebView에 로드하여 상대 이미지 링크를로드 할 수있게하십시오.

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

이 답변은 특히 파일 : \ \ xxxxxxx.xxx 파일에 도움이되었지만 이미지를 표시하려면 해결 방법을 수행해야했습니다.

제 경우에는 서버에 문서 파일로 다운로드 할 HTML 파일이 있습니다. UIWebView에서 로컬 그래픽으로 표시하여 작업 할 수 없었습니다. 내가 한 일은 다음과 같습니다.

  1. NSBundle에서 로컬 문서 디렉토리로 파일을 복사하십시오.
  2. HTML 문서에서 파일을 "file : \\ filename.png"로 참조하십시오.

따라서 시작시 파일을 문서 디렉토리에 복사하십시오.

-(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

RSS 피드에 대한 내 복잡한 솔루션 (또는 자습서)은 장치에서만 작동합니다.

#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]);
                               }
                           }];

- (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
}

}

View 컨트롤러에서

- (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];

}

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

이미지가있는 모든 HTML의 일부

<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>

이름 htc-one-tab-7-concept-1 (1) .jpg에 저장된 이미지

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.