Вложенный запрос Alamofire и Asyn c очередь отправки - PullRequest
0 голосов
/ 24 марта 2020

Я пытаюсь реализовать вложенный запрос Alamofire: - первый запрос вызывает код - второй запрос вызывает результат, используя код, полученный в первом запросе

Более того, я предполагаю, что есть проблема с объект DispatchQueue, я думал использовать DispatchQueue.main.asyn c для второго запроса, но это здесь не принимается.

В следующих строках второй запрос возвращает мне нулевой результат, поскольку он не включает код, найденный в первом запросе.

    func fetch(jan: String) {

 AF.request("https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemSearch?appid=\(appId)&jan=\(jan)&hits=50").responseDecodable(of: Welcome.self , queue: DispatchQueue.main) { response in 
    let boncode1 = String("\(response.value?.resultSet.the0.result.the0?.code)")     
    print(boncode1)

AF.request("https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemLookup?appid=\(self.appId)&itemcode=\(boncode1)").responseDecodable(of: troisViewController.Welcome.self , queue: DispatchQueue.main) { response in

            print("\(response.value?.resultSet.the0.result.the0?.name ?? "is nil" )")

        }
    }
}

Я надеюсь, что кто-то уже имел дело с подобной проблемой,

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 24 марта 2020

Если вам нужно 2 служебных вызова, то вложенные функции могут соответствовать вашим потребностям. Но представьте, что вам нужно обработать результат 5 или даже больше вызовов службы, это наверняка будет Pyramid of Doom кошмар.

Чтобы избежать этого, я бы рекомендовал вам взглянуть на DispatchGroup API и узнать, как его использовать.

Группы позволяют объединять набор задач и синхронизировать поведение в группе. Вы присоединяете несколько рабочих элементов к группе и планируете их асинхронное выполнение в одной и той же очереди или в разных очередях. Когда все рабочие элементы завершают выполнение sh, группа выполняет свой обработчик завершения. Вы также можете синхронно ожидать выполнения всех задач в группе до завершения sh.

Таким образом, вы можете реализовать свою функцию следующим образом:

func fetch(jan: String) {

    // Local variable
    var boncode1: String = ""

    // Create group
    let dispatchGroup = DispatchGroup()

    // Fetch data from the first service

    let url_1 = "https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemSearch?appid=\(appId)&jan=\(jan)&hits=50"

    // Indicate that the first block of work (first service call) has entered the group.
    dispatchGroup.enter()

    AF.request(url_1).responseDecodable(of: Welcome.self) { response in
        // Store data in local variable
        boncode1 = String("\(response.value?.resultSet.the0.result.the0?.code)")

        // Indicate that the first block in the group finished executing.
        dispatchGroup.leave()
    }

    // Fetch data from the second service

    let url_2 = "https://shopping.yahooapis.jp/ShoppingWebService/V1/json/itemLookup?appid=\(self.appId)&itemcode=\(boncode1)"

    //Indicate that the second block of work (second service call) has entered the group.
    dispatchGroup.enter()

    AF.request(url_2).responseDecodable(of: troisViewController.Welcome.self) { response in
        // handle response from the second service if you need it

        // Indicate that the second block in the group finished executing.
        dispatchGroup.leave()
    }

    // This function schedules a notification block to be submitted to the specified queue 
    // when all blocks associated with the dispatch group have completed.
    dispatchGroup.notify(queue: .main) {
        // process results of 2 service calls
    }
}
0 голосов
/ 24 марта 2020

Alamofire не предоставляет собственных асин c примитивов. Скорее, вы можете составлять запросы Alamofire с существующими примитивами или предоставлять свои собственные. Самое простое, хотя и не элегантное, решение здесь - просто вкладывать вызовы:

AF.request(...).responseDecodable(of: ...) { outer in
    // Handle outer response.
    AF.request(...).responseDecodable(of: ...) { inner in
        // Handle inner response.
    }
}

Кроме того, нет необходимости передавать DispatchQueue.main в Alamofire, поскольку это очередь по умолчанию, в которой ваши обработчики ответов в любом случае вызываются.

...