iOS REST服务

做过iOS开发的人员都知道,iOS应用需要通过某种与远程Web服务器通信。有些应用可以在没有网络连接的情况下使用,只在网络连接可用时才与服务器同步数据的应用就是这样。当然还有一类应用需要在几乎连续的网络连接下才能为用户提供有效的价值。这类应用通常作为Web服务的移动客户端。

大部分iOS应用都要用到这种功能,折让iPhone成为有史以来最好的互联网连接设备。不过,由于设备总是在移动,连接和接收信号可能都很差。作为iOS开发者得确保应用的感知时间差不多恒定,就好像全部内容存储在本地一样。所以本地缓存数据就是来解决这个问题的。今天我们来看看iOS如何用缓存技术来结局很差的网络连接甚至无网络连接带来的问题。

REST
REST服务有三大特征:无状态,统一资源定位和可缓存。
无状态:每次API调用都被视作新的请求,服务器不会记录客户端上下文。客户端需要维护服务器的状态。
统一资源定位:URL是REST的参数。REST使用这种资源定位,而且不维护客户端状态。
可缓存:REST的响应是以一种统一的,双方一致同意的格式返回给客户端,这样能够更好地解耦。目前,最常用的是XML和JSON。

XML解析

XML解析最常见的就是DOM和SAX解析器。两者的区别就是SAX是一串流解析器,它逐句便利整个XML文档,通过回掉函数返回解析结果。大部分SAX解析器接受一个URL作为参数,解析完目标数据就将数据返回。之前说过NSXMLParser,通过代理的方式回调。

parserDidStartDocument
parserDidEndDocument
parser:didiStartElement:namespaceURL:qualifiedName:attributes:
parser:didiEndElement:namespaceURL:qualifiedName:
parser:foundCharacters:

DOM解析

需要先把XML整个文档加载到内存中才开始解析。其优势在于可以使用Xpath查询访问随机数据,不需要像SAX使用委托。对于iOS开发没有内置的DOM解析器。一般使用第三方包装器,我再网上看到有:基于libxml2的KissXML,TouchXML和GDataXML。

使用DOM解析可以让代码更加简洁。虽然在处理请求时会花费更多的执行时间,但是跟网络操作消耗的时间相比,简直微不足道。

不过,我在项目中用的是SAX解析。

JSON解析

相信做客户端开发的,一定都逃不过Json吧。苹果有自己的解析JSON框架,也是我们常用的NSJSONSerialization。还有很多不错的第三方框架:SBJson,JSONKit,TouchJSON。基本上都是提供基于NSString,NSArray,NSDictionary的分类扩展。我在项目中用的是苹果自带的。

// 将字典或者数组转化为JSON串
- (NSData *)toJSONData:(id)theData{

    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:theData
                                                      options:NSJSONWritingPrettyPrinted
                                                         error:&error];

    if ([jsonData length] > 0 && error == nil){
        return jsonData;
    }else{
        return nil;
    }
}
使用这个方法的返回,我们就可以得到想要的JSON串
NSString *jsonString = [[NSString alloc] initWithData:jsonData
                                                 encoding:NSUTF8StringEncoding];

// 将JSON串转化为字典或者数组
- (id)toArrayOrNSDictionary:(NSData *)jsonData{
    NSError *error = nil;
    id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
                                                   options:NSJSONReadingAllowFragments error:&error];

    if (jsonObject != nil && error == nil){
        return jsonObject;
    }else{
        // 解析错误
         return nil;
    }
}
//将JSON串与NSArray和NSDictionary的操作进行封装

1.NSString转化为NSArray或者NSDictionary
#import "NSString+JSONCategories.h"
@implementation NSString(JSONCategories)
-(id)JSONValue;
{
    NSData* data = [self dataUsingEncoding:NSUTF8StringEncoding];
    __autoreleasing NSError* error = nil;
    id result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
    if (error != nil) return nil;
    return result;
}
@end
2.NSArray或者NSDictionary转化为NSString
#import "NSObject+JSONCategories.h"
@implementation NSObject (JSONCategories)
-(NSData*)JSONString;
{
    NSError* error = nil;
    id result = [NSJSONSerialization dataWithJSONObject:self
                                                options:kNilOptionserror:&error];
    if (error != nil) return nil;
    return result;
}
@end

之前说过NSURLConnection。但是,为了开发REST服务,用MKNetworkKit更加方便。封装了很多常用的功能:基本认证/摘要认证,表单发布,上传/下载文件。还可以使用队列来管理网络请求。

