Ios 如何将SWIFT函数转换为泛型?

Ios 如何将SWIFT函数转换为泛型?,ios,swift,Ios,Swift,我是Swift的新手,有4种不同的功能,它们可以一起从两个不同的URL下载两个不同的图像 我正在从S3获取预签名URL 因为我下载了两个图像,所以每个图像有两个函数,但这似乎违反了DON'T REPEAT YOURSELF原则,我想让它们更通用,这样我可以编写更少、更简洁的代码 下面是我当前的代码,我将感谢您的帮助 多谢各位 // THESE TWO FUNCS DO THE SAME THING WITH TWO DIFFERENT URLS func downloadIdImage() {

我是Swift的新手,有4种不同的功能,它们可以一起从两个不同的URL下载两个不同的图像

我正在从S3获取预签名URL

因为我下载了两个图像,所以每个图像有两个函数,但这似乎违反了DON'T REPEAT YOURSELF原则,我想让它们更通用,这样我可以编写更少、更简洁的代码

下面是我当前的代码,我将感谢您的帮助

多谢各位

// THESE TWO FUNCS DO THE SAME THING WITH TWO DIFFERENT URLS
 func downloadIdImage() {
        guard let urlString = idUrl else {
            return
        }

        let url = URL(string: urlString)!
        let task = URLSession.shared.dataTask(with: url, completionHandler: 
getIdImageFromResponse(data:response:error:))
        task.resume()
    }
    
    func downloadSelfieImage() {
        guard let urlString = selfieUrl else {
            return
        }

        let url = URL(string: urlString)!
        let task = URLSession.shared.dataTask(with: url, completionHandler: 
getSelfieImageFromResponse(data:response:error:))
        task.resume()
    }
    
// THESE TWO FUNCS DO THE SAME THING WITH TWO RESPONSES....
    func getIdImageFromResponse(data: Data?, response: URLResponse?, error: Error?) {
        guard error == nil else {
            print("Error: \(String(describing: error))")
            return
        }
        
        guard let data = data else {
            print("no image data found")
            return
        }
        
        DispatchQueue.main.async {
            guard let loadedImage = UIImage(data: data) else {
                return
            }
            
            self.idImage = loadedImage
        }
    }
    
    func getSelfieImageFromResponse(data: Data?, response: URLResponse?, error: Error?) {
        guard error == nil else {
            print("Error: \(String(describing: error))")
            return
        }
        
        guard let data = data else {
            print("no image data found")
            return
        }
        
        DispatchQueue.main.async {
            guard let loadedImage = UIImage(data: data) else {
                return
            }
            
            self.selfieImage = loadedImage
        }
    }


让我们首先对完成情况进行分解:

func getImageFromResponse(data: Data?, response: URLResponse?, error: Error?) -> UIImage? {
    guard error == nil else {
        print("Error: \(String(describing: error))")
        return nil
    }
    
    guard let data = data else {
        print("no image data found")
        return nil
    }
    
    let loadedImage = UIImage(data: data)
    return loadedImage
}
使用中:

func downloadIdImage() {
    guard let urlString = idUrl else {
        return
    }

    let url = URL(string: urlString)!
    let task = URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in 
        guard let image = getImageFromResponse(data: data, response: response, error: error) else { return }
        DispatchQueue.main.async { 
            self.idImage = image
        }
    })
    task.resume()
}

func downloadSelfieImage() {
    guard let urlString = selfieUrl else {
        return
    }

    let url = URL(string: urlString)!
    let task = URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in 
        guard let image = getImageFromResponse(data: data, response: response, error: error) else { return }
        DispatchQueue.main.async { 
            self.selfieImage = image
        }
    })
    task.resume()
}
func downloadIdImage() {
    download(image at: idUrl, completion: { image in
        //Do you need to check if nil or not?
        self.idImage = image 
    })
}

func downloadSelfieImage() {
    download(image at: selfieUrl, completion: { image in
        //Do you need to check if nil or not?
        self.selfieImage = image 
    })
}
这是第一步

现在:

使用中:

func downloadIdImage() {
    guard let urlString = idUrl else {
        return
    }

    let url = URL(string: urlString)!
    let task = URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in 
        guard let image = getImageFromResponse(data: data, response: response, error: error) else { return }
        DispatchQueue.main.async { 
            self.idImage = image
        }
    })
    task.resume()
}

func downloadSelfieImage() {
    guard let urlString = selfieUrl else {
        return
    }

    let url = URL(string: urlString)!
    let task = URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in 
        guard let image = getImageFromResponse(data: data, response: response, error: error) else { return }
        DispatchQueue.main.async { 
            self.selfieImage = image
        }
    })
    task.resume()
}
func downloadIdImage() {
    download(image at: idUrl, completion: { image in
        //Do you need to check if nil or not?
        self.idImage = image 
    })
}

func downloadSelfieImage() {
    download(image at: selfieUrl, completion: { image in
        //Do you need to check if nil or not?
        self.selfieImage = image 
    })
}
现在,让我们避免原力展开

guard let urlString = at else { completion(nil); return }
let url = URL(string: urlString)!
应该是:

guard let urlString = at, let url = URL(string, urlString) else { completion(nil); return }

您不需要泛型,只需使用一个参数即可。只需创建一个函数downloadImage(url:String?),对于后两个函数,您可以使函数返回可选的imageLet’s not use generic(这是一个特定的术语,有其含义),但可能会使用因式分解。。。我想这就是你想要的。