Как я могу получить результаты API в очереди

#ios #swift #api #dispatch-queue

Вопрос:

Сначала следует ввести доменное имя. Затем у меня есть кнопка добавить, которая добавляет ключевые слова в массив[Строка], ключевое слово, используемое для поиска Google по URL API. Если указанное доменное имя совпадает с любым URL-адресом в результатах поиска, API возвращает рейтинг списка URL-адреса домена. Просто это SEO-приложение.

Вот мой вопрос: когда я пытаюсь получить более одного результата в цикле, начинается процесс выборки для всех ключевых слов в массиве. И моя последовательность путается. Я хочу получать результаты один за другим.

Я пытался использовать семафор и группу отправки, но я новичок в кодировании, поэтому, вероятно, допустил некоторые ошибки, это не сработало. Поэтому я оставляю ниже необработанные и чистые коды.

Вы можете найти пример цикла и мои коды выборки ниже.

 @objc func refresh(_ sender: AnyObject) {
    var n = 0
    if keywordModel.keywordNames.count == 0 amp;amp; keywordModel.keywordRanks.count == 0 {
        refreshControl?.endRefreshing()
    } else {
        keywordModel.keywordRanks = [Double]()
        keywordModel.keywordNames = [String]()
        keywordModel.averageRank = 0
        keywordModel.keywordCount = 0
        tableView.reloadData()
        let keywords = selectedDomain?.keywords

        var rawKeys = [String]()
        while n < keywords!.count {

            let keys = keywords![n].name
            rawKeys.append(keys)
            n  = 1
        }
        
        let enumKeys = rawKeys.enumerated()
        enumKeys.forEach { forEachKey in
            seo.fetchSEO(keyword: forEachKey.element, requestURL: selectedDomain?.domainName, start: 1)
        }
    }
 

И эта часть используется для извлечения.

 func fetchSEO(keyword: String, requestURL: String? = nil, start: Int? = 1) {
        let start = start
        let urlString = "https://www.googleapis.com/customsearch/v1?q=(keyword)amp;lr=(lang)amp;gl=(location)amp;start=(start ?? 1)amp;key=(apiKey)amp;cx=(searchEngine)"
        performRequest(with: urlString, for: keyword, request: requestURL, startIndex: start ?? 1)
}

func performRequest(with urlString: String, for keyword: String, request requestURL: String?, startIndex: Int) {
    if let url = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!) {
        
        let session = URLSession(configuration: .default)
        let dataTask = session.dataTask(with: url) { data, response, error in
            
            if let e = error {
                delegate?.didFailWithError(error: e)
            } else {
                if let dataSafe = data {
                    if let seoData = parseJSON(data: dataSafe) {
                        checkForLinkorNextPage(seoData: seoData, url: urlString, requestURL: requestURL, keyword: keyword, nextPageStartIndex: startIndex)
                    }
                }
            }
        }
        dataTask.resume()
    }
}

func checkForLinkorNextPage(seoData: SEODataBrain, url: String, requestURL: String?, keyword: String, nextPageStartIndex: Int) {
    var n = 0
    var startIndexForNextPage = nextPageStartIndex
    
    while n < seoData.items.count {
        if let link = seoData.items[n].link {
            delegate?.getLinks(link: link)
            let listLine = startIndexForNextPage   n
            if let request = requestURL {
                if link.contains(request) {
                    delegate?.seoModel(link: link, url: request, listLine: listLine, keyword: keyword)
                    n = 0
                    return
                } else {
                    n  = 1
                }
            } else {
                n  = 1
            }
            print(n)
            if n == 10 {
                
                startIndexForNextPage  = 10
                fetchSEO(keyword: keyword, requestURL: requestURL, start: startIndexForNextPage)
            }
        }
    }
}

func parseJSON(data: Data) -> SEODataBrain? {
    let decoder = JSONDecoder()
    
    do {
        let seoData = try decoder.decode(SEODataBrain.self, from: data)
        return seoData
    } catch {
        delegate?.didFailWithError(error: error)
        return nil
    }
}

func didFailWithError(error: Error) {
    print(error.localizedDescription)
}
 

Комментарии:

1. Возможно, вы захотите прочитать первую часть biteinteractive.com/… , показывает вам, какие у вас есть варианты для зацикливания

2. Большое спасибо. Читаю это прямо сейчас!