Note:与浏览器不同的是,大部分运营商网络都会限制并发数据连接的数量,在EDGE连接中不要进行1个以上的网络操作,在3G网络中不要使用2个以上的并发网络操作,在Wi-Fi连接中的并发网络操作数量不要超过6个。

缓存

为了改善性能,提高用户的体验质量,离线工作是重点。一般有两种缓存技术支持离线:
按需缓存:应用缓存起请求应答,和Web浏览器的工作原理一样
预缓存:缓存全部内容以便离线访问

按需缓存思想:把从服务器获取的内容以某种格式存放在本地文件系统,之后对于每次请求,检查缓存中是否存在这块数据,只有当数据不存在(或者过期)的情况下才从服务器获取。这样,缓存层就和处理器的高速缓存差不多。获取数据的速度比数据本身重要。按需缓存的工作原理类似浏览器,允许我们查看以前查看或者访问过的内容。我们开发中,通讯录,消息等这些都是采用的按需缓存,不需要后台线程做这件事,也可以在一个URL请求返回成功实现按需缓存。

预缓存思想:需要一个后台县城访问数据并以有意义的格式保存,本地缓存无需重新连接服务器就可以被编辑。对预缓存来说,数据丢失或者缓存不命中是不可接受的。CoreData (结构化数据)试试先这种缓存的一种方式。

沙盒文件:
每个ios应用都有自己的应用沙盒,应用沙盒就是文件系统目录,与其他应用的文件系统隔离,ios系统不允许访问其他应用的应用沙盒。在ios8中已经开放访问。

应用沙盒一般包括以下几个文件目录:应用程序包、Documents、Libaray(下面有Caches和Preferences目录)、tmp。

应用程序包:包含所有的资源文件和可执行文件。

Documents:保存应用运行时生成的需要持久化的数据,iTunes会自动备份该目录。苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录

tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也有可能会清除该目录下的文件,iTunes不会同步该目录。iphone重启时,该目录下的文件会丢失。

Library:存储程序的默认设置和其他状态信息,iTunes会自动备份该目录。

Libaray/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除。一般存放体积比较大,不是特别重要的资源。

Libaray/Preferences:保存应用的所有偏好设置,ios的Settings(设置)应用会在该目录中查找应用的设置信息,iTunes会自动备份该目录。

沙盒文件目录获取代码:

//Home目录NSString *homeDirectory = NSHomeDirectory();

//Document目录NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];

//Cache目录NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];

//Libaray目录NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];

//tmp目录
NSString *tmpDir = NSTemporaryDirectory();

就像我们实验室做的企业级通信APP,像用户的账号密码,登陆时需要的IP号和端口号,用户头像等这些信息都需要存放到Library/Cache下。而偏好设置像响铃,震动这些存放到Library/preference下。

而我们的源代码打包后放在应用程序包路径下。我们下载的文件,下载过程中会放在tmp下,下载完成再放到Library。

数据缓存方法

1)数据模型缓存

我们可以用NSKeyedArchiver来实现。首先需要把模型类进行编解码重写。也就是要遵循NSCoding协议。

@interface Student : NSObject <NSCoding>
@property (nonatomic, assign) int idNum;
@property (nonatomic, copy) NSString *name;
@end

@implementation Student

#pragma mark 编码 对对象属性进行编码的处理
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeInt:_idNum forKey:IDNUM];
    [aCoder encodeObject:_name forKey:NAME];
}

#pragma mark 解码 解码归档数据来初始化对象
- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        _idNum = [aDecoder decodeIntForKey:IDNUM];
        _name = [aDecoder decodeObjectForKey:NAME];
    }
    return self;
}
@end

然后对模型对象进行序列化

//获得文件路径
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filePath = [documentPath stringByAppendingPathComponent:@"file.archiver"];

//归档(序列化)
NSArray *archiveAry = @[@"jereh",@"ios"];
if ([NSKeyedArchiver archiveRootObject: archiveAry toFile:filePath]) {

}

//解归档(反序列化)
NSArray *unArchiveAry = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

2)直接对文件进行操作我们常用到的plist
创建文件->添加数据
读取:

