私は以前これを尋ねましたが、もっと分かりやすいようにすべてを再構成する必要がありました。私のプロジェクトで ファイルマネージャで文書ディレクトリのサブフォルダが見つからない場合があります
が、私は次のコードで呼ばdocuments directory
HTML
内部のサブフォルダを作成しました:私は私のアプリの
Bundle
インサイド
Document directory is file:///var/mobile/Containers/Data/Application/103869C9-9D46-4595-A370-A93BCD75D495/Documents/HTML
:
fileprivate func createFolderOnDocumentsDirectoryIfNotExists() {
let folderName = "HTML"
let fileManager = FileManager.default
if let tDocumentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let filePath = tDocumentDirectory.appendingPathComponent("\(folderName)")
if !fileManager.fileExists(atPath: filePath.path) {
do {
try fileManager.createDirectory(atPath: filePath.path, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Couldn't create document directory")
}
}
print("Document directory is \(filePath)")
}
}
print文は、次の印刷します私がHTML
文字列で使用するファイルはWKWebView
に表示されます。
.css
ファイルがHTML baseURL
と同じフォルダにあることが必要であるとして、私は次のコードで上記の関数で作成したディレクトリにBundle
から.css
ファイル、そのコピー:
fileprivate func copyCSSFileToHTMLFolder() {
guard let cssURL = Bundle.main.url(forResource: "swiss", withExtension: "css") else { return }
let fileManager = FileManager.default
if let tDocumentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let fp = tDocumentDirectory.appendingPathComponent("HTML")
if fileManager.fileExists(atPath: fp.path) {
let fp2 = fp.appendingPathComponent(cssURL.lastPathComponent)
do {
try fileManager.copyItem(atPath: cssURL.path, toPath: fp2.path)
} catch {
print("\nFailed to copy css to HTML folder with error:", error)
}
}
}
}
は私が知っています私はBundle
の両方でHTML baseURL
をmain.Bundle
に設定して使うことができましたが、HTML
のローカル画像を表示する必要があり、Webリンクされた画像ではないため、それらをサブフォルダに移動して後でmain.Bundle
から、そのサブフォルダに必要な画像読み取り専用であり、書き込み可能ではありません(画像は保存できません)。
ViewController
はUINavigationController
にプッシュされています。その中にプッシュViewController
私はを提示するWKWebView
を持っています。
私もかつて、私は次の関数を使用してHTML
文字列に変換し、インスタンス化var markdownString: String? {}
プロパティがあります。
func getHTML(str: String) -> String {
/*
the cssImport here points to the previously copied css file as they are on the same folder
*/
let cssImport = "<head><link rel=\"stylesheet\" type=\"text/css\" href=\"swiss.css\"></head>"
let htmlString = try? Down(markdownString: str).toHTML()
return cssImport + htmlString!
}
マイWKWebView
は、次のコードで宣言されています:
private lazy var webView: WKWebView = {
// script to fit the content with the screen
var scriptContent = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let wkuscript = WKUserScript(source: scriptContent, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)
let wkucontroller = WKUserContentController()
wkucontroller.addUserScript(wkuscript)
let wkwebconfig = WKWebViewConfiguration()
wkwebconfig.userContentController = wkucontroller
let wv = WKWebView(frame: .zero, configuration: wkwebconfig)
wv.frame.size.height = 1
return wv
}()
たびに私をmarkdown String
が設定されている場合は、HTML
文字列に変換してからHTML baseURL
をインスタンス化し、フォローインでwebView
にロードしますgコード:
public var markdownString: String? {
didSet {
guard let kPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("HTML", isDirectory: true) else { return }
guard let str = markdownString else { return }
let html = getHTML(str: str)
print("base url:", kPath)
let fm = FileManager.default
do {
let items = try fm.contentsOfDirectory(atPath: kPath.path)
print("items:", items)
} catch {
print("Error:", error)
}
webView.loadHTMLString(html, baseURL: kPath)
}
}
ここで問題が発生します。
swiss.css
ファイルは次のディレクトリにあります。次のパスに
file:///var/mobile/Containers/Data/Application/103869C9-9D46-4595-A370-A93BCD75D495/Documents/HTML/
HTML baseURL
ポイント:
file:///var/mobile/Containers/Data/Application/103869C9-9D46-4595-A370-A93BCD75D495/Documents/HTML/
あなたが見ることができるように、彼らは両方とも同じパスを指しています。
は時々私のHTML
は、それがdo{}catch{}
ブロックでitems
を印刷して、swiss.css
ファイルを見つけたが、それは、フォルダを見つけることができません。他の回、try fm.contentsOfDirectory(atPath: kPath.path)
火災エラーは、次の印刷catch{}
ブロックにcatched:
Error: Error Domain=NSCocoaErrorDomain Code=260 "The folder “HTML” doesn’t exist." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/103869C9-9D46-4595-A370-A93BCD75D495/Documents/HTML, NSUserStringVariant=( Folder ), NSUnderlyingError=0x1c044e5e0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
これは、シミュレータと実際のデバイスで発生します。
この問題の原因は何ですか。どうして私はパスを強制していないのに、documents directory
のパスをリセットするかもしれない、アプリケーションを再起動しなくても時々、それは時々そしてそれ以外の時にフォルダを見つけるのですが、私はあなたが上記のようにそれをフェッチしています。
この現象はわかりません。
UPDATE
だから私は、私は私のmarkdown: String?
宣言を変更してhtml
文字列の読み取りが直接いくつかの問題を引き起こしている可能性がありますことを考えていました。
私は変換されたマークダウン文字列(HTML文字列ではありません)をindex.html
という同じパスのファイルに書き込みます。
このビューを初めてプッシュすると、今度はswiss.css
ファイルが見つかり、html
ファイルがそのファイルを検出して期待通りに使用するようになりました。ここまでは順調ですね。
しかし私は(バックボタンを押す)親ビューコントローラにpoping、このビューコントローラを閉じてから、再度それをプッシュしようとすると、(前述の)同じエラーが求められます。
Failed to write html to file with error: Error Domain=NSCocoaErrorDomain Code=4 "The folder “index.html” doesn’t exist." UserInfo={NSURL=file:///var/mobile/Containers/Data/Application/C0639153-6BA7-40E7-82CF-25BA4CB4A943/Documents/HTML/index.html, NSUserStringVariant=Folder, NSUnderlyingError=0x1c045d850 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
ここではいくつかのパスは以前のものとは異なっていますが、これは別の起動で変更されるためですが、パスを保存せず強制的に書き込むことがないため、ここでは問題はありません。 fetch、
更新されたmarkdown
宣言は次のようになります。
public var markdownString: String? {
didSet {
guard let kPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("HTML", isDirectory: true) else { return }
guard let str = markdownString else { return }
let html = getHTML(str: str)
do {
let writePath = kPath.appendingPathComponent("index.html")
try html.write(to: writePath, atomically: true, encoding: .utf8)
webView.loadFileURL(writePath, allowingReadAccessTo: kPath)
} catch {
print("Failed to write html to file with error:", error)
return
}
let fm = FileManager.default
do {
let items = try fm.contentsOfDirectory(atPath: kPath.path)
print("items:", items)
} catch {
print("Error:", error)
}
}
}
何とか私はさらに混乱しています。
なぜ最初のプレゼンテーションでは動作しますか?あなたのUPDATE]セクションで
この「css」にタグを付けた理由を聞いてもよろしいですか?どのくらい正確にCSSの専門家がこの質問にあなたを助けることができましたか? –
@AndreiGheorghiuあなたは正しいです。それは間違いだった。 –
固定 "guard let str = markdownString else {return}"これは疑わしいコードの唯一の部分です。 – Mozahler