I am pretty new to iOS development - I'm writing an app the uses web services, pretty extensively. With that in mind, I decided to use AFNetworking 2.0 and subclass AFHTTPSessionManager
.
I created a method to build a URL for me - based on NSDictionary
parameters and then I use the URL with the parameters to execute a GET / POST / PUT request. My worry is the last part - have I made this class less readable and less manageable by doing that?
BBWebService.h
#import <Foundation/Foundation.h>#import "AFNetworking.h"@interface BBWebService : AFHTTPSessionManager@property (strong, nonatomic) NSData *responseData; //Designated Initilizer- (id) initWithURL: (NSString*) url RequestType: (NSString*) requestType PostDataValuesAndKeys: (NSDictionary*) postData RequestProperties: (NSDictionary*) requestProperties UrlParameters: (NSDictionary*) urlParameters;@end
BBWebService.m
import "BBWebService.h"@interface BBWebService ()@end@implementation BBWebService- (id) initWithURL: (NSString*) url RequestType: (NSString*) requestType PostDataValuesAndKeys: (NSDictionary*) postData RequestProperties: (NSDictionary*) requestProperties UrlParameters: (NSDictionary*) urlParameters { self = [super init]; if (self) { NSString* urlWithParameters = [NSString stringWithString: url]; // check to see if url parameters have been specified if (urlParameters != nil) { NSString *paramString = nil; // Work-around for URLs that may use a parameter to indicate an "action" instead of a path in the URL itself. BOOL hasQuestionMark = NO; NSRange textRange; textRange = [urlWithParameters rangeOfString:@"?"]; if(textRange.location != NSNotFound) { hasQuestionMark = YES; } for (int i = 0; i < [[urlParameters allKeys] count]; i++) { if (i == 0) { if (hasQuestionMark == YES) { paramString = [NSString stringWithFormat: @"&%@=%@", [[urlParameters allKeys] objectAtIndex: i], [urlParameters objectForKey:[[urlParameters allKeys] objectAtIndex: i]]]; } else { paramString = [NSString stringWithFormat: @"?%@=%@", [[urlParameters allKeys] objectAtIndex: i], [urlParameters objectForKey:[[urlParameters allKeys] objectAtIndex: i]]]; } } else { paramString = [NSString stringWithFormat: @"%@&%@=%@", paramString, [[urlParameters allKeys] objectAtIndex: i], [urlParameters objectForKey:[[urlParameters allKeys] objectAtIndex: i]]]; } } urlWithParameters = [url stringByAppendingString:paramString]; urlWithParameters = [urlWithParameters stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSLog(@"Url with encoded parameters: %@", urlWithParameters); } __unused AFHTTPSessionManager* sessiomNamager = [BBWebService buildRequest:urlWithParameters RequestType:requestType PostDataValuesAndKeys:postData RequestProperties:requestProperties]; } return self;} //Class method+ (AFHTTPSessionManager *) buildRequest: (NSString*) url RequestType: (NSString*) requestType PostDataValuesAndKeys: (NSDictionary*) postData RequestProperties: (NSDictionary*) requestProperties{ AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; if ([requestType isEqualToString:@"GET"]) { [manager GET:url parameters:postData success:^(NSURLSessionDataTask *dataTask, id responseObject){ //Success NSLog (@"Success"); } failure:^(NSURLSessionDataTask *dataTask, NSError *error){ //Failure NSLog (@"Failure"); }]; }else if ([requestType isEqualToString:@"POST"]){ [manager POST:url parameters:postData success:^(NSURLSessionDataTask *dataTask, id responseObject){ //Success NSLog (@"Success!!"); } failure:^(NSURLSessionDataTask *dataTask, NSError *error){ //Failure NSLog (@"Failure"); }]; }else if ([requestType isEqualToString:@"PUT"]){ [manager PUT:url parameters:postData success:^(NSURLSessionDataTask *dataTask, id responseObject){ //Success } failure:^(NSURLSessionDataTask *dataDask, id responseObject){ //Failure }]; } return manager;}@end
Questions:
In my designated
initWithURL
method - is this a good way to build a URL based onNSDictionary
parameters?With the class method:
builRequest
- I looked in the header file ofAFHTTPSessionManager.h
- I couldn't see a way to properly detect therequestType
(GET/POST, etc) - and this is why I am checking with anNSString
value.
I worry that should someone else use this class and they type / spell the GET / POST part wrong - the service won't run and it may be a hard to track bug as the compiler won't show a warning for NSString
values.
This is how I would use this method in another class:
BBWebService *newWebService = [[BBWebService alloc]initWithURL:URL RequestType:@"GET" PostDataValuesAndKeys:nil RequestProperties:nil UrlParameters:nil];
I am aware I have not added the class method to the header file - reason being is I am still finishing the rest of the file - and I have not decided yet if I want it exposed.