博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初探iOS网络开发,数据解析。
阅读量:5825 次
发布时间:2019-06-18

本文共 18174 字,大约阅读时间需要 60 分钟。

  通过大众点评平台开发来简单了解一下,oc的网络编程和数据解析(json)

 

首先我们需要到大大众点评开发者平台申请一个key。http://developer.dianping.com/app/tech/api这个网站有api文档。

本文没有使用第三方库,网络其请求使用NSURLConnection类,json数据解析使用NSJSONSerialization。这个例子是根据条件获取商户信息。

1.定义常量

#define kSearchResto @"v1/business/find_businesses"#define kDPDomain @"http://api.dianping.com/"#define kDPAppKey @"。。。"#define kDPAppSecret @"。。。"#define kWFRequestimeOutInterval 60.0#define kHttpMethodGET @"GET"#define kHttpMethodPOST @"POST"

 2.创建数据类,包含商户信息

////  WFBusiness.h//  WFSearch////  Created by ForrestWoo on 14-9-5.//  Copyright (c) 2014年 ForrestWoo. All rights reserved.//#import 
#import "WFRootModel.h"@interface WFBusiness : WFRootModel@property (nonatomic, assign) int business_id;@property (nonatomic, strong) NSString *name;@property (nonatomic, strong) NSString *branch_name;@property (nonatomic, strong) NSString *address;@property (nonatomic, strong) NSString *telephone;@property (nonatomic, strong) NSString *city;//星级图片链接。@property (nonatomic, strong) NSString *rating_img_url;@property (nonatomic, strong) NSString *rating_s_img_url;@property (nonatomic, strong) NSArray *regions;@property (nonatomic, strong) NSArray *categories;//经纬度信息@property (nonatomic, assign) float latitude;@property (nonatomic, assign) float longitude;@property (nonatomic, assign) float avg_rating;@property (nonatomic, assign) float product_score;@property (nonatomic, assign) float decoration_score;@property (nonatomic, assign) float service_score;//评价 分五种。1:一般,2:尚可,3:好,4:很好,5:非常好@property (nonatomic, assign) int product_grade;@property (nonatomic, assign) int decoration_grade;@property (nonatomic, assign) int service_grade;//人均消费。@property (nonatomic, assign) int avg_price;//点评。@property (nonatomic, assign) int review_count;@property (nonatomic, strong) NSArray *review_list_url;@property (nonatomic, assign) int distance;@property (nonatomic, strong) NSString *business_url;//图片@property (nonatomic, strong) NSString *photo_url;@property (nonatomic, strong) NSString *s_photo_url;@property (nonatomic, assign) int photo_count;@property (nonatomic, strong) NSArray *photo_list_url;//优惠券。@property (nonatomic, assign) int has_coupon;@property (nonatomic, assign) int coupon_id;@property (nonatomic, strong) NSString *coupon_description;@property (nonatomic, strong) NSString *coupon_url;//团购信息。@property (nonatomic, assign) int has_deal;@property (nonatomic, assign) int deal_count;@property (nonatomic, strong) NSArray *deals;@property (nonatomic, strong) NSString *deals_id;@property (nonatomic, strong) NSString *deals_description;@property (nonatomic, strong) NSString *deals_url;@property (nonatomic, assign) int has_online_reservation;@property (nonatomic, strong) NSString *online_reservation_url;- (id)initWithJson:(NSDictionary *)jsonData;@end

 这里的属性名字并不是随便定义的,而是根据服务器端返回的字段名称定义的,它与返回的名称是一致的,目的是方便以后通过反射对类的属性赋值,这样我们不需要一一赋值,详情请继续

3.WFRootModel

