Игнорировать параметры запроса с SDWebImage

Я использую SDWebImage для кэширования изображений в своем приложении, однако недавно столкнулся с проблемой, когда изображения, которые должны кэшироваться, продолжают обновляться. Изучив его, я обнаружил, что полный URL-адрес изображения из AWS на самом деле меняется из-за параметров, добавленных в конец URL-адреса. Каждый раз, когда я извлекаю объект, содержащий URL-адрес изображения, URL-адрес изображения возвращается с динамическим параметром «подпись» и «срок действия» (в целях безопасности). Другой URL-адрес в отношении кеша изображения, но обратите внимание на тот же путь к изображению.

Первая добыча:

https://myapp.s3.amazonaws.com/path/image123.jpeg?AWSAccessKeyId=SOMEKEY&Signature=vrUFlMFEQ9fqQ%3D&Expires=1441702633

Получить снова через 1 секунду:

https://myapp.s3.amazonaws.com/path/image123.jpeg?AWSAccessKeyId=SOMEKEY&Signature=2mcMxUJLyJd7E%3D&Expires=1441703105

Как лучше всего поступить в этой ситуации? Конечно, было бы здорово, если бы у SDWebImage была возможность игнорировать параметры запроса, кроме пути к файлу.


person Kyle Clegg    schedule 08.09.2014    source источник


Ответы (5)


В SDWebImage есть метод, который позволяет использовать пользовательский ключ, который помогает в этом случае, поскольку AWS изменяет запрос каждый раз, когда он вызывается.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary    *)launchOptions
{
    SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) {
        url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
        return [url absoluteString];
    };

    // Your app init code...
    return YES;
}

Дополнительные сведения: SDWebImage | Использование фильтра ключей кеша

person John    schedule 09.09.2014

Ответ @John очень хорош, но иногда я встречал сбои.

ниже более стабильная версия.

SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) {
    if( [[url absoluteString] isEqualToString:@""] ){
        return @"";
    }
    url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
    return [url absoluteString];
};

Этот дополнительный код проверяет правильность URL-адреса. [[NSURL alloc] initWithString:@""] или что-то подобное вызывает сбои.

person Satoshi Suzuki    schedule 29.05.2015
comment
Не могли бы вы объяснить свой ответ, даже если он будет объяснять вещи, аналогичные другому ответу, полезно, чтобы ваш ответ объяснял опубликованный вами код. - person SuperBiasedMan; 29.05.2015
comment
@SuperBiasedMan [[NSURL alloc] initWithString:@""] или что-то в этом роде привело к сбою кода @John. - person Satoshi Suzuki; 01.06.2015
comment
Хороший улов @SatoshiSuzuki. - person John; 09.11.2015

Ответ для языка Swift:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    ...............

    SDWebImageManager.sharedManager().cacheKeyFilter = { url in
        if url.absoluteString == "" {
            return ""
        }

        let newUrl = NSURL(scheme: url.scheme, host: url.host, path: url.path!)!
        return newUrl.absoluteString
    }

    return true
}
person t4nhpt    schedule 23.11.2015

[NSURL initWithScheme: host: path:] устарело в iOS10. вместо этого следует использовать NSURLComponents.

мое обновленное решение:

SDWebImageManager.sharedManager.cacheKeyFilter = ^NSString *(NSURL *url) {
     if([[url absoluteString] isEqualToString:@""]){
        return @"";
    }
    NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO];
    urlComponents.query = nil;
    return [[urlComponents URL] absoluteString];
};
person superwave    schedule 27.02.2018

iOS 14 || Свифт 5

SDWebImageManager.shared.cacheKeyFilter = SDWebImageCacheKeyFilter { url in
    var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
    components?.query = nil

    print("SDWebImage Cache Key:", components?.url)

    return components?.url?.absoluteString ?? ""
}

Поэтому настройте SDWebImageManager при запуске, а затем всякий раз, когда будет предоставлен url, он будет лишен всех своих параметров запроса, чтобы сгенерировать общий идентификатор ключа кэша для логики кэша SDWebImage, чтобы снова работать правильно.

Итак, что-то вроде:

https://bucket.s3.us-east-1.amazonaws.com/public/someAsset.ext?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=TILT&X-Amz-Date=20210602T113954Z&X-Amz-Expires=17999&X-Amz-SignedHeaders=host&X-Amz-Security-Token=TILT&X-Amz-Signature=TILT

будет иметь ключ кеша:

https://bucket.s3.us-east-1.amazonaws.com/public/someAsset.ext


ПРИМЕЧАНИЕ. Обратите внимание на конечный URL. Если URL-адрес зависит от параметров запроса для динамического вывода, то, очевидно, вам потребуется изменить логику в SDWebImageCacheKeyFilter, чтобы она соответствовала вашим требованиям.

person staticVoidMan    schedule 02.06.2021