私のSwift iOSアプリでは、リモートサーバーからいくつかの動的なHTMLページをダウンロードし、ドキュメントディレクトリに保存し、ドキュメントディレクトリからそれらのページを表示します。
私はこれを使用してページをロードしていました:
var appWebView:WKWebView?
...
appWebView!.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: htmlPath)))
すべてがシミュレーターで機能しますが、実際の電話に移動すると、空白のページが表示されました。次に、Safariを使用してアプリに接続しましたが、「リソースの読み込みに失敗しました」という苦情が見つかりました。
次に、最初にhtmlPath
のページのコンテンツを読み取ってから、
appWebView!.loadHTMLString()
ページをロードします。 HTMLページが単純な場合に機能します。ただし、HTMLが他の何かを参照する場合、つまり、ドキュメントディレクトリ内のJavaScriptファイル(<script src="file:////var/mobile/Containers/Data/Application/762035C9-2BF2-4CDD-B5B1-574A0E2B0728/Documents/xxxxx.js">
)、ロードに失敗します。
なぜこれが起こるのか、問題を解決する方法を知っていますか?
詳細:
これは、私のプロジェクト(iOS 10、Swift 3))でローカルファイルをロードするために使用したものの簡易バージョンです。コメントでRaghuramとFox5150が要求したとおり、iOS 10.3.1およびiPhone 7以降で再度テストした後、コード(7.5.2017).
完全に新しいプロジェクトを作成しましたが、これはフォルダー構造です:
2018年4月19日更新:HTML、CSS、JSファイルを含む.Zipをダウンロードし、/ Documents /(Alamofire + Zip )そしてそれらのファイルをwebViewにロードします。 GitHubサンプルプロジェクト にもあります。繰り返しますが、フォークとスターをお気軽に! :)
アップデート08.02.2018:最後に GitHubサンプルプロジェクト を追加しました。これにはローカルJavaScriptファイルも含まれています。分岐とスターをお気軽に! :)
ViewController.Swift
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView()
let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
let htmlUrl = URL(fileURLWithPath: htmlPath!, isDirectory: false)
webView.loadFileURL(htmlUrl, allowingReadAccessTo: htmlUrl)
webView.navigationDelegate = self
view = webView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
ViewController.Swift
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView()
let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
let folderPath = Bundle.main.bundlePath
let baseUrl = URL(fileURLWithPath: folderPath, isDirectory: true)
do {
let htmlString = try NSString(contentsOfFile: htmlPath!, encoding: String.Encoding.utf8.rawValue)
webView.loadHTMLString(htmlString as String, baseURL: baseUrl)
} catch {
// catch error
}
webView.navigationDelegate = self
view = webView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
気をつけるべきゴチャ:
css/styles.css
iOSはファイル構造をフラット化し、styles.cssはindex.htmlと同じレベルになるため、<link rel="stylesheet" type="text/css" href="styles.css">
代わりに2つのバージョンとここでの落とし穴は、プロジェクトからの私のhtml/cssファイルです:
web/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Offline WebKit</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h1 id="webkit-h1">Offline WebKit!</h1>
</body>
</html>
web/css/styles.css
#webkit-h1 {
font-size: 80px;
color: lightblue;
}
誰かがGitHubサンプルプロジェクトを希望する場合は、コメントセクションで教えてください。アップロードします。
このメソッドにより、WKWebViewは、リンクされたCSS/JSファイルのディレクトリおよびサブディレクトリの階層を適切に読み取ることができます。 HTML、CSS、またはJSコードを変更する必要があります[〜#〜] not [〜#〜].
Xcode 9.3用に更新されました
ローカルWebファイルのフォルダーをプロジェクトの任意の場所にインポートします。次のことを確認してください。
needed️必要に応じてアイテムをコピーする
☑️フォルダー参照の作成(「グループの作成」ではない)
targets️ターゲットに追加
WKWebViewを使用してView Controllerに移動し、次のコードをviewDidLoad
メソッドに追加します。
let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
index
–ロードするファイルの名前(.html
拡張子なし)website
– Webフォルダの名前(index.html
はこのディレクトリのルートにある必要があります)全体的なコードは次のようになります。
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.uiDelegate = self
webView.navigationDelegate = self
let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "Website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
}
}
このメソッドまたはコードについてさらに質問がある場合は、できる限りお答えします。 :)
このソリューションは私を助けました:
[configuration.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
これはうまく機能します(Swift 3、Xcode 8):
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
if let url = Bundle.main.url(forResource: "file", withExtension: "txt")
{
do
{
let contents = try String(contentsOfFile: url.path)
webView.loadHTMLString(contents, baseURL: url.deletingLastPathComponent())
}
catch
{
print("Could not load the HTML string.")
}
}
}
}
これは、ファイルURLまたはリモートURL、およびファイルがバンドル内にあるかドキュメント内にあるかでうまく機能します。
if url.isFileURL {
webView.loadFileURL(url, allowingReadAccessTo: url)
} else {
let request = URLRequest(url: url)
webView.load(request)
}