我想增强下面的代码来缓存图片,只有在以前没有缓存它们时才下载它们。我似乎无法找到如何使用URLSession对象执行此操作的任何好例子。
extension UIImageView {
func loadImageWithURL(_ url: URL) -> URLSessionDownloadTask {
let session = URLSession.shared
let downloadTask = session.downloadTask(with: url, completionHandler: { [weak self] url, response, error in
if error == nil, let url = url,
let data = try? Data(contentsOf: url), let image = UIImage(data: data) {
DispatchQueue.main.async {
if let strongSelf = self {
strongSelf.image = image
}
}
}
})
downloadTask.resume()
return downloadTask
}
}
答案 0 :(得分:8)
更新了Swift 4
import requests
from lxml import html
import urllib2
from bs4 import BeautifulSoup
import unicodecsv as csv
import os
import sys
import io
import time
import datetime
import pandas as pd
import MySQLdb
import mechanize
import cookielib
url = 'URL THE WEBSITE'
values = {
'user': 'XXX',
'password': 'YYY',
'recaptcha-token': '03AOPBWq-Ltv5Op-YqU9WsKmE0qtNxr3w-gWwdLMxT4P1ri4j-P1IntWIGT6qRKcouZZr2hmuMPq7HPUL3NUV49gYSIfpnfunppH4tP9EjJO70tUpTaoRO1TkiPvDo8G6fmXaceEu6wMQINpG1-n_Xrp4CllvxcADrLhfmfEMTDmj7TLP-oLLBjFFT3MeMQdcQTndlQ4Kdv9gSTEgQPEl1ljaj1-wVg3zZ9msebL8aLH0Q4yC76AMhsOt4SXpwbliUbcvElWzxvV_uCSXs0jfenPbYYd9vxuy23aOL2kEcISpxsWn_rirDqd66JasBeqtMwTB7XCx_-_hlZlNGluqb4ARXThB7BDq7saKyPRW_TWG2L146qQKl6i9j59bvTE8qdzVMbqhkCboBSP3zTCj-pHkaG2gCrOlRTAVq2IxDNzIP8x0M4hLa8Ho'}
session = requests.Session()
r = session.post(url, data=values)
params = {'Category': 6, 'deltreeid': 6, 'do': 'Delete Tree'}
url = 'URL THE WEBSITE WHERE I WANT FIND THE RELEVANT INFORMATIONS'
result = session.get(url, data=params)
soup = BeautifulSoup(result.text, "lxml")
print soup
<强>用法:强>
import UIKit
let imageCache = NSCache<AnyObject, AnyObject>()
class ImageLoader: UIImageView {
var imageURL: URL?
let activityIndicator = UIActivityIndicatorView()
func loadImageWithUrl(_ url: URL) {
// setup activityIndicator...
activityIndicator.color = .darkGray
addSubview(activityIndicator)
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
activityIndicator.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
activityIndicator.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
imageURL = url
image = nil
activityIndicator.startAnimating()
// retrieves image if already available in cache
if let imageFromCache = imageCache.object(forKey: url as AnyObject) as? UIImage {
self.image = imageFromCache
activityIndicator.stopAnimating()
return
}
// image does not available in cache.. so retrieving it from url...
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
if error != nil {
print(error as Any)
DispatchQueue.main.async(execute: {
self.activityIndicator.stopAnimating()
})
return
}
DispatchQueue.main.async(execute: {
if let unwrappedData = data, let imageToCache = UIImage(data: unwrappedData) {
if self.imageURL == url {
self.image = imageToCache
}
imageCache.setObject(imageToCache, forKey: url as AnyObject)
}
self.activityIndicator.stopAnimating()
})
}).resume()
}
}
答案 1 :(得分:4)
一个可能的解决方案是利用NSCache
来处理缓存。基本上你要做的就是检查你是否已经在本地加载了图像,而不是每次在实际发出请求之前进行加载。
这是我的一个实现,但它是一个子类而不是扩展:
class CustomImageView: UIImageView {
// MARK: - Constants
let imageCache = NSCache<NSString, AnyObject>()
// MARK: - Properties
var imageURLString: String?
func downloadImageFrom(urlString: String, imageMode: UIViewContentMode) {
guard let url = URL(string: urlString) else { return }
downloadImageFrom(url: url, imageMode: imageMode)
}
func downloadImageFrom(url: URL, imageMode: UIViewContentMode) {
contentMode = imageMode
if let cachedImage = imageCache.object(forKey: url.absoluteString as NSString) as? UIImage {
self.image = cachedImage
} else {
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else { return }
DispatchQueue.main.async {
let imageToCache = UIImage(data: data)
self.imageCache.setObject(imageToCache!, forKey: url.absoluteString as NSString)
self.image = imageToCache
}
}.resume()
}
}
}
此外,这是一个有用的资源: https://www.hackingwithswift.com/example-code/system/how-to-cache-data-using-nscache
答案 2 :(得分:0)
let imageCache = NSCache<AnyObject, AnyObject>()
extension UIImageView {
func loadImageFromUrl(urlString: String) {
if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage{
self.image = imageFromCache
return
}
Alamofire.request(urlString, method: .get).response { (responseData) in
if let data = responseData.data {
DispatchQueue.main.async {
if let imageToCache = UIImage(data: data){
imageCache.setObject(imageToCache, forKey: urlString as AnyObject)
self.image = imageToCache
}
}
}
}
}
}
答案 3 :(得分:0)
URLSession DataTask 默认会自动缓存图片,客户端不需要做任何事情,只要服务器端的缓存设置正常即可。图片是静态资源,短时间内不会改变,因此服务器通常会将“Cache-Control”设置为“public, max-age:xxxxx”。 URLSession 默认缓存策略将在内存和磁盘中缓存图像。但是,它不会缓存大于为 URLCache 分配的磁盘大小的 5% 的图像,也不会在后台线程中进行缓存。