Month: March 2016

Swift:URLとTitleを取り込むタイミング

webページのURLとTitleをどのタイミングで取り出せるか?

候補は次の2箇所。

  • func webView(sender: WebView!, didStartProvisionalLoadForFrame frame: WebFrame!)  {
  • func webView(sender:WebView, didFinishLoadForFrame frame:WebFrame) {

最初、webページを読み終わったあとだろうと思い、そこにしていました。しかし、読み込む間にほかのボタンが押されてしまうと、読み込み途中の表示のままになる可能性があり、開始時にURLとタイトルを拾えるならそこの方がいいと思うようになりました。

調べたら、開始時にURLもTitleも拾えます。

もう一点留意すべきは次のことです。

  • didStartProvisionalLoadForFrameはひとつのURLを指示して読み込み終了までの間に何回も呼ばれる。
  • didFinishLoadForFrameは最後に1回だけ呼ばれる。
  • URL読み込みが終わったあとに(自分で書いたコードを抜けたあとに)、さらにdidStartProvisionalLoadForFrameが呼び出される可能性があります(実際に呼ばれています)。しかもそのあとにdidFinishLoadForFrameは呼ばれません。これは回避するようにしないとアプリの不具合につながるかもしれないので、調査中。
  • これは、javaがonのときのrefresh?

Swift:URLの読み込み方式

ページの一部にリンク(URL)が正しく入っていない問題が発生しました。

URLを読み込んだページにあるリンクが、あるものは読めるが、ほかのものは読み込めないことがわかりました。ロジックミスやInterface builderを修正していろいろ試したのですが、うまくいきません。

それで次のようなことがわかってきました。pURLはhttp:// or https://ではじまるアドレスが入っています。

  • 正しくリンクが入ってくる。
    xWebView!.mainFrame.loadRequest(NSURLRequest(URL: NSURL(string: pURL)!))
  •  リンクが入ってこないケースがある。
    do { wString = try NSString(contentsOfURL:NSURL(string:pURL)!, encoding:A.currentEncode)
    } catch let error as NSError {  wEStatus    =   “\(error)” } 
    if wEStatus == “” {
    xWebView!.mainFrame.loadHTMLString(String(wString),baseURL:nil) }

次のように修正したら、リンクが入ってきました。

  •  正しくリンクが入ってくる。
    do { wString = try NSString(contentsOfURL:NSURL(string:pURL)!, encoding:A.currentEncode)
    } catch let error as NSError {  wEStatus    =   “\(error)” }  
    if wEStatus == “” {
    xWebView!.mainFrame.loadHTMLString(String(wString),baseURL:pURL) }

Swift:webViewの接続

二つ目のWebViewにURLを読み込み、表示したあとにアプリが暴走。

ロジックにまちがいがないので、どのようにして問題を調査していけばいいか、ない知恵を絞りました。ゴミ捨てに行ったとき、3つ目のWebViewをNSSplitViewの外側に(window直に)定義したらどうか、と思いつきました。

異常終了の原因は、frameLoadDelegateをAppDelegateと接続していたことにありました。frameLoadDelegateをCustomView(WebView)に接続したらうまくいきました。

修正(3/31/2016):ひとつ目と二つ目で接続を変えないといけないことが判明しました。

Screenshot 2016-03-31 06.54.46

Screenshot 2016-03-31 06.55.03

 

Swift:view basedの表

以前チャレンジして挫折したview basedのNSTableViewに再チャレンジしています。

OS X NSTableView TutorialGetting Started With OS X and Swift Tutorialに出ているサンプルコードを調査しました。後者の方が行数が少なくてわかりやすいです。

気がついた点は次の通りです。

追記(3/28/2016):Interface Builderで次のような接続にしないと、wkArray配列(NSMutableArray)を更新し、xTableView?.reloadData()を実行しても、tableViewに制御が渡ってきませんでした。

Screenshot 2016-03-28 03.10.00

MasterViewControllerに関して

  • extension MasterViewController: NSTableViewDataSource {のように書いている箇所があります。全部のMasterViewControllerをMasterViewに変更して、
    let CallViewManager: MasterView! = MasterView(nibName: “MasterView”, bundle: nil)
    と書き換えたのですが、コンパイルエラーが出ました。
  • 最初、nibNameが何に相当するかわかりませんでした。MasterViewController.xibをMasterView.xibに書き換える必要がありました。
  • 次の2つのoverrideが必要。
    func numberOfRowsInTableView(aTableView: NSTableView) -> Int {
        return 配列.count
    }
    func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
    if ((tableView.makeViewWithIdentifier(tableColumn!.identifier, owner:self) as? NSTableCellView) != nil) {
    let wCell:NSTableCellView = tableView.makeViewWithIdentifier(tableColumn!.identifier, owner:self) as! NSTableCellView//setする表のカラム情報をgetする。if tableColumn!.identifier == “fPopup”{
    wCell.textField?.stringValue = tableColumn!.valueForKey(tableColumn!.identifier) as! String//Popupは元の値を残す。
    return wCell} else if tableColumn!.identifier == “fFolder” {
    wCell.textField?.stringValue = wkArray[row][0]//
    return wCell
    } else if tableColumn!.identifier == “fFile”   {
    wCell.textField?.stringValue = wkArray[row][1]//
    return wCell
    } else { }
    } else { return nil }//何もsetしないとき、nilを返す。
    }
  • tableColumn!.identifierでカラム位置を把握し、値をsetする。元の値を残したい場合は、tableColumn!.valueForKey(tableColumn!.identifier) as! Stringを入れればいい。
  • 配列から転記するロジックを入れる。
  • 何もそのカラムに入れない場合は、nilを返す。

2つのwindowの制御(勉強未了)

サンプルプログラムでは、2つのwindowを制御するために次のような処理をしています。この点については勉強未了。アプリのプログラム構造をこのサンプルプログラムと同じにした方がいいかどうか不明。

xWindow.contentView!.addSubview(CallViewManager.view) 
CallViewManager.view.frame = (xWindow.contentView! as NSView).bounds

追記(3/28/2016):

Note: There are two ways that you can populate a tableview—either using the datasource and delegate protocols you’ll see in this OS X NSTableView tutorial, or via Cocoa bindings. When you start a project ensure that you choose between the two approaches. We’ll have tutorials on the site in the future that cover using Cocoa Bindings

 

Swift:NSSplitViewの接続

NSSplitViewの中にNSSpritViewを定義したとき、NSWindowとの接続がわからなくなったので、この際、整理します。

接続の仕方: 赤い線の接続に注意。

Screenshot 2016-03-25 08.25.58

全体図:今回NSTableViewは割愛。

Screenshot 2016-03-25 08.21.11

Swift:NSProgressIndicatorの実装

意外に簡単にできました。

数日前に試してうまくいきませんでした。しかし、先程、きょう中に完成させたいと取り組んだら、ものすごく簡単にできました。多分、これでいいと思いますが・・・。

@IBOutlet var   xProgressIndicator:NSProgressIndicator!

func webView(sender: WebView!, didStartProvisionalLoadForFrame frame: WebFrame!)  {
xProgressIndicator.startAnimation(self)
}

 

func webView(sender:WebView, didFinishLoadForFrame frame:WebFrame) {
xProgressIndicator.stopAnimation(self)

}

 

Swift:URL読み込み2つの疑問?

なぜそうなるのか、理由が不明。

webViewに直接読み込まないとダメ。

これは、以前、.archiveのリンクを読み込んだとき、似たような問題があったような気がしますが、記憶が曖昧です。

  • xWebView!.mainFrame.loadRequest(NSURLRequest(URL: NSURL(string:pURL)!))
  • wString = try NSString(contentsOfURL:NSURL(string:pURL)!, encoding: A.currentEncode)
    xWebView!.mainFrame.loadHTMLString(String(wString), baseURL:nil) 

faviconを取り出せない。

backwardしてfowardしたあとならOKなようですが、イマイチで、再現方法と原因までたどり着けていません。

Swift:Xcode7.3(Swift2.2)の洗礼

今朝、Xcode7.3(Swift2.2)にアップデートしました。

一日の半分くらいを棒に振りました。コンパイルエラーの多さにガックリ。

for文、配列[index1][index2]の形式がアウトでした。

forはwhileに書き直そうとしたのですが、リリース済みアプリの修正を考えるとリスクがおおきくなるので、for文のままで対応することにしました。

配列 

  • wArray[0] [0] as! String
  • ➡️ (wArray[0] as! NSArray)[0] as! String

for昇順

  • for inx = 0; inx < C.msgUS.count; inx++ {
  • ➡️for inx in 0 ..< C.msgUS.count {

for降順

  • for var inx = wstart; inx > A.webArrayCurrentIndex; inx– {
  • ➡️for inx in (A.webArrayCurrentIndex+1 ..< A.webArray.count).reverse() {
  • [A.webArray.count-1]から[A.webArrayCurrentIndex+1]まで処理

for降順に手間取りました。

参考:既存アプリの Xcode 7.3 + Swift 2.2 対応がたいへんよくまとまっています。