WiFi时,显示图片高清图;网络状态为蜂窝移动网络时,显示图片缩略图http://gold.xitu.io/entry/57285c5e2e958a0068db2f9e
2016-07-06 21:47
633 查看
原文地址
由于要监听网络状态,在这里笔者推荐使用AFNetWorking。
1)在GitHub或者利用cocoaPod给项目导入第三方框架AFNetWorking。
2)在AppDelegate.m文件中的application:didFinishLaunchingWithOptions:方法中监听网络状态。
// AppDelegate.m 文件中- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 监控网络状态 [[AFNetworkReachabilityManager sharedManager] startMonitoring];}// 以下代码在需要监听网络状态的方法中使用AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]; if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图 } else { // 其他,下载小图 } }
这时就会有iOS学习者开始抱怨:这不是很简单吗?于是三下五除二写完了以下代码。
// 利用MVC,在设置cell的模型属性时候,下载图片- setItem:(CustomItem *)item{ _item = item; UIImage *placeholder = [UIImage imageNamed:@"placeholderImage"]; AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]; if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder]; } else { // 其他,下载小图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder]; }}
此时,确实能完成基本的按照当前网络状态下载对应的图片,但是真实开发中,这样其实是不合理的。以下是需要注意的细节:
1)SDWebImage会自动帮助开发者缓存图片(包括内存缓存,沙盒缓存),所以我们需要设置用户在WiFi环境下下载的高清图,下次在蜂窝网络状态下打开应用也应显示高清图,而不是去下载缩略图。
2)许多应用设置模块带有一个功能:移动网络环境下仍然显示高清图。这个功能其实是将设置记录在沙盒中,关于数据保存到本地,可以查看本人另一篇简书首页文章:iOS本地数据存取,看这里就够了。
3)当用户处于离线状态时候,无法合理处理业务。
于是,开始加以改进。为了让读者你更容易理解,我先贴出伪代码:
- setItem:(CustomItem *)item{
_item = item;
if (缓存中有原图) {
self.imageView.image = 原图;
} else {
if (Wifi环境) {
下载显示原图
} else if (手机自带网络) {
if (3G\4G环境下仍然下载原图) {
下载显示原图
} else {
下载显示小图 }
} else {
if (缓存中有小图) {
self.imageView.image = 小图;
} else // 处理离线状态 {
self.imageView.image = 占位图片;
}
}
}}
实现上面的伪代码:读者可以一一对应上面的伪代码。练习的时候推荐先写伪代码,再写真实代码
多多注意“注释”解释。
- setItem:(CustomItem *)item{ _item = item; // 占位图片 UIImage *placeholder = [UIImage imageNamed:@"placeholderImage"]; // 从内存\沙盒缓存中获得原图, UIImage *originalImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.originalImage]; if (originalImage) { // 如果内存\沙盒缓存有原图,那么就直接显示原图(不管现在是什么网络状态) self.imageView.image = originalImage; } else { // 内存\沙盒缓存没有原图 AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]; if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder]; } else if (mgr.isReachableViaWWAN) { // 在使用手机自带网络 // 用户的配置项假设利用NSUserDefaults存储到了沙盒中 // [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"alwaysDownloadOriginalImage"]; // [[NSUserDefaults standardUserDefaults] synchronize];#warning 从沙盒中读取用户的配置项:在3G\4G环境是否仍然下载原图 BOOL alwaysDownloadOriginalImage = [[NSUserDefaults standardUserDefaults] boolForKey:@"alwaysDownloadOriginalImage"]; if (alwaysDownloadOriginalImage) { // 下载原图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder]; } else { // 下载小图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder]; } } else { // 没有网络 UIImage *thumbnailImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.thumbnailImage]; if (thumbnailImage) { // 内存\沙盒缓存中有小图 self.imageView.image = thumbnailImage; } else { // 处理离线状态,而且有没有缓存时的情况 self.imageView.image = placeholder; } } }}
真正的处理方法是
说的没错,确实是SDWebImage帮我们下载图片的,我们来扒一扒SDWebImage源码,看看他是怎么完成的。
我们惊奇的发现,原来SDWebImage在下载图片时,第一件事就是关闭imageView当前的下载操作!
是不是开始感叹SDWebImage多么神奇了?没错,我们只需要把我们写的那段代码所有的直接访问本地缓存代码利用SDWebImage进行设置就OK了!
下面就是完成版代码。
由于要监听网络状态,在这里笔者推荐使用AFNetWorking。
1)在GitHub或者利用cocoaPod给项目导入第三方框架AFNetWorking。
2)在AppDelegate.m文件中的application:didFinishLaunchingWithOptions:方法中监听网络状态。
// AppDelegate.m 文件中- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 监控网络状态 [[AFNetworkReachabilityManager sharedManager] startMonitoring];}// 以下代码在需要监听网络状态的方法中使用AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]; if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图 } else { // 其他,下载小图 } }
这时就会有iOS学习者开始抱怨:这不是很简单吗?于是三下五除二写完了以下代码。
// 利用MVC,在设置cell的模型属性时候,下载图片- setItem:(CustomItem *)item{ _item = item; UIImage *placeholder = [UIImage imageNamed:@"placeholderImage"]; AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]; if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder]; } else { // 其他,下载小图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder]; }}
此时,确实能完成基本的按照当前网络状态下载对应的图片,但是真实开发中,这样其实是不合理的。以下是需要注意的细节:
1)SDWebImage会自动帮助开发者缓存图片(包括内存缓存,沙盒缓存),所以我们需要设置用户在WiFi环境下下载的高清图,下次在蜂窝网络状态下打开应用也应显示高清图,而不是去下载缩略图。
2)许多应用设置模块带有一个功能:移动网络环境下仍然显示高清图。这个功能其实是将设置记录在沙盒中,关于数据保存到本地,可以查看本人另一篇简书首页文章:iOS本地数据存取,看这里就够了。
3)当用户处于离线状态时候,无法合理处理业务。
于是,开始加以改进。为了让读者你更容易理解,我先贴出伪代码:
- setItem:(CustomItem *)item{
_item = item;
if (缓存中有原图) {
self.imageView.image = 原图;
} else {
if (Wifi环境) {
下载显示原图
} else if (手机自带网络) {
if (3G\4G环境下仍然下载原图) {
下载显示原图
} else {
下载显示小图 }
} else {
if (缓存中有小图) {
self.imageView.image = 小图;
} else // 处理离线状态 {
self.imageView.image = 占位图片;
}
}
}}
实现上面的伪代码:读者可以一一对应上面的伪代码。练习的时候推荐先写伪代码,再写真实代码
多多注意“注释”解释。
- setItem:(CustomItem *)item{ _item = item; // 占位图片 UIImage *placeholder = [UIImage imageNamed:@"placeholderImage"]; // 从内存\沙盒缓存中获得原图, UIImage *originalImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.originalImage]; if (originalImage) { // 如果内存\沙盒缓存有原图,那么就直接显示原图(不管现在是什么网络状态) self.imageView.image = originalImage; } else { // 内存\沙盒缓存没有原图 AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]; if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder]; } else if (mgr.isReachableViaWWAN) { // 在使用手机自带网络 // 用户的配置项假设利用NSUserDefaults存储到了沙盒中 // [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"alwaysDownloadOriginalImage"]; // [[NSUserDefaults standardUserDefaults] synchronize];#warning 从沙盒中读取用户的配置项:在3G\4G环境是否仍然下载原图 BOOL alwaysDownloadOriginalImage = [[NSUserDefaults standardUserDefaults] boolForKey:@"alwaysDownloadOriginalImage"]; if (alwaysDownloadOriginalImage) { // 下载原图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder]; } else { // 下载小图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder]; } } else { // 没有网络 UIImage *thumbnailImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.thumbnailImage]; if (thumbnailImage) { // 内存\沙盒缓存中有小图 self.imageView.image = thumbnailImage; } else { // 处理离线状态,而且有没有缓存时的情况 self.imageView.image = placeholder; } } }}
真正的处理方法是
说的没错,确实是SDWebImage帮我们下载图片的,我们来扒一扒SDWebImage源码,看看他是怎么完成的。
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { // 关闭当前图片的下载操作 [self sd_cancelCurrentImageLoad]; objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); if (!(options & SDWebImageDelayPlaceholder)) { dispatch_main_async_safe(^{ self.image = placeholder; }); } if (url) { // check if activityView is enabled or not if ([self showActivityIndicatorView]) { [self addActivityIndicator]; } __weak __typeof(self)wself = self; id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { [wself removeActivityIndicator]; if (!wself) return; dispatch_main_sync_safe(^{ if (!wself) return; if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) { completedBlock(image, error, cacheType, url); return; } else if (image) { wself.image = image; [wself setNeedsLayout]; } else { if ((options & SDWebImageDelayPlaceholder)) { wself.image = placeholder; [wself setNeedsLayout]; } } if (completedBlock && finished) { completedBlock(image, error, cacheType, url); } }); }]; [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"]; } else { dispatch_main_async_safe(^{ [self removeActivityIndicator]; if (completedBlock) { NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; completedBlock(nil, error, SDImageCacheTypeNone, url); } }); } }
我们惊奇的发现,原来SDWebImage在下载图片时,第一件事就是关闭imageView当前的下载操作!
是不是开始感叹SDWebImage多么神奇了?没错,我们只需要把我们写的那段代码所有的直接访问本地缓存代码利用SDWebImage进行设置就OK了!
下面就是完成版代码。
- setItem:(CustomItem *)item { _item = item; // 占位图片 UIImage *placeholder = [UIImage imageNamed:@"placeholderImage"]; // 从内存\沙盒缓存中获得原图 UIImage *originalImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.originalImage]; if (originalImage) { // 如果内存\沙盒缓存有原图,那么就直接显示原图(不管现在是什么网络状态) [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder]; } else { // 内存\沙盒缓存没有原图 AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager]; if (mgr.isReachableViaWiFi) { // 在使用Wifi, 下载原图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder]; } else if (mgr.isReachableViaWWAN) { // 在使用手机自带网络 // 用户的配置项假设利用NSUserDefaults存储到了沙盒中 // [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"alwaysDownloadOriginalImage"]; // [[NSUserDefaults standardUserDefaults] synchronize]; #warning 从沙盒中读取用户的配置项:在3G\4G环境是否仍然下载原图 BOOL alwaysDownloadOriginalImage = [[NSUserDefaults standardUserDefaults] boolForKey:@"alwaysDownloadOriginalImage"]; if (alwaysDownloadOriginalImage) { // 下载原图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.originalImage] placeholderImage:placeholder]; } else { // 下载小图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder]; } } else { // 没有网络 UIImage *thumbnailImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:item.thumbnailImage]; if (thumbnailImage) { // 内存\沙盒缓存中有小图 [self.imageView sd_setImageWithURL:[NSURL URLWithString:item.thumbnailImage] placeholderImage:placeholder]; } else { [self.imageView sd_setImageWithURL:nil placeholderImage:placeholder]; } } } }
相关文章推荐
- AJAX入门 之 XMLHttpRequest 状态与 onreadystatechange 事件(三)
- 使用WebService进行网络编程【工具类】
- Linux下的C语言开发(网络编程)
- Qt---获取本机网络信息
- 学习笔记——网络基础(一)
- wifi eth gprs 网络自动切换 脚本
- 通过HttpServletRequest获取上一个页面
- HTTP中GET和POST的区别
- tensorflow入门简单卷积神经网络
- 高性能HTTP加速器Varnish安装与配置
- HTTP协议
- httpClient
- 计算机网络核心原理-授课用
- tcping
- 网络爬虫基本原理
- [转]www-authenticate认证过程浅析
- 计算机网络——基于socket的网络应用
- AJAX入门 之 XMLHttpRequest对象的属性(一)
- 网络通讯选择TCP或UDP的指导方针
- 关于HTTP中GET,POST,PUT,DELETE的区别。