//path 读取当前程序定义好的provinces.plist省份城市文件
    NSString *path = [[NSBundle mainBundle] pathForResource:@"student" ofType:@"plist"];

    NSDictionary *data = [NSDictionary dictionaryWithContentsOfFile:path];
    self.studentContent = [NSArray arrayWithArray:[data objectForKey:@"student"]];//array数组的名称就叫student
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];//获取标准函数对象
    NSMutableDictionary *default = [defaults objectForKey:@"xxx"];//通过对象获取名称下NSMutableDictionary数据
    NSString *studentname= [default objectForKey:@"name"];

增删改查

    [defaults setObject:@"kaka" forKey:@"newdata"];//添加id对象类型数据
    [defaults objectForKey:@"newdata"];//获取对象类型数据

    [defaults setDouble:2013 forKey:@"double"];//添加double类型数据
    [defaults doubleForKey:@"double"];//获取double类型数据

    [defaults setBool:NO forKey:@"BOOL"];//添加BOOL类型数据
    [defaults boolForKey:@"BOOL"];//获取BOOL类型数据

    [defaults setInteger:12 forKey:@"int"];//添加int类型数据
    [defaults integerForKey:@"int"];//获取int类型数据

    [defaults setFloat:0.23 forKey:@"float"];//添加Float类型数据
    [defaults floatForKey:@"float"];//获取float类型数据

    [defaults removeObjectForKey:@"newdata"];//删除对象数据

3)SQLite
项目中的sqlit3,简单说一下使用过程吧

使用的过程根据使用的函数大致分为如下几个过程:

sqlite3_open()
sqlite3_prepare()
sqlite3_step()
sqlite3_column()
sqlite3_finalize()
sqlite3_close()

具体的讲解,可以参考这微博主:http://blog.csdn.net/zhuzhihai1988/article/details/7878093

4) CoreData
CoreData更像是一个对象序列化框架,而不仅仅是一个数据库的API。我理解的是非关系型数据库的一种,采用key-value的形式存储。用CoreData保存数据,首先创建一个CoreData模型文件,创建实体和关系,然后写好保存和获取数据的方法。实现预缓存时需要定期删除不再需要的(过时的)数据,否则缓存会不断增长进而影响应用的性能。同步本地变更是通过追踪变更集并发送回服务器实现的。

5)数据模型缓存和URL缓存
按需缓存可以采用数据模型缓存或者URL缓存。使用哪一个取决于服务器的实现。URL缓存的实现原理和浏览器缓存或代理服务器缓存类似。当服务器遵循HTTP1.1时缓存规范,效果很好。如果是SOAP服务器则采用数据模型缓存。数据模型缓存允许客户端有缓存失效的情形,当采用URL缓存,服务器通过HTTP1.1的缓存控制头控制缓存失效。MKNetworkKit提供对HTTP1.1缓存标准的原生支持。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ArcGIS REST API是Esri公司提供的一种基于HTTP/HTTPS协议的Web API,用于访问和管理ArcGIS Server和ArcGIS Online等GIS服务和资源。ArcGIS REST API支持多种编程语言和平台,例如Java、Python、JavaScript、.NET、iOS和Android等。以下是ArcGIS REST API的一些主要特点和功能: 1. 支持多种HTTP操作:ArcGIS REST API支持多种HTTP操作,例如GET、POST、PUT和DELETE等,可以用于从GIS服务中获取或修改数据。 2. 支持多种数据格式:ArcGIS REST API支持多种数据格式,包括JSON、XML、HTML和二进制等,可以根据需要选择合适的数据格式。 3. 支持多种GIS服务和资源:ArcGIS REST API支持多种GIS服务和资源,例如地图服务、要素服务、空间分析服务、地理编码服务、地理处理服务、Web地图和Web应用程序等。 4. 支持数据查询和过滤:ArcGIS REST API支持对GIS服务中的数据进行查询和过滤,可以根据要求返回符合条件的数据。 5. 支持安全认证和授权:ArcGIS REST API支持多种安全认证和授权方式,例如基本认证、令牌认证和OAuth2.0认证等,可以保证GIS服务和资源的安全性和可靠性。 6. 支持跨域访问:ArcGIS REST API支持跨域访问,可以在不同的域名和网站之间进行数据交互和共享。 7. 支持自定义扩展:ArcGIS REST API支持自定义扩展,可以根据需要扩展和定制GIS服务和资源的功能和特性。 总之,ArcGIS REST API是Esri公司提供的一种基于HTTP/HTTPS协议的Web API,用于访问和管理ArcGIS Server和ArcGIS Online等GIS服务和资源,具有多种特点和功能,可以满足不同用户的需求和要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值