Swift4:.htmlファイルとbookmark

bookmarkとして読み込んだ.htmlファイルを書き込もうとしたのですが、うまくいきません。テキストで書き込まれてしまいます。

ない知恵を絞った結果、やりたいことは、

  • デフォルトのbookmarkを利用できるようにしたい
  • ユーザーが固有のbookmarkを使えるようにしたい
という2点に尽きるので、デフォルトのbookmarkはプログラム内に.htmlを定義して読み込むことにし、ユーザー固有のbookmarkは、従来通り、外部ファイルから読み込むことにしました。

.htmlファイルを読み込むとき、今までencodeを指定していなかったのですが、指定できるように変更しました。

プログラムに内包した.htmlファイルの読み込みは意外と簡単でした。

bookmarkの開閉処理でフォルダでbookmarkが泣き別れるとき、これをちゃんと開閉できないバグがあったので修正しました。

Calling sequence to read a user’s .html file.
var wA:String? = Com.CallReadHTMLfile(pFilepath,
pEncode: String.Encoding.utf8.rawValue)

 

func CallReadHTMLfile(_ pFilepath:String, pEncode:UInt) -> String? {//<*Read .html file*
var wString:String?           = nil                             //
    if CallFileExists(pFilepath) == “NG” {                      //This file exists?
       return nil                                               //♻️return♻️ Not exist.
    } else { }                                                  //
    do {                                                        //
        wString   = try String(contentsOf: URL(fileURLWithPath:pFilepath),
                    encoding:String.Encoding(rawValue: pEncode))//Read .html file
    } catch {                                                   //
    }                                                           //
    if wString == nil { return nil }                            //♻️return♻️ error
    else            { return String(describing: wString) }      //♻️return♻️ normal end
}//🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳

◾️How to read a .html file bundled in Swift program

func ExecGetBookmarks() -> String {                      //<*Read a default bookmark file*>
  let wFilepath:String? = Bundle.main.path(forResource: “MesaBookmarks, ofType: “html”)//
  if wFilepath == nil { return “” }                      //♻️return♻️ NA
  else { }                                               //
  let wBookmark:String = try! String(contentsOfFile: wFilepath!, encoding: String.Encoding.utf8)//
  return wBookmark                                       //
}//🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳🐳

Screenshot 2018-04-16 08.03.17

Swift4:Safariコンテンツブロック・メモ

httpからhttpsへのコンバートで副作用が起きました。

何が正しい結果なのかわかりませんが、少しイメージと違う結果になりました。

それにしても、手持ちのフィルタをSafariコンテンツブロックフィルタに移植したのですが、勘違いと錯誤による手間がとてもかかってしまいました。基本の欠如が原因です。

cookieがブロックされているかどうか、どうすればわかるのでしょう?とても気になります。

URLは産経新聞ニュース十段戦第3局 井山裕太十段が勝って3連覇、七冠を堅持「運がよかった」です。

Screenshot 2018-04-12 22.55.55

Screenshot 2018-04-13 04.58.51

Swift4:コンテンツブロックに関わるメモ

忘備録です。

  1. json改を使ったアプリ版で.jsonファイルを取り込めなくなっていたのは、Copy Bundle Resourcesに.jsonファイルを組み込んでいなかったことが原因でした。今回の件がなければ、使うのを諦め、気がつかないところでした。
    Screenshot 2018-04-10 00.19.26
  2. json改を使ったアプリ版では、.jsonファイルを使わず、フィルタをメモリ(プログラム)だけに定義することにしました。ファイルからだと時間がかかる(?)。フィルタはタブやスペースを使って、整理することができました。
    Screenshot 2018-04-10 00.34.38
  3. コンテンツブロックのOn/OffはpWebView.configuration.userContentController.removeAllContentRuleLists()で可能でした。ユーザーがOn/Offできれば、Safari版コンテンツブロックか、私版コンテンツブロックかは問われないため。
  4. 課題(1) Safari版コンテンツブロック(=json改アプリ版)では、どのフィルタがヒットしているかわからないので、コンテンツブロックの統計情報を取る機能を残すことにしました。

    (2) 広告はいいとして、cookieが正しくブロックされているかどうかわからないのが問題。一応、WKWebViewの出口のdecidePolicyFor navigationActionやdidReceiveServerRedirectForProvisionalNavigation navigationで見ていますが、よくわかりません。

Swift4:URLに関わるバグ収束中

Swiftのコンテンツブロックが動かなくなった件、結局、福山氏に問い合わせ、回答が得られ、無事解決となりました。

詳細は、iOS 11 WKWebViewで広告などのコンテンツブロックをするを参照してください。やりとりはブログの下側にあります。なお、その中に動くようになった時点のソースコードのリンクも入れてあります。

これに関して、ほかのサイトも調べたのですが、福山氏のブログ以上の内容は見あたりませんでした。

参考:Introduction to WebKit Content Blockers
参考:Creating Safari Content-Blocking Rules (Apple)

Swift4:URLに関わるバグ修正

