Я недавно прошел через то же самое, что и вы.Вот пользовательский класс, который я написал для обработки практически любого сетевого запроса.
NetworkClient.h:
//
// NetworkClient.h
//
// Created by LJ Wilson on 3/8/12.
// Copyright (c) 2012 LJ Wilson. All rights reserved.
//
#import <Foundation/Foundation.h>
extern NSString * const ACHAPIKey;
@interface NetworkClient : NSObject
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
block:(void (^)(id obj))block;
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
syncRequest:(BOOL)syncRequest
block:(void (^)(id obj))block;
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
syncRequest:(BOOL)syncRequest
alertUserOnFailure:(BOOL)alertUserOnFailure
block:(void (^)(id obj))block;
+(void)handleNetworkErrorWithError:(NSError *)error;
+(void)handleNoAccessWithReason:(NSString *)reason;
@end
NetworkClient.m:
//
// NetworkClient.m
//
// Created by LJ Wilson on 3/8/12.
// Copyright (c) 2012 LJ Wilson. All rights reserved.
//
#import "NetworkClient.h"
#import "AFHTTPClient.h"
#import "AFHTTPRequestOperation.h"
#import "SBJson.h"
NSString * const APIKey = @"APIKeyIfYouSoDesire";
@implementation NetworkClient
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
block:(void (^)(id obj))block {
[self processURLRequestWithURL:url andParams:params syncRequest:NO alertUserOnFailure:NO block:^(id obj) {
block(obj);
}];
}
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
syncRequest:(BOOL)syncRequest
block:(void (^)(id obj))block {
if (syncRequest) {
[self processURLRequestWithURL:url andParams:params syncRequest:YES alertUserOnFailure:NO block:^(id obj) {
block(obj);
}];
} else {
[self processURLRequestWithURL:url andParams:params syncRequest:NO alertUserOnFailure:NO block:^(id obj) {
block(obj);
}];
}
}
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
syncRequest:(BOOL)syncRequest
alertUserOnFailure:(BOOL)alertUserOnFailure
block:(void (^)(id obj))block {
// Default url goes here, pass in a nil to use it
if (url == nil) {
url = @"MyDefaultURLGoesHere";
}
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:params];
[dict setValue:APIKey forKey:@"APIKey"];
NSDictionary *newParams = [[NSDictionary alloc] initWithDictionary:dict];
NSURL *requestURL;
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:requestURL];
NSMutableURLRequest *theRequest = [httpClient requestWithMethod:@"POST" path:url parameters:newParams];
__block NSString *responseString = [NSString stringWithString:@""];
AFHTTPRequestOperation *_operation = [[AFHTTPRequestOperation alloc] initWithRequest:theRequest];
__weak AFHTTPRequestOperation *operation = _operation;
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
responseString = [operation responseString];
id retObj = [responseString JSONValue];
// Check for invalid response (No Access)
if ([retObj isKindOfClass:[NSDictionary class]]) {
if ([[(NSDictionary *)retObj valueForKey:@"Message"] isEqualToString:@"No Access"]) {
block(nil);
[self handleNoAccessWithReason:[(NSDictionary *)retObj valueForKey:@"Reason"]];
}
} else if ([retObj isKindOfClass:[NSArray class]]) {
NSDictionary *dict = [(NSArray *)retObj objectAtIndex:0];
if ([[dict valueForKey:@"Message"] isEqualToString:@"No Access"]) {
block(nil);
[self handleNoAccessWithReason:[(NSDictionary *)retObj valueForKey:@"Reason"]];
}
}
block(retObj);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failed with error = %@", [NSString stringWithFormat:@"[Error]:%@",error]);
block(nil);
if (alertUserOnFailure) {
[self handleNetworkErrorWithError:operation.error];
}
}];
[operation start];
if (syncRequest) {
// Only fires if Syncronous was passed in as YES. Default is NO
[operation waitUntilFinished];
}
}
+(void)handleNetworkErrorWithError:(NSError *)error {
NSString *errorString = [NSString stringWithFormat:@"[Error]:%@",error];
// Standard UIAlert Syntax
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:@"Connection Error"
message:errorString
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[myAlert show];
}
+(void)handleNoAccessWithReason:(NSString *)reason {
// Standard UIAlert Syntax
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:@"No Access"
message:reason
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[myAlert show];
}
@end
Это добавляет впара функций, которые вам могут не понадобиться или которые вам не нужны, не стесняйтесь изменять их по мере необходимости, пока сохраняется раздел «Авторское право».Я использую этот APIKey для проверки запроса, полученного от моего приложения, а не от того, кто пытается его взломать.
Вызов его (при условии, что вы включили NetworkClient.h:
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
@"ParamValue1", @"ParamName1",
@"ParamValue2", @"ParamName2",
nil];
[NetworkClient processURLRequestWithURL:nil andParams:params block:^(id obj) {
if ([obj isKindOfClass:[NSArray class]]) {
// Do whatever you want with the object. In this case, I knew I was expecting an Array, but it will return a Dictionary if that is what the web-service responds with.
}
}];
Также может:
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
@"ParamValue1", @"ParamName1",
nil];
NSString *urlString = @"https://SuppliedURLOverridesDefault";
[NetworkClient processURLRequestWithURL:urlString
andParams:params
syncRequest:YES
alertUserOnFailure:NO
block:^(id obj) {
if ([obj isKindOfClass:[NSArray class]]) {
// Do stuff
}
}];
Таким образом, он будет принимать любое количество параметров, вводить APIKey или что-либо еще, если вы хотите, и возвращать обратно словарь или массив в зависимости от веб-службы. Это действительно ожидает SBJson BTW.