watchOS中进行异步图片加载和缓存的策略

watchOS中进行异步图片加载和缓存的策略

一、引言

        iWatch是智能手表的一次革命。iWatch的应用也将会越来越多,基于watch的一些特点,watchOS的开发者需要更加精益的把握watch的UI和性能。运用watchOS自带的缓存体系进行数据的缓存,是增强用户体验度的一种方式,这篇博客,介绍在watchOS中进行异步加载图片和缓存的方法,愿与志同道合的朋友,一起交流。

关于watchOS中的缓存框架,在这里:http://my.oschina.net/u/2340880/blog/519023   

二、存储的命名规则

        在进行设计之前,我们应该先了解,watchOS的缓存容量为最大20M,因为有限,我们更应该认真的利用每一份空间,因此,缓存我们不仅可以存,在即将装满的时候,我们还要有办法从缓存中删去一些东西,让出空间,那么应该删除哪些东西了,我们应该都可以想到,当然是旧的了,把最早的缓存删掉,所以,在存的时候,我们要设计一种规则,可以保存存入的时间,并且不影响我寻找这个缓存文件。我的方法是通过格式化的命名:

//这是一个规范缓存命名的方法
func checkString(str:NSString)->NSString{
    let result:NSMutableString=NSMutableString()
    //先将所有的非字母和数字剔除掉
    for var i=0 ; i<str.length ; i++ {
        if (str.characterAtIndex(i)>=48&&str.characterAtIndex(i)<=57)||(str.characterAtIndex(i)>=65&&str.characterAtIndex(i)<=90)||(str.characterAtIndex(i)>=97&&str.characterAtIndex(i)<=122){
            result.appendFormat("%c",str.characterAtIndex(i))
        }
    }
    //拼接上当前时间戳
    let date:Double = NSDate().timeIntervalSince1970
    result.appendFormat("?%.0f",date)
    return result
}

通过?符号将名称和时间戳进行了拼接。

二、进行异步加载图片和缓存

        这一步是如下的设计思路:通过图片url从缓存的路径中进行寻找,如果有,直接取出图片,如果没有,开启一个线程进行异步加载,完成后刷新主线程UI并将图片文件规范命名后进行缓存:

//进行存取缓存的操作
//取出watchOS的缓存目录
let imagedic:NSDictionary = WKInterfaceDevice().cachedImages as NSDictionary
    //取图片存储的名称
    let imageUrl:NSMutableString=NSMutableString()
        //这里的url是外界传进来的图片地址url,进行去掉特殊字符
        for var i=0 ; i<url?.length ; i++ {
            if (url?.characterAtIndex(i)>=48&&url?.characterAtIndex(i)<=57)||(url?.characterAtIndex(i)>=65&&url?.characterAtIndex(i)<=90)||(url?.characterAtIndex(i)>=97&&url?.characterAtIndex(i)<=122){
                imageUrl.appendFormat("%c",(url?.characterAtIndex(i))!)
             }
        }
        //查找缓存中是否有图片
        //遍历watchOS的缓存目录
        for var i=0 ; i<imagedic.allKeys.count ; i++ {
           //通过规定好的?进行分割
           let str:NSArray =  imagedic.allKeys[i].componentsSeparatedByString("?")
                if str[0].isEqualToString(imageUrl as String) {
                    //找到图片 view是要设置的interfaceImage
                    view.setImageNamed(imagedic.allKeys[i] as? String)
                    return;
                }
            }
            //设置缺省图片 这里是外界传进来的缺省图片,如果需要下载,先设置缺省图片
            if defaultImage != nil {
                view.setImageNamed(defaultImage as? String)
            }
            
            //进行下载和存储
            let dispath = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
            //在新的线程中下载
            dispatch_async(dispath, { () -> Void in
                let imgURL:NSURL = NSURL(string: url as! String)!
                let imageData:NSData? = NSData(contentsOfURL: imgURL)
                if imageData != nil {
                    //主线程中刷新
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        view.setImageData(imageData!)
                    })
                    //写缓存  如果缓存满了 就删掉时间戳最早的一张缓存
                    //这个方法会返回bool值,判断是否存入成功
                    while !WKInterfaceDevice().addCachedImageWithData(imageData!, name: checkString(url!) as String) {
                        //如果存入失败,删去时间戳最早的缓存
                        var temp:NSString?
                        //保存最早的缓存名称
                        var result:NSString?
                        for var i=0 ; i<imagedic.allKeys.count ; i++ {
                            let str:NSArray =  imagedic.allKeys[i].componentsSeparatedByString("?")
                            if temp == nil {
                                temp = str[1] as? NSString
                                result = imagedic.allKeys[i] as! String
                                break
                            }
                            if str[1].doubleValue < temp?.doubleValue {
                                //找到更早的缓存
                                temp = str[1] as? NSString
                                result = imagedic.allKeys[i] as! String
                            }
                        }
                        //删掉缓存
                        WKInterfaceDevice().removeCachedImageWithName(result as! String)
                    }
                }
            })

上面的代码和注释,已经介绍了所有的思路,有错误之处或者更好的方式,还望多多指点。

专注技术,热爱生活,交流技术,也做朋友。 ——珲少 QQ群:203317592

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏游戏杂谈

emoji表情引发的JNI崩溃

今天突然接到客服那边的反馈说,有玩家反馈进游戏后不久就崩溃了,我先是怀疑网络问题,因为一连接聊天成功后就挂了。之后用logcat抓日志,发现挂在jni那里了

2013
来自专栏Python小屋

Python不使用scrapy框架而编写的网页爬虫程序

本文代码节选(略有改动)自《Python程序设计(第2版)》(董付国编著,清华大学出版社),没有使用scrapy爬虫框架,而是使用标准库urllib访问网页实现...

3565
来自专栏黑泽君的专栏

从零讲JAVA ,给你一条清晰地学习道路!该学什么就学什么!!

 原文链接:https://zhuanlan.zhihu.com/p/25296859

1082
来自专栏有趣的django

CRM客户关系管理系统(二) 第三章、前端页面设计

5310
来自专栏函数式编程语言及工具

Akka(28): Http:About Akka-Http

  众所周知,Akka系统是基于Actor模式的分布式运算系统,非常适合构建大数据平台。所以,无可避免地会出现独立系统之间、与异类系统、与移动系统集成的需求。由...

2687
来自专栏武培轩的专栏

2018年Java实习春招总结

因为女票在北京,打算去北京实习,所以从去年12月开始复习Java,做项目,视频是看的黑马的视频,还可以吧,把Java基础和SSM框架看了下,做了个小项目,然后看...

3246
来自专栏老司机的简书

老司机出品———疯狂造轮子之事件总线的设计思路

随着公司业务不断地迭代,数据层和UI层不断地下沉,被业务层进行包装,导致数据层想要跟UI层进行通信要经过一层层的带向上抛事件转发给对应的UI层。在重构过程中,我...

1555
来自专栏iOS Developer

Swift2.0后Alamofire的使用方法

1652
来自专栏吴伟祥

生词篇-Shiro官网 的笔记_0114

xml  [ˌeks em ˈel ] abbr. Extensible Markup Language 可扩展标记语言

711
来自专栏陈满iOS

iOS小经验:初始化的方法中不该设置self.view的属性

结果发现,在执行数据源传值 nextVC.source = [self.source copy]; 代码之前,NextViewController的 viewD...

1293

扫码关注云+社区

领取腾讯云代金券