#import 
//根类,定义一些通用的属性和消息@interface WFRootModel : NSObject//获取类的属性名称,以通过反射对对象的属性赋值。- (NSArray *)PropertyKeys;@end#import "WFRootModel.h"#import
@implementation WFRootModel- (NSArray *)PropertyKeys{ unsigned int outCount,i; objc_property_t *pp = class_copyPropertyList([self class], &outCount); NSMutableArray *keys = [[NSMutableArray alloc] initWithCapacity:0]; for (i = 0; i < outCount; i++) { objc_property_t property = pp[i]; NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding]; [keys addObject:propertyName]; } return keys;}@end

  此类赋予了它的子类一个重要行为,它只包含一个消息[- (NSArray *)PropertyKeys],它的作用是子类能够获取自己包含的所有属性。反射中会使用这些属性。

4.创建请求url

  大众点评请求使用SHA加密。

[1]SHA加密类SHA1,需要引入

CommonDigest.h
@interface SHA1 : NSObject+ (NSString *)getSHAString:(NSData *)aStringbytes;@end#import 
#import "SHA1.h"@implementation SHA1+ (NSString *)getSHAString:(NSData *)aStringbytes{ unsigned char digest[CC_SHA1_DIGEST_LENGTH]; if (CC_SHA1([aStringbytes bytes], [aStringbytes length], digest)) { NSMutableString *digestString = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH]; for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) { unsigned char aChar = digest[i]; [digestString appendFormat:@"%02x",aChar]; } return digestString; } else { return nil; }}@end

 由于我对加密了解很少,所以就不做介绍了,只给出一个方法,供大家参考。

[2]返回根url,因为根url会常用到,我们就将它封装起来,以便后用

- (NSString *)getRootURL{    return kDPDomain;}

 [3]返回合法的url