かなり苦戦しました。

しかし、バグと不具合を修正できました。
不満な点は多いです。もちろん、完璧は今の実力では望めません。

.jsonベースが動かなくなったことをずっとあとから気づきがっくりしましたが。。。

問題点と対処:

  • コンテンツブロックが急に効かなくなった(Xcode9.3?)。
    →一旦、ファイルベース(.json)を無効にする。これは動くものと信じ込んでいたため、気づきが遅く、致命的だった!
    → macOSから転用したフィルタの構成を全面的に見直し、再構成/追加。
  • 読み込みURLとwebページのURLが異なるために起きる機能不全。
    → リダイレクトのようなものと理解し、管理テーブルで制御。
  • URLの更新・前後への制御が悪い(バグ)。
    → 単なるバグもあれば、全体の制御不良もあったので、URL読み込みのロジックを全面的に再レビュし、処理を一箇所にまとめた(あとでコードをアップ予定)。
  • 検索結果のリンクがduckduckgoとgoogleで異なるものがある。
    → googleなら問題がないが、duckduckgoだと機能不全を起こす。
    → 先の読み込みURLとwebページのURLが異なるために起きる機能不全を参照。
  • ツールバーのボタンがわかりにくい。
    → ツールバーの見直しによる簡素化/登録アプリを意識した修正。
参考
🍎🌝🌝🍎 🅿️URL= http://www.sankei.com/smp/<—-URLを指定
⭕️開始⭕️ 🅿️CurrentURL= http://www.sankei.com/smp/ 🅿️CompURL=
🔵終了🔵 🅿️CurrentURL= http://www.sankei.com/smp/ 🅿️CompURL= ⛔️読完 🅿️URLRow= 2
⛔️終了⛔️ 🅿️CurrentURL= http://www.sankei.com/smp/ 🅿️CompURL= ⛔️読完
*
⬅️⬅️➡️➡️ 🅿️CurrentURL= https://duckduckgo.com/?q=産経&t=ffab&ia=meanings 🅿️URL Row= 1<—-Backward
🍎🌝🌝🍎 🅿️URL= https://duckduckgo.com/?q=産経&t=ffab&ia=meanings
⭕️開始⭕️ 🅿️CurrentURL= https://duckduckgo.com/?q=産経&t=ffab&ia=meanings 🅿️CompURL=
🔵終了🔵 🅿️CurrentURL= https://duckduckgo.com/?q=産経&t=ffab&ia=meanings 🅿️CompURL= ⛔️読完 🅿️URLRow= 1
⛔️終了⛔️ 🅿️CurrentURL= https://duckduckgo.com/?q=産経&t=ffab&ia=meanings 🅿️CompURL= ⛔️読完
⭕️開始⭕️ 🅿️CurrentURL= https://duckduckgo.com/?q=産経&t=ffab&ia=meanings 🅿️CompURL= ⛔️読完<—-無視
*
⭐️ポチ⭐️ 🅿️CurrentURL= http://www.sankei.com/ 🅿️CompURL=<—-リンクをクリック
🍎🌝🌝🍎 🅿️URL= http://www.sankei.com/
⭕️開始⭕️ 🅿️CurrentURL= http://www.sankei.com/ 🅿️CompURL=
🔵終了🔵 🅿️CurrentURL= http://www.sankei.com/smp/ 🅿️CompURL= ⛔️読完 🅿️URLRow= 2
⛔️終了⛔️ 🅿️CurrentURL= http://www.sankei.com/smp/ 🅿️CompURL= ⛔️読完

Screenshot 2018-04-03 00.23.14

糸島はすっかり春になりました。

DSC_0172

Swift4:URLに関わるバグ

webページ読み込みでURLをどうするかでバグが起きることがわかりました。

URLのエンコードとデコード

func CallEncodeURL(_ pString:String) -> String {             //<*Encode with %*>
return (pString as NSString).addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)!
}

func CallGetURL(_ pWeb:WKWebView, pURL:String) -> String {  //<*長い方のURLをStringで返す*>
let wWebURL:String          = String(describing: pWeb.url!).removingPercentEncoding!//webページのURL
let wURL:String             = pURL.removingPercentEncoding!//Current URL
if pURL.count <= 0          { return wWebURL }             //♻️return♻️
else                        { return wURL    }             //♻️return♻️
}

  • 検索パラメータと日本語が混在する場合、%エンコードしないと読み込みがうまくいかなかったのでそうしたのですが、問題は、URLを比較するとき、どちらかにしないとうまくいかないケースが出てきました。
  • もう一点、あるwebページを読み込むとき、2つのURLが存在するケースがありました。このままだと前後のページへの移動ができなくなるので、長いURLに合わせるようにしようとしましたがうまく行かなかったので、ケース的にはないはずの読み込みURLがない場合をwebページURL、それ以外は読み込みURLとしました。
    →そのアイデアではうまく行かないことが判明。次善の策は、いずれかと一致したときという条件でどうか?
  • なお、webページにURLが設定されていないこともあるようです。同上ロジックで短い方を採用する場合、注意が必要です。

