2016-08-31 22 views
0

RSSフィードからXMLを取得し、各記事のリンクを取得してから、これらの記事から情報を抽出しようとしています。私はxmlを得るためにAEXML、リンク抽出のためにReadabilityKitを使用しています。非同期呼び出し内の非同期呼び出しが実行されない

XMLからのリンクを正常にプルしていますが、可読性に関するパーサー呼び出しは決して実行されません。私はすべてのUIをブロックするので、これをメインスレッドでは望んでいませんが、これまでのところ、私がそれを機能させる唯一の方法です。コードは(発送はメインキューを取得することを取り除い)以下である:

func retrieveXML() { 
    let request = NSURLRequest(URL: NSURL(string: "<XML URL HERE>")!) 
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { 
     (data, response, error) in 

     if data == nil { 
      print("\n\ndataTaskWithRequest error: \(error)") 
      return 
     } 

     do { 
      let xmlDoc = try AEXMLDocument(xmlData: data!) 
      for child in xmlDoc.root.children { 

       if let postURL = child["id"].value { 

        let url = NSURL(string: postURL) 
        let parser = Readability(url: url!) 
        let title = parser.title() 
        print("TITLE: \(title)") 
       } 
      } 
     } catch { 
      print(error) 
     } 
    } 
    task.resume() 
} 
+0

これを試しましたか? 'DispatchQueue.main.async { のlet URL = NSURL(文字列:postURL) LETパーサ=可読性(URL:URL!) LETタイトル= parser.title() プリント( "TITLE:\(タイトル)") } ' – heikomania

+0

コンパイルしない@heikomania = /。しかし、メインのキューに "parser = Readability ..."という行を置くとUIがブロックされますが、これは嫌です。 – kerbelda

+0

ええ、スウィフト3でメインキューにディスパッチしますが、コンセプトは正しいです:「可読性」はデッドロックであるため、別のキューに非同期にディスパッチする必要があります。しかし、私はそれにメインキューを使うべきではない、と私は同意します。もちろん、Swift 2を使用している場合は、Swift 2構文を使用します。 – Rob

答えて

0

問題はReadabilityがデッドロックされていることです。 NSURLSessionコンプリートブロック(デフォルトではシリアルキュー)から呼び出しますが、Readabilityブロックは、それ自身のネットワーク要求が完了するまでセマフォをキューに入れます。従ってReadabilityは、ブロッキングしているスレッドと同じスレッドから送信されるはずのセマフォ信号を待っているスレッドをブロックしているため、デッドロックしています。

Readabilityをインスタンス化するコードを別のキュー(グローバルキューなど)に非同期でディスパッチすることで、これを修正できます。

dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) { 
    let url = NSURL(string: postURL) 
    let parser = Readability(url: url!) 
    let title = parser.title() 
    print("TITLE: \(title)") 
} 

そのAPIを非同期で実行するように更新されているので、最新のバージョンと、このデッドロックの問題が解消されますと、上記の非同期ディスパッチが必要とされることはありませんように見えます。あなたは明らかに、更新されたAPIの完了ハンドラパターンを採用する必要があります。

1

ご報告いただきありがとうございます。新しいバージョンは、新しいaync APIを使用して、ココアのポッドやカートで利用できます。 Sync APIはプロジェクトから削除されます。

Readability.parse(url: articleUrl, { data in 
    let title = data?.title 
    let description = data?.description 
    let keywords = data?.keywords 
    let imageUrl = data?.topImage 
    let videoUrl = data?.topVideo 
}) 

お寄せいただきありがとうございます。詳細はREADMEをご確認くださいhttps://github.com/exyte/ReadabilityKit

関連する問題