1

I am taking over an old iOS project from developers no longer part of the project - the app is getting a rewrite and with that I am going to support iOS7 and upwards only.

So, I wanted to use AFNetworking 2.0 instead of ASIHTTPRequest - the reason behind this is NSURLSeesion. AFNetworking 2.0 supports NSURLSession and with that I can get my app to download content in the background at opportunistic times (According to Apple - NSURLSession must be used and Background Fetch mode turned on, for this to work? )

Let me start out by saying I am a new developer to iOS and networking stuff goes a little over my head - but I am determined to learn more about it and as much as I can. I have read AFNetworking documentation as well, but I fear since some of the terminology escapes me (Request, Response, Sterilisation, etc) - I am not grasping them 100%.

So, I took a look at the ASIHTTPRequest code the previous developer used to, from what I can see, build a GET / POST request - This is the code they used:

 + (ASIHTTPRequest*) buildRequest: (NSString*) url RequestType: (NSString*) requestType
 PostData: (NSString*) postData 
 Host: (NSString*) host  
ContentType: (NSString*) contentType 
 SoapAction: (NSString*) soapAction  
RequestProperties: (NSDictionary*) requestProperties
    {

        NSURL *url = [NSURL URLWithString: url];
        ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:u] autorelease];
        [request setDidFinishSelector:@selector(requestDone:)];
        [request setDidFailSelector:@selector(requestWentWrong:)];
        [request setTimeOutSeconds:20];
        [request setQueuePriority:NSOperationQueuePriorityVeryHigh];

        if (host != nil)
            [request addRequestHeader: @"Host" value: host];

        if (contentType != nil)
            [request addRequestHeader: @"Content-Type" value: contentType];

        if (soapAction != nil)
            [request addRequestHeader: @"SOAPAction" value:soapAction];

        if (requestType != nil)
            [request setRequestMethod: requestType];

        if (postData != nil)
        {
            NSMutableData* mPostData = [NSMutableData dataWithData:[postData dataUsingEncoding:NSUTF8StringEncoding]];
            NSString *msgLength = [NSString stringWithFormat:@"%d", [postData length]];
            [request setPostBody: mPostData];
            [request addRequestHeader: @"Content-Length" value:msgLength];  
        }

        if (requestProperties != nil)
        {
            for (int i = 0; i < [[requestProperties allKeys] count]; i++)
            {
                [request addRequestHeader:[[requestProperties allKeys] objectAtIndex: i]   value: [requestProperties objectForKey:[[requestProperties allKeys] objectAtIndex: i]]];
            }
        }
        return request;
    }

I'm trying to understand this code and upgrade it to use AFNetworking V2.0 instead. I assume, just replacing ASIHTTPRequest with AFHTTPRequestOperation will not do the trick, correct?

halfer
  • 19,824
  • 17
  • 99
  • 186
Robert J. Clegg
  • 7,231
  • 9
  • 47
  • 99
  • just replacing ASIHTTPRequest with AFHTTPRequestOperation will not do the trick. Have a look at other open source projects that use AFNetworking (and/or ASIHTTPRequest) to get an idea of how it is implemented. – Nitin Alabur Oct 22 '13 at 14:03
  • Thanks for the feedback. I will try find some projects to look over. – Robert J. Clegg Oct 23 '13 at 03:45

1 Answers1

0

I have been given some help and also managed to do a lot of digging around to see how I can get this right.

I made the method simpler - as I did not need Soap / Content-type, etc - just urlParamerters and some basic stuff:

This is the answer I came up with:

+ (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");


           NSData *xmlData = responseObject;
           NSLog(@"Got XML Data: %@", xmlData);
       }
            failure:^(NSURLSessionDataTask *dataTask, NSError *error){

                    //Failure
                NSLog (@"Failure");


            }];

       }else if ([requestType isEqualToString:@"GT"]){

           [manager POST:url parameters:postData success:^(NSURLSessionDataTask *dataTask, id responseObject){

                   //Success

           }
                failure:^(NSURLSessionDataTask *dataTask, NSError *error){

                        //Failure
                    NSLog (@"Failure");


                }];

       }


    return manager;
}

It will work for what I need it to do - but I am not sure if it's the best way to do it.

I couldn't see how I could detect the requestType other thank with looking at the NSString value. I looked into the AFHTTPSessionManager.h file for some clues on what to do with that - Matt suggests overriding the GET / POST methods if I want them done differently - per his comments in the header file:

Methods to Override

To change the behavior of all data task operation construction, which is also used in the GET / POST / et al. convenience methods, override dataTaskWithRequest:completionHandler:.

Also there is a requestSerializer property in that file - which you could use to detect the type of request - however it's implementation goes to the super class: AFURLSessionManager

In that class - there is a requestWithMethodmethod.

So, I tried to do this instead:

If I try implement that method - then I am not using the convince methods in AFHTTPSessionManager:

 (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(NSDictionary *)parameters
                      success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                      failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;

Unless I have that completely wrong. After that I decided to just check the requestType using [NSString isEqualToString]

halfer
  • 19,824
  • 17
  • 99
  • 186
Robert J. Clegg
  • 7,231
  • 9
  • 47
  • 99
  • (I've converted this old request for feedback into an answer, since an answer containing new questions is liable to be deleted in the Review Queue. It looks OK to me now). – halfer Nov 26 '17 at 22:43