我遇到了麻烦,是否有可能在Completion内部设置函数的参数?具体来说,我有2个结构,我希望用户选择其中之一。我的代码是这样的:
struct Photo: Decodable {
...
}
//Function
func fetchPhotos(url: String, completion: @escaping ([Photo]?, Error?) -> ()) {
...
}
基本上我想要代替[Photo]吗?在“完成”中,将有我可以设置的参数。这可能吗?
谢谢!
答案 0 :(得分:3)
创建一个协议,并在两个协议上进行确认,然后将其作为参数传递,您不在乎对象是什么类型,您只需要知道如何使用它,这就是为什么在完成后仅将其类型转换为您需要检查以下代码,由于您没有问题,我添加了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)
}
答案 1 :(得分:0)
除了Mohmmad S answer之外,对于实现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
为:
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)
}
}