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
initWithURLmethod - is this a good way to build a URL based onNSDictionaryparameters?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 anNSStringvalue.
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.