не может получить доступ к значению извне userCompletionHandler - PullRequest
0 голосов
/ 01 июня 2019

Я работаю с API (API YouTube, если быть более точным ...), чтобы получить название видео.

Поэтому я в основном создал функцию для вызова API и получения ответа на то, что я ищу. После этого я хочу иметь возможность взять этот результат и вернуть его в tableCellView.

Получение информации в порядке, все работает. Но когда я хочу взять информацию и вернуть ее, возникает проблема.

Так вот моя функция:

func fetchData(userCompletionHandler: @escaping (String?, Error?) -> Void){
    var yUrl = URL(string: youtubeUrlForRequest)
    let task = URLSession.shared.dataTask(with: yUrl!) { (data, yresponse, yerror) in
        do {
            if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as? [String : AnyObject] {

                if var items = jsonResult["items"] as? [AnyObject]? {
                    var snippetDict = items?[0]["snippet"] as! [String: AnyObject]
                    var titleVideo = snippetDict["title"] as! String
                    userCompletionHandler(titleVideo, nil)
                }
            }
        }
        catch {
            print("json error: \(error)")
        }
    }
    task.resume()

}

Так что с этой частью все в порядке.

Вот как я называю свою функцию:

fetchData ( userCompletionHandler: { (ytitle, yerror) in
        //var untitre = ""

        guard let untitle = ytitle else{
            print("Ok I'm in!!!")
            //untitle = ytitle
            //print(untitle)
            return
        }
        print("OK HERE!!!!!!!!")
        print(untitle)
    })
    //var test_titre = "Le titre est: " + bontitre
    print(untitle)
    return ()

Так что print(untitle) под print("OK HERE!!!!!!!") в порядке, я получаю нужные данные.

Но print(untitle) над return() не напечатает то же самое. Он напечатает значение, которое я дал untitle, когда я создал его выше:

var untitle: String = "a"

Моя цель - иметь возможность иметь return(untitle) с названием видео, где return() прямо сейчас.

1 Ответ

0 голосов
/ 02 июня 2019

Я, наконец, могу узнать, как получить нужную информацию, с помощью DispatchGroup, чтобы убедиться, что все фрагменты информации были там, прежде чем выполнять какие-либо действия.

Итак, главное отличие кода выше следующего - это порядок действий, которые все изменили. Поэтому в моем старом коде я обычно запрашивал обновление моего tableView и в этой функции обновления, а затем вызывал API YouTube. Эта установка привела меня в узкое место. Поэтому после некоторых советов (спасибо, ребята!) Я решил сначала вызвать API и сохранить результат в новом массиве. Как только все будет доступно (с помощью DispatchGroup), я обновлю tableView данными нового нового массива.

Итак, вот (большая часть) новый код моих различных функций (некоторые из них связаны с кнопками или другими элементами пользовательского интерфейса):

let youtubeUrl = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails%2C+snippet%2C+statistics&id="
//"AKiiekaEHhI&key="
var youtubeUrlForRequest:String = ""
let dispatchGroup = DispatchGroup()
var test_title: Array<String> = []


//func

@IBAction func plus(_ sender: NSButton) {
    if urlInput.stringValue == "" {

    } else {
        if valeurEndroit.indexOfSelectedItem == -1{
            print("coucou!")
            test_text = urlInput.stringValue
            test_data.append(test_text)
            dispatchGroup.enter()
            fetchData2(lien: test_data.last!, userCompletionHandler: {data_y, user_y, error_y in
                if let user_y = user_y{
                    self.test_title.append(user_y)
                    self.dispatchGroup.leave()
                }
            })
            dispatchGroup.notify(queue: .main) {
                //print(untitle)
                print("J'ai fini la liste de titre. Voici la liste: ")
                //print(self.test_title)
                self.urlInput.stringValue = ""
                print(self.test_title)
                self.tableView.reloadData()
            }


            //tableView.reloadData()
        }else{
            if valeurEndroit.indexOfSelectedItem >= test_data.count{
                test_text = urlInput.stringValue
                test_data.append(test_text)
                dispatchGroup.enter()
                fetchData2(lien: test_data.last!, userCompletionHandler: {data_y, user_y, error_y in
                    if let user_y = user_y{
                        self.test_title.append(user_y)
                        self.dispatchGroup.leave()
                    }
                })
                dispatchGroup.notify(queue: .main) {
                    //print(untitle)
                    print("J'ai fini la liste de titre. Voici la liste: ")
                    //print(self.test_title)
                    self.urlInput.stringValue = ""
                    print(self.test_title)
                    self.tableView.reloadData()
                }
            }else{
                var y_index = (valeurEndroit.indexOfSelectedItem)
                test_text = urlInput.stringValue
                test_data.insert(test_text, at: valeurEndroit.indexOfSelectedItem)
                dispatchGroup.enter()
                fetchData2(lien: test_data[y_index], userCompletionHandler: {data_y, user_y, error_y in
                    if let user_y = user_y{
                        self.test_title.insert(user_y, at : y_index)
                        self.dispatchGroup.leave()
                    }
                })
                dispatchGroup.notify(queue: .main) {
                    //print(untitle)
                    print("J'ai fini la liste de titre. Voici la liste: ")
                    //print(self.test_title)
                    self.urlInput.stringValue = ""
                    print(self.test_title)
                    self.tableView.reloadData()
                }
            }
        }

    // fonction du bouton +
    }
}

