背景介绍:
APP启动页,常有静态图加链接,gif加链接,短视频等几种形式。
我们APP前期只有静态图这一种,功能已经实现。
之后,有了添加gif的需求,按理说,只要添加一个类型判断,按照数据类型,通过不同方法展示内容即可,但是一直不可以。。
出了这样的问题,下好的gif图,内容类型没错但是通过对应的gif方法显示的内容一直是一张静态图,并且还是模糊的。
因为之前的下载图片,以及显示图片的逻辑完全没问题,所以定位问题在显示gif的方法上,所以走了弯路,但是这条弯路是必然要走的。

下面开始我们的星辰大海,我们的目标是终结问题
先看源码--原来的代码

/**
* 下载新的图片
*/
+ (void)downloadAdImageWithUrl:(NSString *)imageUrl imageName:(NSString *)imageName imgLinkUrl:(NSString *)imgLinkUrl imgDeadline:(NSString *)imgDeadline imgStartline:(NSString *)imgstartline
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:data]; NSString *filePath = [self getFilePathWithImageName:imageName]; // 保存文件的名称
[UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES];
if ([UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES]) { // 保存成功
//判断保存下来的图片名字和本地沙盒中存在的图片是否一致,如果不一致,说明图片有更新,此时先删除沙盒中的旧图片,如果一致说明是删除缓存后再次下载,这时不需要进行删除操作,否则找不到已保存的图片
if (![imageName isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:adImageName] ]) {
[self deleteOldImage];
} [[NSUserDefaults standardUserDefaults] setValue:imageName forKey:adImageName];
[[NSUserDefaults standardUserDefaults] setValue:imageUrl forKey:adUrl];
[[NSUserDefaults standardUserDefaults] setValue:imgDeadline forKey:adDeadline];
[[NSUserDefaults standardUserDefaults] setValue:imgstartline forKey:adstartline];
//保存图片
// [[NSUserDefaults standardUserDefaults] setValue:@"" forKey:@"Deadline"];
// [[NSUserDefaults standardUserDefaults] setValue:@"" forKey:@"startline"];
[[NSUserDefaults standardUserDefaults] synchronize];//立即写入 }else{
NSLog(@"保存失败");
} });
}
/**
* 通过在沙盒路径,获取gif图
*/
-(void)setImgFilePath:(NSString *)imgFilePath{
_imgFilePath = imgFilePath;
if ([_imgFilePath hasSuffix:@"gif"]) {
_adImageView.image = [UIImage sd_animatedGIFWithData:[NSData dataWithContentsOfFile:imgFilePath]];
}else{
_adImageView.image = [UIImage imageWithContentsOfFile:_imgFilePath];
} }

以上两个方法一个实现下载,一个实现显示,起初只有一张图片做启动图的时候,这种写法勉强用,虽然走了弯路,但是不会影响实现效果
但是新需求是需要加载gif,或许以后还有小视频

问题出来了
 gif一直下载不下来,起初修改了方法,毕竟gif有3M不小,所以换了下载方法,如下

/**
* 这个方法,下图片还行,你要是下载个大点的gif那就不合适了
*/
   NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:data];

那就改成下边的下载方法,适合稍大一点的文件下载

[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]]
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) { } else { }
}];

但是下载解决了问题后,发现还不能正常显示,但是项目中其他地方是没问题的啊,所以一直纠结于下面这个赋图的方法,其实是完全没问题的,只是能数据就不对了

 _adImageView.image = [UIImage sd_animatedGIFWithData:[NSData dataWithContentsOfFile:imgFilePath]];

读取数据没问题,只能是存数据的时候不对了

这个时候注意到,问题所在
 原因是下载的图片资源没有直接保存到某个路径下,而是先转成图片,然后图片转data保存了,多此一举了,重要的是,gif图的话,就把原来的资源都改变了,用的时候,获取的资源自然就出问题了,我们看代码

        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:data]; NSString *filePath = [self getFilePathWithImageName:imageName]; // 保存文件的名称
[UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES];
if ([UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES]){}

这是下载图片方法中的存储功能代码:获取data,转image,image写成data保存。我们可以看到多了一步,可能图片的时候,虽然多转换一步,图片资源没有改变,但是gif图用[UIImageJPEGRepresentation(image, 0) writeToFile:filePath atomically:YES];这个方法数据资源就改变了。所以导致图片虽然没问题,但是gif就不行了!

这儿其实不管他是何种类型资源直接保存data就好了。

下面是修改后的代码

+ (void)downloadAdImageWithUrl:(NSString *)imageUrl imageName:(NSString *)imageName imgLinkUrl:(NSString *)imgLinkUrl imgDeadline:(NSString *)imgDeadline imgStartline:(NSString *)imgstartline
{ [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]]
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) { NSString *filePath = [self getFilePathWithImageName:imageName]; // 保存文件的名称 //图片data直接存储,不需要转image然后再转data
if ([data writeToFile:filePath atomically:YES]) { // 保存成功
//判断保存下来的图片名字和本地沙盒中存在的图片是否一致,如果不一致,说明图片有更新,此时先删除沙盒中的旧图片,如果一致说明是删除缓存后再次下载,这时不需要进行删除操作,否则找不到已保存的图片
if (![imageName isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:adImageName] ]) {
[self deleteOldImage];
} [[NSUserDefaults standardUserDefaults] setValue:imageName forKey:adImageName];
[[NSUserDefaults standardUserDefaults] setValue:imageUrl forKey:adUrl];
[[NSUserDefaults standardUserDefaults] setValue:imgDeadline forKey:adDeadline];
[[NSUserDefaults standardUserDefaults] setValue:imgstartline forKey:adstartline];
//保存图片
// [[NSUserDefaults standardUserDefaults] setValue:@"" forKey:@"Deadline"];
// [[NSUserDefaults standardUserDefaults] setValue:@"" forKey:@"startline"];
[[NSUserDefaults standardUserDefaults] synchronize];//立即写入 }else{
NSLog(@"保存失败");
} } else { }
}];
return;
}

