最近項(xiàng)目遇到webp在wkwebview上不顯示的問(wèn)題,眾所周知,safari瀏覽器是不支持webp格式的圖片的。
那要顯示在ios的webview上顯示webp格式,要如何做呢?
查閱了很多資料,集眾家之所長(zhǎng),以下使用SDWebImage重新定向webp圖片的數(shù)據(jù)源,有不足之處,還望多多指教。
首先,使用cocopods引入兩個(gè)第三方庫(kù),
libwebp是用c寫(xiě)的一個(gè)webp相關(guān)的功能庫(kù)
SDWebImage默認(rèn)是不會(huì)加入WebP的庫(kù)的,需要手動(dòng)添加webP的路徑
? pod'libwebp','0.5.1'
? pod'SDWebImage/WebP'
然后,在初始化你的wkweview之后,需要給NSURLProtocol注冊(cè)一個(gè)自定義的類(lèi)
?[NSURLProtocol registerClass:[WebPURLProtocol class]];
最后一步,就是重寫(xiě)NSURLProtocol其中的方法了
#import "WebPURLProtocol.h"
#import?<SDWebImage/UIImage+WebP.h>
#import?<SDWebImage/SDWebImageManager.h>
NSString*constkWebPprefix =@"webp";
@interface WebPURLProtocol()
@property (nonatomic , strong) id <SDWebImageOperation> downOperation;
@end
@implementationWebPURLProtocol
//該方法返回YES則表示 需要進(jìn)行處理,返回NO,則 不做任何處理
+ (BOOL)canInitWithRequest:(NSURLRequest*)request {
? ?//此處由于我使用了又拍云的網(wǎng)址進(jìn)行測(cè)試,由于webp的圖片格式都會(huì)以webp作為結(jié)尾,因此需要屏蔽又拍云的官網(wǎng)
? ? if([request.URL.absoluteStringhasSuffix:kWebPprefix]&&![request.URL.absoluteStringisEqualToString:@"https://www.upyun.com/webp"]) {
? ? ? ? //如果是webp自定義協(xié)議,則不需要過(guò)濾
? ? ? ? if([NSURLProtocolpropertyForKey:@"URLProtocolHandleKey"inRequest:request]) {
? ? ? ? ? ? returnNO;
? ? ? ? }
? ? ? ? returnYES;
? ? }
? ? return NO;
}
//這倆方法沒(méi)有變化,可以不重寫(xiě)
+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request {
? ? return?request;
}
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest*)a toRequest:(NSURLRequest*)b {
? ? return [super requestIsCacheEquivalent:a toRequest:b];
}//該方法中對(duì)webp圖片進(jìn)行相應(yīng)的處理
- (void)startLoading {
? ? // 重定向請(qǐng)求
? ? NSMutableURLRequest*mRequest = [[self?request]mutableCopy];
//? ? [NSURLProtocol setProperty:@YES forKey:@"URLProtocolHandledKey" inRequest:mRequest];
? ? self.downOperation= [[SDWebImageManager sharedManager]loadImageWithURL:[self?request].URL options:0 progress:nil?completed:^(UIImage*_Nullable?image,NSData*_Nullable?data,NSError*_Nullable?error,SDImageCacheType cacheType,BOOL?finished,NSURL*_Nullable?imageURL) {
? ? ? ? ? //攔截webp, 將webp格式轉(zhuǎn)為data數(shù)據(jù)進(jìn)行重定向加載
? ? ? ? // 通知 client 收到響應(yīng)
? ? ? ? NSURLResponse *response = [[NSURLResponse alloc] initWithURL:mRequest.URL MIMEType:@"image/jpeg" expectedContentLength:data.length textEncodingName:nil];
? ? ? ? [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
? ? ? ? // 通知 client 已經(jīng)加載完數(shù)據(jù)
? ? ? ? [self.client URLProtocol:self didLoadData:UIImageJPEGRepresentation(image, 1.0f)];
? ? ? ? // 通知 client 請(qǐng)求完成, 成功或者失敗的處理
? ? ? ? if(!error) {
? ? ? ? ? ? //成功
? ? ? ? ? ? [self.client URLProtocolDidFinishLoading:self];
? ? ? ? }else{
? ? ? ? ? ? //失敗
? ? ? ? ? ? [self.client URLProtocol:self didFailWithError:error];
? ? ? ? }
? ? }];
}
- (void)stopLoading {
? ? // 終止任務(wù)
? ? if ([self.downOperation conformsToProtocol:@protocol(SDWebImageOperation)]) {
? ? ? ? [self.downOperationcancel];
? ? }
}
至此,就完成了wkweview在webp無(wú)法顯示的問(wèn)題
測(cè)試地址:https://www.upyun.com/webp
補(bǔ)充:
有很多小伙伴經(jīng)常會(huì)看到類(lèi)似以下兩行代碼,將http和https注冊(cè)到NSURLProtocol的白名單。分類(lèi)的源碼:NSURLProtocol的分類(lèi)
[NSURLProtocol wk_registerScheme:@"http"];
[NSURLProtocol wk_registerScheme:@"https"];
但是,經(jīng)過(guò)我的測(cè)試考證,我在項(xiàng)目中加入這兩行代碼后,如果項(xiàng)目中是以列表的形式出現(xiàn)webp,那么,列表會(huì)無(wú)限重復(fù)第一個(gè)數(shù)據(jù),目前我仍然雖不明,卻覺(jué)厲。因此,我在項(xiàng)目中并沒(méi)有加上這兩行。如果有大神能給予解釋?zhuān)笾坏谩?/p>
如果有遇到問(wèn)題的小伙伴,我們可以一起討論,謝謝!