web-dev-qa-db-ja.com

SwiftコマンドラインプログラムからNSURLSessionを使用する

より大きなアプリに統合する前に、小さな概念実証コマンドラインアプリをテストしようとしています。私がやろうとしているのは、 この例 を使用してNSURLSessionを使用していくつかのデータをダウンロードすることです。ただし、単純なOS Xコマンドラインアプリで示した例を使用すると、データが取得される前にアプリが終了するようです。

NSURLSessionを使用してスタンドアロンコマンドラインアプリからデータをダウンロードするにはどうすればよいですか?私が読んだのは NSRunLoop を使用していますが、Swift)で明確な例をまだ見つけていないので、NSRunLoopが実際に進む方法である場合、どの例でも感謝します。

SwiftコマンドラインアプリのURLからデータをダウンロードするための他の戦略も歓迎します(無限のwhileループ?)。

27
Fred Clausen

セマフォを使用して現在のスレッドをブロックし、URLセッションが終了するのを待つことができます。

セマフォを作成し、URLセッションを開始して、セマフォを待ちます。 URLセッション完了コールバックから、セマフォにシグナルを送信します。

グローバルフラグ(揮発性ブール変数を宣言する)を使用して、whileループからポーリングすることもできますが、それは最適ではありません。一つには、CPUサイクルを不必要に消費しているということです。

これは私が遊び場を使って行った簡単な例です:

import Foundation

var sema = DispatchSemaphore( value: 0 )

class Delegate : NSObject, URLSessionDataDelegate
{
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
    {
        print("got data \(String(data: data, encoding: .utf8 ) ?? "<empty>")");
        sema.signal()
    }
}

let config = URLSessionConfiguration.default
let session = URLSession(configuration: config, delegate: Delegate(), delegateQueue: nil )

guard let url = URL( string:"http://Apple.com" ) else { fatalError("Could not create URL object") }

session.dataTask( with: url ).resume()    

sema.wait()
34
nielsbot

これを試して

let sema = DispatchSemaphore( value: 0)

let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/4/4d/Cat_November_2010-1a.jpg")!;

let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
  print("after image is downloaded");
  sema.signal(); // signals the process to continue
};

task.resume();
sema.wait(); // sets the process to wait
6
thiagoh

テスト目的のみの場合、コマンドラインアプリのハードコード「実行時間」を次のようにすると、セマフォの使用を回避できます。

Swift

//put at the end of your main file
RunLoop.main.run(until: Date(timeIntervalSinceNow: 15))  //will run your app for 15 seconds only

これは非常に迅速で汚い他のスレッドが終了するのを待つためにコマンドラインアプリを「有効にする」方法です。また、アプリのプロセスを明示的に強制終了またはキャンセルしなくても、タイムアウトの期限が切れるとアプリは正常に終了します。

[〜#〜]注[〜#〜]

  1. ネットワークタスクの完了にさらに時間がかかる場合は、「タイムアウト」期間を変更できます。
  2. より深刻な待機メカニズムが必要な場合、この「解決策」は間違いなく不適切な決定です(別名。しないでくださいこれを本番環境で使用してください)
3
Vexy