이전 iOS 8 베타의 경우 로컬 웹 앱 (번들)을로드하면 UIWebView
및 WKWebView
에서 모두 잘 작동 하며 새로운WKWebView
API를 .
var url = NSURL(fileURLWithPath:NSBundle.mainBundle().pathForResource("car", ofType:"html"))
webView = WKWebView(frame:view.frame)
webView!.loadRequest(NSURLRequest(URL:url))
view.addSubview(webView)
하지만 베타 4에서는 빈 흰색 화면이 나타납니다 (UIWebView
아무것도로드되거나 실행되지 않는 것처럼 보이는 여전히 작동)이 나타납니다. 로그에 오류가 있습니다.
에 대한 샌드 박스 확장을 만들 수 없습니다. /
나를 올바른 방향으로 안내하는 데 도움이 필요하십니까? 감사!
답변
그들은 마침내 버그를 해결했습니다! 이제 -[WKWebView loadFileURL:allowingReadAccessToURL:]
. 분명히 수정은 WWDC 2015 비디오 504 에서 몇 초의 가치가있었습니다. Safari View Controller를 소개합니다.
iOS8 ~ iOS10 (Swift 3) 용
으로 댄 Fabulish의 응답 상태이 WKWebView의 버그가 분명히 빠른 시일 내에 해결되지 않는 그가 말했다 같은 해결 방법이 있습니다 :
여기에서 해결 방법을 보여주고 싶었 기 때문에 대답하고 있습니다. https://github.com/shazron/WKWebViewFIleUrlTest에 표시된 IMO 코드 는 대부분의 사람들이 관심이없는 관련없는 세부 정보로 가득 차 있습니다.
해결 방법은 20 줄의 코드, 오류 처리 및 주석이 포함되어 있으며 서버가 필요하지 않습니다. 🙂
func fileURLForBuggyWKWebView8(fileURL: URL) throws -> URL {
// Some safety checks
if !fileURL.isFileURL {
throw NSError(
domain: "BuggyWKWebViewDomain",
code: 1001,
userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("URL must be a file URL.", comment:"")])
}
try! fileURL.checkResourceIsReachable()
// Create "/temp/www" directory
let fm = FileManager.default
let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("www")
try! fm.createDirectory(at: tmpDirURL, withIntermediateDirectories: true, attributes: nil)
// Now copy given file to the temp directory
let dstURL = tmpDirURL.appendingPathComponent(fileURL.lastPathComponent)
let _ = try? fm.removeItem(at: dstURL)
try! fm.copyItem(at: fileURL, to: dstURL)
// Files in "/temp/www" load flawlesly :)
return dstURL
}
다음과 같이 사용할 수 있습니다.
override func viewDidLoad() {
super.viewDidLoad()
var fileURL = URL(fileURLWithPath: Bundle.main.path(forResource:"file", ofType: "pdf")!)
if #available(iOS 9.0, *) {
// iOS9 and above. One year later things are OK.
webView.loadFileURL(fileURL, allowingReadAccessTo: fileURL)
} else {
// iOS8. Things can (sometimes) be workaround-ed
// Brave people can do just this
// fileURL = try! pathForBuggyWKWebView8(fileURL: fileURL)
// webView.load(URLRequest(url: fileURL))
do {
fileURL = try fileURLForBuggyWKWebView8(fileURL: fileURL)
webView.load(URLRequest(url: fileURL))
} catch let error as NSError {
print("Error: " + error.debugDescription)
}
}
}
답변
WKWebView는 해당 loadRequest:
메서드 를 통해 file : URL에서 콘텐츠를로드 할 수 없습니다 . http://www.openradar.me/18039024
를 통해 콘텐츠를로드 할 수 loadHTMLString:
있지만 baseURL이 file : URL이면 여전히 작동하지 않습니다.
iOS 9에는 원하는 작업을 수행하는 새로운 API 인 [WKWebView loadFileURL:allowingReadAccessToURL:]
.
iOS 8에 대한 해결 방법이 있습니다. Shazron이 Objective-C의 https://github.com/shazron/WKWebViewFIleUrlTest 에서 파일/tmp/www
을 복사 하고 거기에서로드 하는 방법을 보여줍니다 .
Swift에서 작업하는 경우 대신 nachos4d의 샘플을 사용해 볼 수 있습니다. (또한 shazron의 샘플보다 훨씬 짧으므로 shazron의 코드에 문제가있는 경우 대신 시도해보세요.)
답변
iOS 9 에서 [WKWebView loadFileURL : allowingReadAccessToURL :]을 사용하는 방법의 예입니다 .
웹 폴더를 프로젝트로 이동할 때 “폴더 참조 생성”을 선택하십시오.
그런 다음 다음과 같은 코드를 사용하십시오 (Swift 2).
if let filePath = NSBundle.mainBundle().resourcePath?.stringByAppendingString("/WebApp/index.html"){
let url = NSURL(fileURLWithPath: filePath)
if let webAppPath = NSBundle.mainBundle().resourcePath?.stringByAppendingString("/WebApp") {
let webAppUrl = NSURL(fileURLWithPath: webAppPath, isDirectory: true)
webView.loadFileURL(url, allowingReadAccessToURL: webAppUrl)
}
}
html 파일에서 다음과 같은 파일 경로를 사용하십시오.
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
이건 아니야
<link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet">
xcode 프로젝트로 이동 된 디렉토리의 예입니다.
답변
임시 해결 방법 : GuidoMB 에서 제안한대로 GCDWebServer를 사용하고 있습니다.
먼저 번들로 제공되는 “www /”폴더 ( “index.html”포함)의 경로를 찾습니다.
NSString *docRoot = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"www"].stringByDeletingLastPathComponent;
… 다음과 같이 시작하십시오.
_webServer = [[GCDWebServer alloc] init];
[_webServer addGETHandlerForBasePath:@"/" directoryPath:docRoot indexFilename:@"index.html" cacheAge:3600 allowRangeRequests:YES];
[_webServer startWithPort:port bonjourName:nil];
중지하려면 :
[_webServer stop];
_webServer = nil;
iPad 2에서도 성능이 좋아 보입니다.
앱이 백그라운드로 들어간 후 충돌이 발생 했으므로 중지 applicationDidEnterBackground:
하고 applicationWillTerminate:
; 나는 / 시작에 다시 시작 application:didFinishLaunching...
하고 applicationWillEnterForeground:
.
답변
[configuration.preferences setValue:@"TRUE" forKey:@"allowFileAccessFromFileURLs"];
이것은 iOS 8.0+ dev.apple.com 의 문제를 해결했습니다.
또한 이것은 잘 작동하는 것 같습니다 …
NSString* FILE_PATH = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:@"htmlapp/FILE"];
[self.webView
loadFileURL: [NSURL fileURLWithPath:FILE_PATH]
allowingReadAccessToURL: [NSURL fileURLWithPath:FILE_PATH]
];
답변
Dan Fabulich가 언급 한 솔루션 외에도 XWebView 는 또 다른 해결 방법입니다. [WKWebView loadFileURL : allowingReadAccessToURL :] 은 확장을 통해 구현됩니다 .
답변
아직 댓글을 달 수 없으므로 별도의 답변으로 게시하고 있습니다.
이것은 nacho4d 솔루션 의 객관적인 C 버전입니다 . 지금까지 본 최고의 해결 방법입니다.
- (NSString *)pathForWKWebViewSandboxBugWithOriginalPath:(NSString *)filePath
{
NSFileManager *manager = [NSFileManager defaultManager];
NSString *tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"www"];
NSError *error = nil;
if (![manager createDirectoryAtPath:tempPath withIntermediateDirectories:YES attributes:nil error:&error]) {
NSLog(@"Could not create www directory. Error: %@", error);
return nil;
}
NSString *destPath = [tempPath stringByAppendingPathComponent:filePath.lastPathComponent];
if (![manager fileExistsAtPath:destPath]) {
if (![manager copyItemAtPath:filePath toPath:destPath error:&error]) {
NSLog(@"Couldn't copy file to /tmp/www. Error: %@", error);
return nil;
}
}
return destPath;
}