0

Firstly a domain name should be entered. Then, I have an add button, which adds keywords in an array[String], which keyword used for google searches through the API URL. If the specified domain name matches with any URL in search results the API returns the listing rank of the domain URL. Simply it's an SEO app.

Here is my question, when I try to fetch more than one result in a loop fetching process starts for all keywords in the array. And my sequence gets messed up. I want to fetch results one after one.

I tried to use semaphore and dispatch group but I'm new in codding so probably did some mistakes it did not work. So I leave below raw and clean codes.

You can find a loop example and my fetching codes below.

@objc func refresh(_ sender: AnyObject) {
    var n = 0
    if keywordModel.keywordNames.count == 0 && 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)
        }
    }

And this part used for fetching.

func fetchSEO(keyword: String, requestURL: String? = nil, start: Int? = 1) {
        let start = start
        let urlString = "https://www.googleapis.com/customsearch/v1?q=\(keyword)&lr=\(lang)&gl=\(location)&start=\(start ?? 1)&key=\(apiKey)&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)
}

0 Answers0