测试之后,正常显示gif。。。问题得以解决!

总结,问题往往就在你以为不可能出错的地方!

作者流浪

查看文章

iOS启动图-从网络获取的gif图,在本地一直是没有动画,还模糊的的更多相关文章

  1. Android LazyList 从网络获取图片并缓存

    原演示地址 本文内容 环境 演示 LazyList 从网络获取图片并缓存 参考资料 本文是 Github 上的一个演示,通过网络获取歌手专辑的缩略图,并显示在 ListView 控件中.该演示具备将缩 ...

  2. 用rose画UML图(用例图,活动图)

    用rose画UML图(用例图,活动图) 首先,安装rose2003,电脑从win8升到win10以后,发现win10并不支持rose2003的安装,换了rose2007以后,发现也不可以. 解决途径: ...

  3. iOS启动图和开屏广告图,类似网易

    iOS启动图和开屏广告图,类似网易 启动图是在iOS开发过程中必不可少的一个部分,很多app在启动图之后会有一张自定义的开屏广告图,点击该广告图可以跳转到广告图对应的页面.今天呢,和大家分享一下如何添 ...

  4. iOS最笨的办法实现无限轮播图(网络加载)

    iOS最笨的办法实现无限轮播图(网络加载) 简单的做了一下: 使用方法: 把 请求返回的 图片地址(字符串类型)放进数组中就行 可以使用SDWebImage(我就是用的这个)等..需要自己导入并引用, ...

  5. Android代码优化----PullToRefresh+universal-image-loader实现从网络获取数据并刷新

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  6. 关于iOS开发首次进入需要获取地理位置

    今天给大家简单介绍一下iOS开发过程中会遇到的获取地理位置的问题,(话不多说进入正题)这里给大家讲解一下两种在APPdelegate获取地理位置的方法: 一:首先是用系统的方法获取地理位置: 1. 首 ...

  7. Android & iOS 启动画面工具

    感谢Aone!为我们开发了如此便捷的工具!! 以下为原文:  Android & iOS 启动画面工具 下载:OneSplash.启动画面工具.Aone.20190318.zip 说明:这一个 ...

  8. Android ListView 和 ***Adapter 从本地/网络获取歌曲列表

    本文内容 环境 项目结构 测试数据 演示 1:SimpleAdapter 演示 2:BaseAdapter 演示 3:CustomLazyList 演示 4:CustomLazyCompleteLis ...

  9. Android Volley 库通过网络获取 JSON 数据

    本文内容 什么是 Volley 库 Volley 能做什么 Volley 架构 环境 演示 Volley 库通过网络获取 JSON 数据 参考资料 Android 关于网络操作一般都会介绍 HttpC ...

随机推荐

  1. 使用ActionBarActivity或者RxAppCompatActivity或者AppCompatActivity闪退的问题

    新建一个项目,Activity继承RxAppCompatActivity的时候,在页面跳转的时候会出现闪退的问题,一直都没有解决. 后面将两个父类全部改成activity,问题解决.但是有的时候必须使 ...

  2. Three.js使用局部纹理更新

    THREE.js开发的应用运行在iphone5下发现有些时候会崩溃,跟了几天发现是因为Sprite太多频繁更新纹理占用显存导致的.通常解决纹理频繁更新问题就要用到one draw all方法,放到纹理 ...

  3. Python下的OpenCV学习 02 —— 图像的读取与保存

    OpenCV提供了众多对图片操作的函数,其中最基本的就是图片的读取与输出了. 一.读取图片 利用OpenCV读取一张图片是非常容易的,只需要用到 imread() 函数,打开shell或者cmd,进入 ...

  4. 用Redis作为缓存服务器,加快数据库操作速度

    https://zh.wikipedia.org/wiki/Redis http://www.jianshu.com/p/01b37cdb3f33

  5. 【Maven】项目中没有resources目录

    在eclipse中创建maven项目,src/main/只有java没有resources目录 解决办法: 1.项目右键properties 2.Java Build Path 中移除JRE Syst ...

  6. 从 HTTP 到 HTTPS 再到 HSTS

    近些年,随着域名劫持.信息泄漏等网络安全事件的频繁发生,网站安全也变得越来越重要,也促成了网络传输协议从 HTTP 到 HTTPS 再到 HSTS 的转变. HTTP HTTP(超文本传输协议) 是一 ...

  7. 【JBoss】Linux下JBoss服务器"Too many open files"的解决方法

    linux中,每个socket连接都使用文件描述符进行标识,文件描述符属于系统资源,存在使用上的限制:缺省情况下JBoss能使用的最大描述符数是系统默认的最大文件描述符数(通过命令ulimit -H ...

  8. 九天学会Java,第三天,选择结构

    选择结构 变量和数据类型,赋值和输出 算术运算 选择结构 循环结构 函数定义,函数调用 变量作用域 栈,程序运行的基石 面向对象 异常处理 语言提供的公用包 上一节介绍了Java的算术运算,如加减乘除 ...

  9. HTML图像

    HTML 图像- 图像标签( <img>)和源属性(Src) 在 HTML 中,图像由<img> 标签定义. <img> 是空标签,意思是说,它只包含属性,并且没有 ...

  10. CSS-三栏响应式布局(左右固宽,中间自适应)的五种方法

    代码: <!-- 1 float --> <h3 class="block">第一种方法-float</h3> <div class=&q ...