Я пытаюсь использовать многопоточность в Swift для извлечения и отображения изображения в контроллере представления. Однако функция, которую я использую для извлечения изображения, находится в отдельной модели. Я мог бы просто скопировать и вставить функцию в контроллер представления, но я буду повторно использовать эту функцию несколько раз и предпочту оставить ее отдельно от конкретного контроллера представления.Swift - использовать многопоточность из функции в отдельном файле
Функция я в настоящее время (опять же, в отдельном файле я по имени WikimediaAPI) имеет следующий вид:
public func getThumbnailImage(forPage page: String) -> UIImage? {
if let data = try? Data(contentsOf: URL(string: "https://en.wikipedia.org/w/api.php?action=query&titles=" + page + "&prop=pageimages&format=json&pithumbsize=1000")!) {
let json = JSON(data: data)
if let pageId = json["query"]["pages"].dictionary?.first?.key {
if let imageUrl = json["query"]["pages"][pageId]["thumbnail"]["source"].string {
if let url = URL(string: imageUrl) {
if let imageData = try? Data(contentsOf: url) {
if let image = UIImage(data: imageData) {
return image
}
}
}
}
}
}
return nil
}
Вышеуказанные работы, но не многопоточный, и когда я непосредственно перейти к контроллеру вид из контроллер табличного представления занимает слишком много времени. Я пытался реализовать многопоточность где-то вдоль этих линий, но я не имею права ничего возвращать в асинхронном блоке
public func getThumbnailImage(forPage page: String) -> UIImage? {
DispatchQueue.global().async {
if let data = try? Data(contentsOf: URL(string: "https://en.wikipedia.org/w/api.php?action=query&titles=" + page + "&prop=pageimages&format=json&pithumbsize=1000")!) {
DispatchQueue.main.async {
let json = JSON(data: data)
if let pageId = json["query"]["pages"].dictionary?.first?.key {
if let imageUrl = json["query"]["pages"][pageId]["thumbnail"]["source"].string {
if let url = URL(string: imageUrl) {
DispatchQueue.global().async {
if let imageData = try? Data(contentsOf: url) {
DispatchQueue.main.async {
if let image = UIImage(data: imageData) {
return image //error: "Unexpected non-void return value in void function"
}
}
}
}
}
}
}
}
}
}
return nil
}
я имел мысль, что это может быть возможным, чтобы вернуть затвор с асинхронным кодом блока вместо UIImage, но я не уверен, как это реализовать. И, если бы я это сделал, мне все равно нужно было установить изображение в контроллере представления, и я не уверен, как это сделать.
Вот вызов функции в контроллере представления:
let wikiQuery = WikimediaAPI() // the class from above
fileprivate func setImage() {
if let pageTitle = wikimediaPageTitleDict[(allergy.0).lowercased()] {
if let image = wikiQuery.getThumbnailImage(forPage: pageTitle) {
wikipediaImage.image = image
wikipediaImage.contentMode = .scaleAspectFit
}
}
}
Я использую словарь (wikimediaPageTitleDict) из списка свойств, чтобы связать строку с правой страницы википедии (allergy.0 что строка)
Вся помощь оценивается. Спасибо!
также JSON выше, относится к SwiftyJSON (https: // GitHub.com/SwiftyJSON/SwiftyJSON) –
Просто голова, вы можете связать свои 'if let' в том же состоянии, чтобы избежать пирамиды смерти. – JAL