J'utilise un completionHandler dans cette fonction, mais il est imbriqué dans plusieurs boucles for (ci-dessous). Le problème est le gestionnaire où il est maintenant appelé chaque fois que la boucle dans laquelle il s'exécute, alors que je veux seulement que le gestionnaire passe dans le Set
lorsque la fonction entière a terminé le traitement. Si je le place en dehors de la boucle, il est appelé trop tôt et est vide. Que devrais-je faire ici?Où placer un completionHandler à l'intérieur des boucles?
En ce moment, lorsque j'imprime à la console pour le tester imprime: Set article 1 Set article 1, 2 Set point 1, 2, 3, etc.
struct RekoRequest {
public func getRekos(rekoType: rekoCategory, handler: @escaping (Set<String>) -> Void) {
var urls = [NSURL]()
var IDs = Set<String>()
TwitterRequest().fetchTweets(searchType: "things") { result in
guard let tweets = result as? [TWTRTweet] else {print("Error in getRekos receiving tweet results from TwitterRequest.fetchTweets"); return}
for tweet in tweets {
let types: NSTextCheckingResult.CheckingType = .link
let detector = try? NSDataDetector(types: types.rawValue)
guard let detect = detector else { print("NSDataDetector error"); return }
let matches = detect.matches(in: text, options: .reportCompletion, range: NSMakeRange(0, (text.characters.count)))
for match in matches {
if let url = match.url {
guard let unwrappedNSURL = NSURL(string: url.absoluteString) else {print("error converting url to NSURL");return}
//Show the original URL
unwrappedNSURL.resolveWithCompletionHandler {
guard let expandedURL = URL(string: "\($0)") else {print("couldn't covert to expandedURL"); return}
guard let urlDomain = expandedURL.host else { print("no host on expandedURL"); return }
switch urlDomain {
case "www.somesite.com":
let components = expandedURL.pathComponents
for component in components {
if component == "dp" {
guard let componentIndex = components.index(of: component) else {print("component index error"); return}
let IDIndex = componentIndex + 1
let ID = components[IDIndex]
//Filter out Dups and add to Set
IDs.insert(ID)
handler(IDs)
print(ID) //this prints multiple sets of IDs, I only want one when the function is finished completely
}
}
break;
default:
break;
}
}
} else { print("error with match.url") }
} //for match in matches loop
} //for tweet in tweets loop
}
}
}
// Create an extension to NSURL that will resolve a shortened URL
extension NSURL
{
func resolveWithCompletionHandler(completion: @escaping (NSURL) -> Void)
{
let originalURL = self
let req = NSMutableURLRequest(url: originalURL as URL)
req.httpMethod = "HEAD"
URLSession.shared.dataTask(with: req as URLRequest)
{
body, response, error in completion(response?.url as NSURL? ?? originalURL)
}
.resume()
}
}
pourquoi ne pas mettre le gestionnaire d'achèvement après la boucle? –
Quand je le mets après la boucle, j'obtiens un ensemble vide – GarySabo
@GarySabo Où insérez-vous dans l'ensemble 'IDs'? Est-ce que 'setOfIDs' est supposé être' IDs'? –