アプリにUIWebViewがあり、別のURLにリンクする画像を表示するために使用します。
私は使っています
<img src="image.jpg" /> to load the image.
問題は、プロジェクトにリソースとして追加され、バンドルにコピーされているにもかかわらず、イメージが読み込まれない(つまり、見つからない)ことです。
NSBundleを使用して画像の完全なパスを取得しようとしましたが、それを使用してもWebビューに表示されません。
何か案は?
アプリにUIWebViewがあり、別のURLにリンクする画像を表示するために使用します。
私は使っています
<img src="image.jpg" /> to load the image.
問題は、プロジェクトにリソースとして追加され、バンドルにコピーされているにもかかわらず、イメージが読み込まれない(つまり、見つからない)ことです。
NSBundleを使用して画像の完全なパスを取得しようとしましたが、それを使用してもWebビューに表示されません。
何か案は?
回答:
相対パスまたはファイルの使用:画像を参照するパスは、UIWebViewでは機能しません。代わりに、正しいbaseURLを使用してHTMLをビューにロードする必要があります。
NSString *path = [[NSBundle mainBundle] bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
[webView loadHTMLString:htmlString baseURL:baseURL];
その後、次のように画像を参照できます。
<img src="myimage.png">
これを使って:
[webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];
bundleURL
がNSBundleに追加されました。bundlePathを取得してURLに変換する必要はありません。したがって、10.6以降のバージョンで作業している人にとっては、これはより良いソリューションを提供します。
私もこの問題に遭遇しました。私の場合、ローカライズされていない画像と複数の言語の画像を扱っていました。ベース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を使用します。
これが同じ問題に遭遇したすべての人に役立つことを願っています。
file://
が必要だった。
同様の問題がありましたが、すべての提案は役に立ちませんでした。
ただし、問題は* .png自体でした。アルファチャンネルはありませんでした。どういうわけか、Xcodeはデプロイプロセス中にアルファチャネルのないすべてのpngファイルを無視します。
[MyProj にファイルを追加]を選択し、[フォルダー参照の作成]を選択することにより、フォルダー(css、img、jsとファイルtest.htmlを含むWEBなど)をプロジェクトに追加できます。次のコードは、参照されるすべての画像、CSS、JavaScriptを処理します
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"WEB/test.html" ofType:nil];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];
iOS 6プログラミングクックボックのいくつかの章を読み、objective-cとiOSプログラミングの学習を開始した後、カスタムバンドルからリソースをロードし、それをWebビューで使用する場合に追加したいと思います。 、それはこのように達成することができます:
NSString *resourcesBundlePath = [[NSBundle mainBundle] pathForResource:@"Resources" ofType:@"bundle"];
NSBundle *resourcesBundle = [NSBundle bundleWithPath:resourcesBundlePath];
[self.outletWebView loadHTMLString:[html description] baseURL:[resourcesBundle bundleURL]];
次に、htmlで、「カスタム」バンドルをベースパスとして使用してリソースを参照できます。
body {
background-image:url('img/myBg.png');
}
画像への相対リンクを使用する場合、iOSアプリのコンパイル後にすべてのフォルダー構造が保持されないため、画像は表示されません。あなたができることは、 ' .bundle 'ファイル名拡張子を追加することにより、ローカルのWeb フォルダをバンドルに変換することです。
したがって、ローカルWebサイトがフォルダー「www」に含まれている場合、これを「www.bundle」に名前変更する必要があります。これにより、画像フォルダとディレクトリ構造を保持できます。次に、 ' baseURL '(www.bundleパスに設定)を含むHTML文字列として' index.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];
}
これらの答えは私に役立ちました-具体的にはファイル:\\ xxxxxxx.xxxですが、画像を表示するには回避策を実行する必要がありました。
私の場合、サーバーにHTMLファイルがあり、ドキュメントディレクトリにダウンロードします。動作させることができなかったUIWebViewのローカルグラフィックで表示したいです。これが私がしたことです:
したがって、起動時にファイルをドキュメントディレクトリにコピーします。
-(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);
}
rss-feedの複雑なソリューション(またはチュートリアル)(RSSItemsで取得)はデバイスでのみ機能します。
#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
}
}
ビューコントローラー上
- (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に保存された画像