@IBAction func nextLien(_ sender: NSButton) {
    if test_data == [] {

    } else {
    nextUrl=test_data[0]
    var monUrl = URL(string: nextUrl)
    var maRequete = URLRequest(url: monUrl!)
    view_web.load(maRequete)
    test_data.remove(at: 0)
    test_title.remove(at: 0)
    tableView.reloadData()
    //fonction du bouton pour le prochain lien
    }
}

@IBAction func openUnFichier(_ sender: NSMenuItem) {
    let fichierPanel: NSOpenPanel = NSOpenPanel()
    fichierPanel.allowsMultipleSelection = false
    fichierPanel.canChooseFiles = true
    fichierPanel.canChooseDirectories = false
    fichierPanel.allowedFileTypes = ["txt"]
    let response = fichierPanel.runModal()
    if response == NSApplication.ModalResponse.OK{
        guard let selectedURL = fichierPanel.url else{return}
        do{
            var fullDocument = try String(contentsOf: selectedURL, encoding: String.Encoding.utf8)
            var lines : [String] = fullDocument.components(separatedBy: "\n" as String)
            for line in lines {
                test_data.append(line)
                dispatchGroup.enter()
                fetchData2(lien: test_data.last!, userCompletionHandler: {data_y, user_y, error_y in
                    if let user_y = user_y{
                        self.test_title.append(user_y)
                        self.dispatchGroup.leave()
                    }
                })
                dispatchGroup.notify(queue: .main) {
                    //print(untitle)
                    print("J'ai fini la liste de titre. Voici la liste: ")
                    //print(self.test_title)
                    self.urlInput.stringValue = ""
                    print(self.test_title)
                    self.tableView.reloadData()
                }
            }
        } catch let error as NSError{
            print("Erreur!!!!!!! \(error)")
        }
        //tableView.reloadData()
    }else {

    }
}

func numberOfRows(in tableView: NSTableView) -> Int {
    return test_title.count
}

func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
    return (test_title[row])

}

func fetchData2(lien: String, userCompletionHandler: @escaping (String?, String?, Error?) -> Void){
    var titleLien: String = ""
    var urlToExtract_y = lien
    var videoID_y = urlToExtract_y.components(separatedBy: "=")[1]
    var youtubeUrlForRequest_y = youtubeUrl + videoID_y + "&key=" + youtubeApiKey
    print(youtubeUrlForRequest_y)
    var Url_y = URL(string: youtubeUrlForRequest_y)
    var titleVideo_y = ""
    let task_y = URLSession.shared.dataTask(with: Url_y!) { (data_y, response, error_y) in
        do {
            if let jsonResult_y = try JSONSerialization.jsonObject(with: data_y!, options: JSONSerialization.ReadingOptions.allowFragments) as? [String : AnyObject] {

                if var items_y = jsonResult_y["items"] as? [AnyObject]? {
                    var snippetDict_y = items_y?[0]["snippet"] as! [String: AnyObject]
                    var titleVideo_y = snippetDict_y["title"] as! String
                    userCompletionHandler(titleVideo_y, titleVideo_y, nil)
                }
            }
        }
        catch {
            print("json error: \(error_y)")
        }
    }
    task_y.resume()
}




//var Outlet

@IBOutlet weak var urlInput: NSTextField!

@IBOutlet weak var view_web: WKWebView!

@IBOutlet weak var tableView: NSTableView!

@IBOutlet weak var valeurEndroit: NSComboBox!

Некоторые части здесь не вставлены, потому что это не важно для понимания или чувствительно (например, ключ API Youtube).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...