Swift4:Stringでwebページ読み込み

NSStringでしか読み込めないと思い込んでいたのがまちがいでした。Stringでも読み込めました。

次のことを新たに注意事項としました。

  • 検索エンジンに検索キーワードとパラメタを設定してURLを作成してwebページ(検索結果)を読み込む場合、Stringに読み込める場合とそうでない場合があります。google関連は読み込めないので、直接、WKWebViewに読み込む必要があります。
  • Stringに読み込めなかった場合、当然、当該htmlに対して編集・加工はできません。
  • macOS Safariでは、まだ未確認ですが、googleの仕様が変わったのでしょうか。それとも、WKWebViewの特性なのでしょうか。

Click SampleWebView4searchEngine Folder.
Source code to test NSString / String / searchEngine URL is @dropbox.
(評価用のソースコードはdropboxの
SampleWebView4searchEngine Folderにあります)

import UIKit //
import WebKit //
class MesaReadURL: UIViewController, WKNavigationDelegate, WKUIDelegate {//
let Com = MesaCommon() //
func CallReadURL(_ pURL:String, pEncode:UInt, pWeb: WKWebView, pAds:String,//<*Read URL or link clicked*>
pCustomFilter:NSMutableArray, pAllowDomain:NSMutableArray, pAllowFileter:NSMutableArray, pSave:UIButton) -> String {//
//🅿 Before to call CallReadURL:
// ① Set web page URL to currentURLにsave.
// ② Set “” to compURL. You can recognize whether or not a user click a link in didStartProvisionalNavigation.
//🅿 Set
// ① pURL to current URL

// ② “” to compURL so that you can separate your assignment from the clicked one.
//🍎 pURL: URL String
//🍎 pEncode: Encode value(UInt)
//🍎 pWeb: WKWebView
//🍎 pAds: 🌝:Block contents 🌚:Not block contents
//🍎 pCustomFilter: customFilter (NSMutableArray) to block contents.
//🍎 pSave: When xSave (UIButton) is RED, don’t make other UIButton effective.
//🅿 return info. “”: OK “\(error)”: NG
var wErrorInfo:String = “”                                  //Clear error info.
var wBuffer:String? = “”                                    //Clear Buffer.
//xWebView?.mainFrame.loadHTMLString(String(“”),baseURL:nil)//Clear webView.
pSave.setImage(#imageLiteral(resourceName: “save No”), for:.normal) //Set Start Reading(= Don’t run the other UIButton.)
let wURL:String? = pURL                                     //Check pURL
if wURL == “” || wURL == nil { return “URL ERROR” }         //”” or nil —> Error
else { }                                                    //
let wEncodedURL:String = Com.CallEncodeURL(wURL!)           //% encode
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
// do { wBuffer = try NSString(contentsOf:URL(string:wEncodedURL)!, encoding:pEncode) as String
do { wBuffer = try String(contentsOf:URL(string:wEncodedURL)!, encoding:String.Encoding(rawValue: pEncode))
} catch let error as NSError {                              //
pSave.setImage(#imageLiteral(resourceName: “save Yes”), for:.normal)//Reset reading URL
  wErrorInfo = “\(error)” + “🍎🍎” + pURL                   //
}                                                           //
if wErrorInfo != “” {                                       //<—Yes, error occurs.
  pWeb.load(URLRequest(url: URL(string:wEncodedURL)!))      //Read URL directly to WKWebView.
return “”                                                   //♻return♻ Return with normal state as
} else { }                                                  //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
let wD = MesaBlock().CallDomainBlockCheck(wEncodedURL, pAllowDomain: pAllowDomain)//block contents?
var wBlocked:String = “”                                       //
if (wD.rState == true) && (pAds == “🌝”) {                     //
wBlocked = MesaBlock().CallBlockMain(wBuffer!,               //
pCustomFilter: pCustomFilter,//
pAllowFileter: pAllowFileter)//Personal contents block process.
  pWeb.loadHTMLString(wBlocked, baseURL:URL(string: pURL))     //Set the String to Web View.
} else {                                                       //<—Don’t block contents.
  pWeb.loadHTMLString(wBuffer!, baseURL:URL(string: pURL))     //Set the String to Web View.
}                                                              //
wBlocked = “”                                                //Not need any more.
return “”                                                    //♻return♻ Normal end. }
//————————————————————-//

func CallEncodeURL(_ pString:String) -> String {                //<*Encode with %*>
  return (pString as NSString).addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)!
}//————————————————————-//

 

Swift4:113 httpエラー

結局、このエラーは解決できそうにない。

残念なことですが、諦めました。

  • Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service
  • Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service

それらしい解決方法を見つけました。しかし、解決できませんでした。

plist変更に関してはhttpを通すために対処済みなので解決策として不適当。subviewに入れる案に関しては対処方法不明。

案2を読むと、段々バグに思えてきて解決意欲がなくなりました。