web-dev-qa-db-ja.com

完了ハンドラーSwift 3関数から変数を返します

Swift 3の完了ハンドラーの構文をめぐって混乱しています。

以下の関数では、Webサービス呼び出しからxmlファイルを解析した後、変数(array [String:String])。
私の試みは以下のとおりですが、明らかに間違っています。

  enum HistoryKey {
  case success([String:String])
  case failure(String)
 }

 private func getHistoryKeys(searchterm: String, completion: @escaping () -> HistoryKey) {
    let url = PubmedAPI.createEsearchURL(searchString: searchterm)
    let request = URLRequest.init(url: url as URL)
    let task = session.dataTask(with: request) { (data, response, error) in

        if let theData = data{
            let myParser = XMLParser.init(data: theData)
            myParser.delegate = self
            myParser.parse()
        }
    }
    task.resume()

    if keys.isEmpty {
        return .failure("no historyKeyDictionary")
    }else{
        return .success(keys)
    }

}// End of func

この機能を次のように使いたい

 let result = self.getHistoryKeys(searchTerm)
3
tim

2つの問題:

  • 完了ハンドラーはHistoryKeyインスタンスを渡し、戻り値がないため、署名は逆である必要があります。
  • 完了ハンドラーの呼び出しは、insideデータタスクの完了ブロックである必要があります。

完了ブロックの外で受信したデータを解析できるようにするには、成功した場合にdataを返します。

enum ConnectionResult {
   case success(Data)
   case failure(Error)
}

private func getHistoryKeys(searchterm: String, completion: @escaping (ConnectionResult) -> ()) {
   let url = PubmedAPI.createEsearchURL(searchString: searchterm)
   let task = session.dataTask(with: url) { (data, response, error) in
       if let error = error {
          completion(.failure(error))
       } else {
          completion(.success(data!))
       }
  }
  task.resume()
}

そしてそれを呼ぶ

getHistoryKeys(searchterm: String) { connectionResult in 
    switch connectionResult {
       case .success(let data): 
           let myParser = XMLParser(data: data)
           myParser.delegate = self
           myParser.parse()
           // get the parsed data from the delegate methods

       case .failure(let error): print(error)
    }
}
12
vadian

completionブロックを使用していません。
次のように使用します:

private func getHistoryKeys(searchterm: String, completion: @escaping (_ keys: Array) -> Void) {
    //do the magic
    completion(keys)
}

次に、この関数を次のように呼び出すことができます。

getHistoryKeys(searchterm: "str") { (keys) in 
    print("\(keys)")
}
2
D4ttatraya

完了ハンドラーの引数として結果を返します。

private func getHistoryKeys(searchterm: String, completion: @escaping (result: HistoryKey) -> Void) {
    let url = PubmedAPI.createEsearchURL(searchString: searchterm)
    let request = URLRequest.init(url: url as URL)
    let task = session.dataTask(with: request) { (data, response, error) in

        if let theData = data{
            let myParser = XMLParser.init(data: theData)
            myParser.delegate = self
            myParser.parse()
        }

        //DispatchQueue.main.async { // if you want to do UI stuff dispatch calls to completion() on the main queue
        if keys.isEmpty {
            completion(.failure("no historyKeyDictionary"))
        } else{
            completion(.success(keys))
        }
        //}
    }
    task.resume()   
}

そしてそれをこのように呼んでください:

getHistoryKeys("searchMe") { (result: HistoryKey) in
    print(result)
}
1
shallowThought

Swift 4.2

enum HistoryKey {
    case success([String:String])
    case failure(String)
}

func myFunction(str: String, completionHandler: @escaping (HistoryKey) -> ()){
     completion(.success([String:String]))
     //OR
     completion(.failure(""))
}

myFunction(str: String) { result in 
    switch result {
       case .success(let data): break;
       case .failure(let error): break;
    }
}

[〜#〜]または[〜#〜]

func myFunction(str: String, completionHandler: @escaping (String) -> ()){
     completionHandler("")
} 

myFunction(str: "someThing", completionHandler: {(str) in

})
1
ZAFAR007

私が見ることができるものから、それはあるべきです

_private func getHistoryKeys(searchterm: String, completion: @escaping (HistoryKey) -> ())
_

また、returnの代わりにcompletion(.failure("no historyKeyDictionary"))またはcompletion(.success(keys))を使用する必要があります

0
Tristan Beaton
 enum HistoryKey {
    case success([String: String])
    case failure(String)
 }

 private func getHistoryKeys(searchterm: String, completion: @escaping (_ result: HistoryKey) -> Void) {
    let url = PubmedAPI.createEsearchURL(searchString: searchterm)
    let request = URLRequest.init(url: url as URL)
    let task = session.dataTask(with: request) { (data, response, error) in

        if let theData = data{
            let myParser = XMLParser.init(data: theData)
            myParser.delegate = self
            myParser.parse()
        }

        if keys.isEmpty {
            completion(.failure("no historyKeyDictionary"))
        } else {
            completion(.success(keys))
        }
    }
    task.resume()    
} // End of func

そんな感じ。変化する @escaping宣言し、returnの代わりに完了を実行します。

それが役に立てば幸い。

0
Vlad Pulichev