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)
2つの問題:
HistoryKey
インスタンスを渡し、戻り値がないため、署名は逆である必要があります。完了ブロックの外で受信したデータを解析できるようにするには、成功した場合に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)
}
}
completion
ブロックを使用していません。
次のように使用します:
private func getHistoryKeys(searchterm: String, completion: @escaping (_ keys: Array) -> Void) {
//do the magic
completion(keys)
}
次に、この関数を次のように呼び出すことができます。
getHistoryKeys(searchterm: "str") { (keys) in
print("\(keys)")
}
完了ハンドラーの引数として結果を返します。
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)
}
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
})
私が見ることができるものから、それはあるべきです
_private func getHistoryKeys(searchterm: String, completion: @escaping (HistoryKey) -> ())
_
また、return
の代わりにcompletion(.failure("no historyKeyDictionary"))
またはcompletion(.success(keys))
を使用する必要があります
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の代わりに完了を実行します。
それが役に立てば幸い。