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

背景介绍:
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。。。问题得以解决!

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

作者流浪

查看文章

时间: 2024-10-28 09:27:46

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

android网络获取图片并保存在本地

获取网络上的图片有三步: 一.设置连接网络的权限和写入读取SD卡的权限.二.网络访问获得数据流. 三.在SD卡中创建文件夹将数据流转成图片格式存储. 注意:response.getEntity().getContent()方法,而此方法只能调用一次.否则会报错:java.lang.IllegalStateException: Content has been consumed. manifest.xml 赋予权限,注意:在<application...>application>前添加 &

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

原文地址   本文内容 环境 演示 LazyList 从网络获取图片并缓存 参考资料 本文是 Github 上的一个演示,通过网络获取歌手专辑的缩略图,并显示在 ListView 控件中.该演示具备将缩略图缓存到手机外存的功能,所以叫"Lazy",这样就不用每次都通过网络重新获取. 该演示仅仅是获得缩略图,但在另一篇文章中,作者根据这个 LazyList,做了一个相对完整的演示(包括歌曲名称.歌手名.时长.缩略图等信息),如图 3 所示. 环境 Windows 2008 R2 64 位

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

iOS启动图和开屏广告图,类似网易 启动图是在iOS开发过程中必不可少的一个部分,很多app在启动图之后会有一张自定义的开屏广告图,点击该广告图可以跳转到广告图对应的页面.今天呢,和大家分享一下如何添加这张广告图以及点击广告图的跳转.这个广告图是通过将UIImageView添加到UIWindow上实现的. 一.添加本地启动图 1.准备好本地图片 2.找到工程中的Images.xcassets文件,打开LaunchImage,将图片拖到对应的地方,如下图: 3.将LaunchScreen.stor

[转]IOS启动图以及应用图标

设置应用程序图标和引导画面 一个好的应用程序图标,不仅会给用户留下良好的第一印象,而且可以帮助用户在茫茫多的桌面图标中,快速发现你的应用程序.本文将介绍如何把已经设计好的图标以及启动图片添加到我们的应用程序. 大纲 图标的规格及说明: 启动图片规格及说明: 添加素材演练: 设定启动图片显示时间. 一. 图标规格及说明 iOS中图标的名称及规格见下表: 序号 文件名 规格 说明 备注 1 iTunesArtwork 512 * 512 发布到App Store时使用 可选 2 Icon.png 5

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

本文内容 环境 项目结构 演示1:SimpleAdapter 演示2:BaseAdapter 演示3:customlazylist 演示4:customcompletelazylist 本文只给出演示概要,代码太多,贴出来意义不大,自己下载调试一下,点击此处下载. 本文通过四个示例,循序渐进地演示,将歌曲列表加载到 ListView 控件,歌曲列表,包括缩略图.歌手名.歌曲名等信息,或存放在本地,或以 JSON 形式存放在网络. 环境 Windows 2008 R2 64 位 Eclipse A

如何实现从网络获取图片的缓存机制

前言 在iOS开发中从网络加载图片是一个比较值得思考的问题,因为你要考虑用户的体验,这其实包括流畅度,以及用户的流量考虑,那么今天我就来简单的说点这方面知识. 具体实现: 说到缓存就可以分为内存缓存和沙盒缓存,内存缓存的话就是用简单的用一个字典来记录下载的图片. 今天的环境就是从网络下载一些图片给tableview的imageView的image赋值,SAMApp是模型类,icon是url. 1.定义几个属性,具体如下 /** 所有数据 */ @property (nonatomic, stro

iOS开发项目篇—34获取用户信息

iOS开发项目篇—34获取用户信息 一.简单说明 需求:获取当前用户的昵称 ,需要获取当前登录用户的个人信息. 查看接口 要求传递的参数 这里要获取的时用户的昵称(所以使用用户id作为参数传入) 二.实现代码 1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 5 //设置导航栏内容 6 [self setupNavBar]; 7 8 //集成刷新控件 9 [self setupRefresh]; 10 11 //设置用户的昵称为标题 12 [s

salt未持久化保存导致应用启动时候的网络请求失败(没有权限)

@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/css/cuteeditor.css); 获取位置--请求列表--发现没有权限 原因就是salt还没有获取 @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/c

iOS开发项目篇—39获取用户未读的微博信息(信息提醒)

iOS开发项目篇—39获取用户未读的微博信息(信息提醒) 一.简单说明 1.实现效果       2.实现 (1)新建一个类,封装请求 查看新浪官方要求的请求参数 该类中的代码设计 YYUnreadCountParam.h文件 1 // YYUnreadCountParam.h 2 //封装请求参数的类 3 4 #import "YYBaseParam.h" 5 6 @interface YYUnreadCountParam : YYBaseParam 7 /**uid true in