- (NSString *)serializeURL:(NSString *)aBaseURL params:(NSDictionary *)aParams{	NSURL* parsedURL = [NSURL URLWithString:[aBaseURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];	NSMutableDictionary *paramsDic = [NSMutableDictionary dictionaryWithDictionary:[self parseQueryString:[parsedURL query]]];	if (aParams) {		[paramsDic setValuesForKeysWithDictionary:aParams];	}		NSMutableString *signString = [NSMutableString stringWithString:kDPAppKey];	NSMutableString *paramsString = [NSMutableString stringWithFormat:@"appkey=%@", kDPAppKey];	NSArray *sortedKeys = [[paramsDic allKeys] sortedArrayUsingSelector: @selector(compare:)];	for (NSString *key in sortedKeys) {		[signString appendFormat:@"%@%@", key, [paramsDic objectForKey:key]];		[paramsString  appendFormat:@"&%@=%@", key, [paramsDic objectForKey:key]];	}    NSString *str = kDPAppSecret;	[signString appendString:str];	NSData *stringBytes = [signString dataUsingEncoding: NSUTF8StringEncoding];    NSString *digestString = [SHA1 getSHAString:stringBytes];    if (digestString)    {        [paramsString appendFormat:@"&sign=%@", [digestString uppercaseString]];        NSLog(@"...%@...", [NSString stringWithFormat:@"%@://%@%@?%@", [parsedURL scheme], [parsedURL host], [parsedURL path], [paramsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]);		return [NSString stringWithFormat:@"%@://%@%@?%@", [parsedURL scheme], [parsedURL host], [parsedURL path], [paramsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];    }    else    {        return nil;    }}

 5.创建网络连接,发送请求

使用NSURLConnection来完成网络连接

- (void)createConnectionWithUrl:(NSString *)urlString params:(NSDictionary *)aParams delegate:(id
)aDelegate{ NSString *urlStr = [self serializeURL:[self generateFullURL:urlString] params:aParams]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:kWFRequestimeOutInterval]; [request setHTTPMethod:kHttpMethodGET]; NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; self.delegate = aDelegate;// [[[self class] sharedInstance] setConnections:conn];}

 6.返回结果以及数据解析

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{    _responseData = [[NSMutableData alloc] init];}- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{    [_responseData appendData:data];}- (void)connectionDidFinishLoading:(NSURLConnection *)connection{    NSError *error = nil;    id result= [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingAllowFragments error:&error];    if (!result)    {        NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:error,@"error", nil];        NSError *err = [NSError errorWithDomain:@"domain is error" code:-1 userInfo:userInfo];        if ([self.delegate respondsToSelector:@selector(request:didfailWithError:)])        {            [self.delegate request:self didfailWithError:err];        }    }    else    {        NSString *status = 0;        if ([result isKindOfClass:[NSDictionary class]])        {            status = [result objectForKey:@"status"];        }                if ([status isEqualToString:@"OK"])        {            if ([self.delegate respondsToSelector:@selector(request:didfinishloadingWithResult:)])            {                [self.delegate request:self didfinishloadingWithResult:result == nil ?                                 _responseData : result];            }        }        else        {            if ([status isEqualToString:@"ERROR"])            {                //TODO:错误处理代码。            }        }    }//    NSString *str = [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding];//    NSLog(@"_responseData:%@", str);    //    [self clearData];}- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{    NSLog(@"ERROR!%@", error.description);}

 返回的数据存储在一个WFFindBusinessesResult的实例中。

//super class for result.@interface WFUrlResult : NSObject@property (nonatomic, strong) NSString *status;@property (nonatomic, assign) NSInteger total_count;@property (nonatomic, assign) NSInteger count;- (id)initWithJson:(NSDictionary *)jsonData;@end@interface WFFindBusinessesResult : WFUrlResult@property (nonatomic, strong) NSArray *businesses;@end

 对对象赋值非常简单

@implementation WFFindBusinessesResult- (id)initWithJson:(NSDictionary *)jsonData{        self.status = [jsonData objectForKey:@"status"];    self.count = [[jsonData objectForKey:@"count"] integerValue];    self.total_count = [[jsonData objectForKey:@"total_count"] integerValue];    NSArray *arr = nil;    NSMutableArray *businessArr = [[NSMutableArray alloc] initWithCapacity:0];        if ([jsonData isKindOfClass:[NSDictionary class]])    {        arr = [jsonData objectForKey:@"businesses"];     //赋值,通过反射赋值,根本不需要一一对字段赋值。        for (id obj in arr)        {            WFBusiness *bus = [[WFBusiness alloc] init];            NSArray *propertyList = [[[WFBusiness alloc] init] PropertyKeys];            for (NSString *key in propertyList)            {                                [bus setValue:[obj objectForKey:key] forKey:key];            }            [businessArr addObject:bus];            NSLog(@"photo is %@", [bus categories]);        }            }    NSLog(@"businessArr count is %lu", [businessArr count]);    self.Businesses = businessArr;    return self;}@end

 完整的封装类WFHTTPRequest。它用于创建一个连接,并发送请求,管理整个应用出现的网络连接,创建一个单例,全局唯一。

////  WFRequest.h//  WFSearch////  Created by ForrestWoo on 14-8-30.//  Copyright (c) 2014年 ForrestWoo. All rights reserved.//#import 
@class WFHTTPRequest;@protocol WFRequestDelegate
@optional- (void)request:(WFHTTPRequest *)request didfinishloadingWithResult:(id)aResult;- (void)request:(WFHTTPRequest *)request didfailWithError:(NSError *)aError;@end@interface WFHTTPRequest : NSObject@property (nonatomic, unsafe_unretained) id
delegate;@property (nonatomic, strong) NSString *aUrl;@property (nonatomic, strong) NSDictionary *aParams;@property (nonatomic, strong) NSArray *connections;+ (WFHTTPRequest *)sharedInstance;- (void)createConnectionWithUrl:(NSString *)urlString params:(NSDictionary *)aParams delegate:(id
)aDelegate;- (void) cancel;- (NSString *)getRootURL;//api- (void)findBusinessesWithParams:(NSDictionary *)aParams delegate:(id
)aDelegate;- (void)findCityWithDelegate:(id
)aDelegate;- (void)getCategoriesForBusinessesWithDelegate:(id
)aDelegate;@end

 

////  WFRequest.m//  WFSearch////  Created by ForrestWoo on 14-8-30.//  Copyright (c) 2014年 ForrestWoo. All rights reserved.//#import "WFHTTPRequest.h"#import "WFConstants.h"#import "SHA1.h"@interface WFHTTPRequest () 
//- (void)appendUTF8Body:(NSMutableData *)aBody dataString:(NSString *)aDataString;//- (NSDictionary *)parseQueryString:(NSString *)query;- (void)handleResponseData:(NSData *)data;//- (NSString *)generateFullURL:(NSString *)url;- (void)addConnection;//- (NSString *)serializeURL:(NSString *)aBaseURL params:(NSDictionary *)aParams;@endstatic WFHTTPRequest *sharedObj = nil;@implementation WFHTTPRequest{ NSURLConnection *_connection; NSMutableData *_responseData;}- (NSString *)getRootURL{ return kDPDomain;}- (NSString *)generateFullURL:(NSString *)url{ NSMutableString *str = [[NSMutableString alloc] initWithCapacity:0]; [str appendString:[self getRootURL]]; [str appendString:url]; return str;}+ (WFHTTPRequest *)sharedInstance{ static dispatch_once_t pred = 0; dispatch_once(&pred, ^{ sharedObj = [[super allocWithZone:NULL] init]; }); return sharedObj;}+ (id)allocWithZone:(struct _NSZone *)zone{ return [self sharedInstance];}- (void)createConnectionWithUrl:(NSString *)urlString params:(NSDictionary *)aParams delegate:(id
)aDelegate{ NSString *urlStr = [self serializeURL:[self generateFullURL:urlString] params:aParams]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:kWFRequestimeOutInterval]; [request setHTTPMethod:kHttpMethodGET]; NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; self.delegate = aDelegate;// [[[self class] sharedInstance] setConnections:conn];}- (void)findBusinessesWithParams:(NSDictionary *)aParams delegate:(id
)aDelegate{ [self createConnectionWithUrl:kSearchResto params:aParams delegate:aDelegate];}- (void)findCityWithDelegate:(id
)aDelegate{ [self createConnectionWithUrl:kSearchCity params:nil delegate:aDelegate];}- (void)getCategoriesForBusinessesWithDelegate:(id
)aDelegate{ [self createConnectionWithUrl:kCategoriesWithBusinesses params:nil delegate:aDelegate];}//- (void)appendUTF8Body:(NSMutableData *)aBody dataString:(NSString *)aDataString//{// [aBody appendData:[aDataString dataUsingEncoding:NSUTF8StringEncoding]];//}- (NSDictionary *)parseQueryString:(NSString *)query{ NSMutableDictionary *paramDict = [[NSMutableDictionary alloc] initWithDictionary:0]; NSArray *paramArr = [query componentsSeparatedByString:@"&"]; for (NSString *param in paramArr) { NSArray * elements = [param componentsSeparatedByString:@"="]; if ([elements count] <= 1) { return nil; } NSString *key = [[elements objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString *value = [[elements objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [paramDict setObject:value forKey:key]; } return paramDict;}- (NSString *)serializeURL:(NSString *)aBaseURL params:(NSDictionary *)aParams{ NSURL* parsedURL = [NSURL URLWithString:[aBaseURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSMutableDictionary *paramsDic = [NSMutableDictionary dictionaryWithDictionary:[self parseQueryString:[parsedURL query]]]; if (aParams) { [paramsDic setValuesForKeysWithDictionary:aParams]; } NSMutableString *signString = [NSMutableString stringWithString:kDPAppKey]; NSMutableString *paramsString = [NSMutableString stringWithFormat:@"appkey=%@", kDPAppKey]; NSArray *sortedKeys = [[paramsDic allKeys] sortedArrayUsingSelector: @selector(compare:)]; for (NSString *key in sortedKeys) { [signString appendFormat:@"%@%@", key, [paramsDic objectForKey:key]]; [paramsString appendFormat:@"&%@=%@", key, [paramsDic objectForKey:key]]; } NSString *str = kDPAppSecret; [signString appendString:str]; NSData *stringBytes = [signString dataUsingEncoding: NSUTF8StringEncoding]; NSString *digestString = [SHA1 getSHAString:stringBytes]; if (digestString) { [paramsString appendFormat:@"&sign=%@", [digestString uppercaseString]]; NSLog(@"...%@...", [NSString stringWithFormat:@"%@://%@%@?%@", [parsedURL scheme], [parsedURL host], [parsedURL path], [paramsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]); return [NSString stringWithFormat:@"%@://%@%@?%@", [parsedURL scheme], [parsedURL host], [parsedURL path], [paramsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; } else { return nil; }}- (void) cancel{ [_connection cancel];}+ (NSString *)getParamValueFromURL:(NSString *)aURl paramName:(NSString *)aParamName{ return nil;}#pragma mark - NSURLConnection Delegate Methods- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ _responseData = [[NSMutableData alloc] init];}- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ [_responseData appendData:data];}- (void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSError *error = nil; id result= [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingAllowFragments error:&error]; if (!result) { NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:error,@"error", nil]; NSError *err = [NSError errorWithDomain:@"domain is error" code:-1 userInfo:userInfo]; if ([self.delegate respondsToSelector:@selector(request:didfailWithError:)]) { [self.delegate request:self didfailWithError:err]; } } else { NSString *status = 0; if ([result isKindOfClass:[NSDictionary class]]) { status = [result objectForKey:@"status"]; } if ([status isEqualToString:@"OK"]) { if ([self.delegate respondsToSelector:@selector(request:didfinishloadingWithResult:)]) { [self.delegate request:self didfinishloadingWithResult:result == nil ? _responseData : result]; } } else { if ([status isEqualToString:@"ERROR"]) { //TODO:错误处理代码。 } } }// NSString *str = [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding];// NSLog(@"_responseData:%@", str); // [self clearData];}- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ NSLog(@"ERROR!%@", error.description);}- (void)clearData{ _responseData = nil; [_connection cancel]; _connection = nil;}@end

。下节详细介绍数据解析和网络编程,反射(运行时)

转载地址:http://qaidx.baihongyu.com/

你可能感兴趣的文章
.NET各种小问题
查看>>
ApkTool反编译和重新打包
查看>>
OpenState: Programming Platform-independent Stateful OpenFlow Applications Inside the Switch
查看>>
java中的Volatile关键字
查看>>
前端自定义图标
查看>>
sqlserver 取取月初月末和月份间隔
查看>>
Vagrant的一个BUG - 不支持'change_host_name'
查看>>
实验二
查看>>
独立开发一个云(PaaS)的核心要素, Go, Go, Go!!!
查看>>
java的继承性
查看>>
tomcat 实例
查看>>
MyBatis使用DEMO及cache的使用心得
查看>>
网站文章如何能自动判定是抄袭?一种算法和实践架构剖析
查看>>
【OpenCV学习】滚动条
查看>>
ofo用科技引领行业进入4.0时代 用户粘性连续8个月远甩摩拜
查看>>
无法拒绝|华为618最高优惠1000元 更有梅西签名球衣奉送
查看>>
乐信Q2季报图解:调整后净利过5亿 同比增长776%
查看>>
兰州青年志愿者“中西合璧”玩快闪 温暖旅客回家路
查看>>
计划10年建10万廉价屋 新西兰政府:比想象中难
查看>>
甘肃发首版《3D打印职业教育教材》:校企合作育专才
查看>>