Explore iOS network development and data parsing ., Ios

Source: Internet
Author: User
Tags allkeys

Explore iOS network development and data parsing ., Ios

Let's take a look at the oc network programming and data parsing (json) through the development of the public comments platform)

 

First, we need to apply for a key on the public comment developer platform. Http://developer.dianping.com/app/tech/apithis website has an API document.

This document does not use a third-party library. The NSURLConnection class is used for network requests, and NSJSONSerialization is used for json data parsing. In this example, the merchant information is obtained based on the conditions.

1. Define Constants

#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. Create a data class that contains merchant Information

//// WFBusiness. h // WFSearch // Created by ForrestWoo on 14-9-5. // Copyright (c) 2014 ForrestWoo. all rights reserved. // # import <Foundation/Foundation. h> # 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 * addh Ss; @ property (nonatomic, strong) NSString * telephone; @ property (nonatomic, strong) NSString * city; // star image link. @ 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; // latitude and longitude information @ property (nonatomic, assign) float latitude; @ property (nonatomic, assign) float longpolling; @ property (nonatomic, assign) float avg_rating; @ property (nonatomic, assign) float product_sco Re; @ property (nonatomic, assign) float decoration_score; @ property (nonatomic, assign) float service_score; // rating: 5. 1: General, 2: acceptable, 3: Good, 4: Good, 5: Very good @ property (nonatomic, assign) int product_grade; @ property (nonatomic, assign) int decoration_grade; @ property (nonatomic, assign) int service_grade; // per capita consumption. @ Property (nonatomic, assign) int avg_price; // comment. @ Property (nonatomic, assign) int review_count; @ property (nonatomic, strong) NSArray * review_list_url; @ property (nonatomic, assign) int distance; @ property (nonatomic, strong) NSString * business_url; // image @ 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_u Rl; // coupon. @ Property (nonatomic, assign) int has_coupon; @ property (nonatomic, assign) int coupon_id; @ property (nonatomic, strong) NSString * coupon_description; @ property (nonatomic, strong) NSString * coupon_url; // group buying information. @ 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

Here, the attribute name is defined based on the field name returned by the server, which is consistent with the returned name to facilitate the assignment of class attributes through reflection, in this way, we do not need to assign values one by one. For details, continue.

3. WFRootModel

# Import <Foundation/Foundation. h> // The root class, which defines some common attributes and the message @ interface WFRootModel: NSObject // gets the attribute name of the class to assign values to the attributes of the object through reflection. -(NSArray *) PropertyKeys; @ end # import "WFRootModel. h "# import <objc/runtime. h> @ 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

This class gives its subclass an important behavior. It only contains one message [-(NSArray *) PropertyKeys], and its role is that the subclass can obtain all its own attributes. These attributes are used in reflection.

4. Create a request url

Public comments request SHA encryption.

[1] SHA Encryption Class SHA1, which needs to be introduced

CommonDigest.h
@interface SHA1 : NSObject+ (NSString *)getSHAString:(NSData *)aStringbytes;@end#import <CommonCrypto/CommonDigest.h>#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

I have little knowledge about encryption, so I will not introduce it. I will only provide one method for your reference.

[2] returns the root url. Because the root url is often used, we encapsulate it for later use.

- (NSString *)getRootURL{    return kDPDomain;}

[3] return a valid 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. Create a network connection and send a request

Use NSURLConnection to complete network connection

- (void)createConnectionWithUrl:(NSString *)urlString params:(NSDictionary *)aParams delegate:(id<WFRequestDelegate>)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. Return results and data parsing

-(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: _ respons EData 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: ERROR handling code. }}// NSString * str = [[NSString alloc] initWithData: _ responseData encoding: NSUTF8StringEncoding]; // NSLog (@ "_ responseData: % @", str ); // [self clearData];}-(void) connection :( NSURLConnection *) connection didFailWithError :( NSError *) error {NSLog (@ "ERROR! % @ ", Error. description );}

The returned data is stored in a WFFindBusinessesResult instance.

//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

Assigning values to objects is very simple.

