经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
iOS下载图片失败
来源:cnblogs  作者:菁欣  时间:2018/9/25 19:59:35  对本文有异议

一、具体问题  

  开发的过程中,发现某个界面部分图片的显示出现了问题只显示占位图片,取出图片的url在浏览器却是能打开的,各种尝试甚至找同行的朋友帮忙在他们项目里展示都会存在问题,最终发现通过第三方框架SDWebImage或者YYWebImage下载带有逗号的url图片链接都会下载失败,在下载方法完成的回调block里面打印信息如下:

  1. Error Domain=NSURLErrorDomain Code=403 "(null)"

  现列举两个不能正常展示的图片url:

  1. http://img1.imgtn.bdimg.com/it/u=3044191397,2911599132&fm=27&gp=0.jpg
  2. http://img2.imgtn.bdimg.com/it/u=3509004173,840437551&fm=27&gp=0.jpg

  有兴趣的小伙伴可以拿到自己的项目里试试

二、问题原因

  网上有小伙伴提出是因为缺少User-Agent用户代理导致的。只有设置了用户代理,才能访问到这张带有逗号的url图片。至于这个用户代理的格式,只要有值或者约定的特定格式字符串都可以。

三、具体解决

1.第三方框架YYWebImage

  找到YYWebImageManager.m文件,定位到设置http请求头的属性即_headers的地方,加入一个User-Agent的键值对,具体改动可以看下面的方法

  1. - (instancetype)initWithCache:(YYImageCache *)cache queue:(NSOperationQueue *)queue{
  2. self = [super init];
  3. if (!self) return nil;
  4. _cache = cache;
  5. _queue = queue;
  6. _timeout = 15.0;
  7. NSString *userAgent = @"";
  8. userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
  9. if (userAgent) {
  10. if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
  11. NSMutableString *mutableUserAgent = [userAgent mutableCopy];
  12. if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) {
  13. userAgent = mutableUserAgent;
  14. }
  15. }
  16. }
  17. //带有逗号的图片url不显示的问题,重要的是设置代理才能解决
  18. if (YYImageWebPAvailable()) {
  19. _headers = @{ @"Accept" : @"image/webp,image/*;q=0.8", @"User-Agent" : userAgent};
  20. } else {
  21. _headers = @{ @"Accept" : @"image/*;q=0.8", @"User-Agent" : userAgent};
  22. }
  23. return self;
  24. }

2.第三方框架SDWebImage

  找到SDWebImageDownloader.m文件,也是定位到设置http请求头的属性即_HTTPHeaders的地方,加入一个User-Agent的键值对,具体改动可以看下面的方法

  1. - (id)init {
  2. if ((self = [super init])) {
  3. _operationClass = [SDWebImageDownloaderOperation class];
  4. _shouldDecompressImages = YES;
  5. _executionOrder = SDWebImageDownloaderFIFOExecutionOrder;
  6. _downloadQueue = [NSOperationQueue new];
  7. _downloadQueue.maxConcurrentOperationCount = 6;
  8. _URLCallbacks = [NSMutableDictionary new];
  9. /***********************/
  10. NSString *userAgent = @"";
  11. userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
  12. if (userAgent) {
  13. if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
  14. NSMutableString *mutableUserAgent = [userAgent mutableCopy];
  15. if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) {
  16. userAgent = mutableUserAgent;
  17. }
  18. }
  19. }
  20. /***********************/
  21. #ifdef SD_WEBP
  22. _HTTPHeaders = [@{@"Accept": @"image/webp,image/*;q=0.8", userAgent : @"User-Agent"} mutableCopy];
  23. #else
  24. _HTTPHeaders = [@{@"Accept": @"image/*;q=0.8", userAgent : @"User-Agent"} mutableCopy];
  25. #endif
  26. _barrierQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderBarrierQueue", DISPATCH_QUEUE_CONCURRENT);
  27. _downloadTimeout = 15.0;
  28. }
  29. return self;
  30. }

或者是直接在UIImageView+WebCache.m文件中,在统一下载图片入口最前面添加如下代码

  1. - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
  2. /***********************/
  3. NSString *userAgent = @"";
  4. userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
  5. if (userAgent) {
  6. if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
  7. NSMutableString *mutableUserAgent = [userAgent mutableCopy];
  8. if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) {
  9. userAgent = mutableUserAgent;
  10. }
  11. }
  12. [[SDWebImageDownloader sharedDownloader] setValue:userAgent forHTTPHeaderField:@"User-Agent"];
  13. }
  14. /***********************/
  15. [self sd_cancelCurrentImageLoad];
  16. ........省略原源码
  17. }

3.其他第三方下载图片的框架

  直接全局搜索字符串"Accept",因为虽然缺少设置User-Agent用户代理,但是http请求头一般都会有设置"Accept",所以定位后,直接再加一个User-Agent的键值对就可以了

 

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号