Структурировать как параметр в функции с Завершение - Swift - PullRequest
0 голосов
/ 04 марта 2019

У меня проблемы, есть возможность установить параметр функции внутри Завершения?В частности, у меня есть 2 структуры, и я хочу, чтобы пользователь выбрал одну из них.Мой код выглядит примерно так:

struct Photo: Decodable {
...
}
//Function
func fetchPhotos(url: String, completion: @escaping ([Photo]?, Error?) -> ()) {
...
}

По сути, я хочу это вместо [Фото]?в Завершение будет параметр, который я могу установить раньше.Это возможно?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

В дополнение к ответу Мохмада S , для реализации fetchPhotos, кажется, что использование перечислений было бы более уместным, потому что в параметре completion мы задаем как "результат ИЛИ ошибка".

Вы можете реализовать что-то вроде:

enum CustomError: Error {
    case notFound
}

enum Result<T> {
    case success(T)
    case failure(CustomError)
}

protocol Switchable: Decodable { }
struct Video: Switchable { }
struct Photo: Switchable { }

Следовательно, fetchPhotos as:

func fetchPhotos(url: String, completion: @escaping (Result<[Switchable]>) -> Void) {
    // in case of error:
    let error: CustomError? = CustomError.notFound
    if let error = error {
        completion(.failure(error))
    }

    // in case of success - videos:
    completion(.success([Video(), Video()]))

    // in case of success - photos:
    completion(.success([Photo(), Photo()]))
}

Называя его как:

fetchPhotos(url: "...") { result in
    switch result {

    case .success(let photos):
        // in case of photos
        if let photos = photos as? [Photo] { /**/ }

        // in case of videos
        if let videos = photos as? [Video] { /**/ }

        // in case of mix of photos and videos, you should iterate through it and check each object
        photos.forEach({ photo in
            if let media = photo as? Photo {

            } else if let media = photo as? Video {

            }
        })

    case .failure(let error):
        print(error.localizedDescription)

    }
}
0 голосов
/ 04 марта 2019

Создайте протокол, подтвердите его на обоих и передайте в качестве аргумента, что вам не важно, какой это тип объекта, вам просто нужно знать, как его использовать, поэтому после завершения вы просто приводите его типвам нужно, проверьте код ниже, я добавил Video struct как ваш второй, так как у вас его нет в вопросе.

protocol Switchable: Decodable {

}

struct Video: Switchable {

}
struct Photo: Switchable {

}
//Function
func fetchPhotos(url: String, completion: @escaping ([Switchable]?, Error?) -> ()) {
     completion([],nil)
}
//Check on the result after completion is called
let v: [Switchable] = [Video(), Video()]

if let photos = v as? [Photo] {
    print("its photos", photos)
}
if let videos = v as? [Video] {
    print("its videos ",videos)
}
...