@ 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] limit: 0]; if ([jsonData isKindOfClass: [NSDictionary class]) {arr = [jsonData objectForKey: @ "businesses"];
// Assign values. Values are obtained through reflection. You do not need to assign values to fields one by one. 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

The complete encapsulation class WFHTTPRequest. It is used to create a connection, send requests, manage network connections that appear throughout the application, and create a Singleton, which is globally unique.

//// WFRequest. h // WFSearch // Created by ForrestWoo on 14-8-30. // Copyright (c) 2014 ForrestWoo. all rights reserved. // # import <Foundation/Foundation. h> @ class WFHTTPRequest; @ protocol WFRequestDelegate <NSObject> @ optional-(void) request :( WFHTTPRequest *) request principal :( id) aResult;-(void) request :( WFHTTPRequest *) request didfailWithError :( NSError *) aError; @ end @ interface WFHTTPRequest: NSObject @ property (nonatomic, assign) id <WFRequestDelegate> 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 <WFRequestDelegate>) aDelegate;-(void) cancel;-(NSString *) getRootURL; // api-(void) authorization :( NSDictionary *) aParams delegate :( id <WFRequestDelegate>) aDelegate;-(void) Authorization :( id <authorization>) aDelegate;-(void) Authorization :( id <WFRequestDelegate>) 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 () <NSURLConnectionDataDelegate> //-(void) appendUTF8Body :( NSMutableData *) aBody dataString :( NSString *) aDataString; //-(NSDictionary *) parseQueryString :( NSString *) query; //-(void) handleRe Eclipsedata :( NSData *) data; //-(NSString *) generateFullURL :( NSString *) url; //-(void) addConnection; //-(NSString *) serializeURL :( NSString *) aBaseURL params :( NSDictionary *) aParams; @ endstatic WFHTTPRequest * export dobj = 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, ^ {includobj = [[super allocWithZone: NULL] init] ;}); return includobj ;} + (id) allocWithZone :( struct _ NSZone *) zone {return [self sharedInstance];}-(void) createCon NectionWithUrl :( NSString *) urlString params :( NSDictionary *) aParams delegate :( id <strong>) aDelegate {NSString * urlStr = [self serializeURL: [self defined: urlString] params: aParams]; NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: urlStr] cachePolicy: Invalid timeoutInterval: kWFRequestimeOutInterval]; [request setHT TPMethod: 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 <WFRequestDelegate>) aDelegate {[self createConnectionWithUrl: kSearchResto params: aParams delegate: aDelegate];}-( Void) Authorization :( id <WFRequestDelegate>) aDelegate {[self createConnectionWithUrl: kSearchCity params: nil delegate: aDelegate];}-(void) Authorization :( id <WFRequestDelegate>) aDelegate {[self createConnectionWithUrl: kCategoriesWithBusinesses params: nil delegate: aDelegate];} // (void) appendUTF8Body :( NSMutableData *) aBody dataString :( NSString *) aDataString // {// [aBody ap PendData: [aDataString dataUsingEncoding: bytes]; //}-(NSDictionary *) parseQueryString :( NSString *) query {interval * paramDict = [[NSMutableDictionary alloc] initWithDictionary: 0]; NSArray * paramArr = [query componentsSeparatedByString: @ "&"]; for (NSString * param in paramArr) {NSArray * elements = [param componentsSeparatedByString: @ "="]; if ([elements count] <= 1) {retur N nil;} NSString * key = [[elements objectAtIndex: 0] encoding: NSUTF8StringEncoding]; NSString * value = [[elements objectAtIndex: 1] encoding: NSUTF8StringEncoding]; [paramDict setObject: value forKey: key];} return paramDict;}-(NSString *) serializeURL :( NSString *) aBaseURL params :( NSDictionary *) aParams {NSURL * parsedURL = [NSURL URLWithString: [aBaseURL parameters: parameters]; NSMutableDictionary * paramsDic = [partition dictionaryWithDictionary: [self parseQueryString: [parsedURL query]; if (aParams) {[paramsDic parameters: 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 = [signSt Ring dataUsingEncoding: NSUTF8StringEncoding]; NSString * digestString = [SHA1 getSHAString: stringBytes]; if (digestString) {[paramsString appendFormat: @ "& sign = % @", [digestString uppercaseString]; NSLog (@"... % @... ", [NSString stringWithFormat: @" % @: // % @? % @ ", [ParsedURL scheme], [parsedURL host], [parsedURL path], [paramsString encoding: NSUTF8StringEncoding]); return [NSString stringWithFormat: @" % @: // % @? % @ ", [ParsedURL scheme], [parsedURL host], [parsedURL path], [paramsString encoding: 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 didR EceiveResponse :( 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: & err Or]; 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: ERROR handling code. }}// 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

Download the code. Next section describes data parsing, network programming, reflection (runtime)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.