AFnetworking 3 or 4 GET ResponseObject how to have responseString and ResponseData

338 Views Asked by At

Hello I would like to know how it's possible to have responseString and responseObject with the new version of AFNetworking.

When I made GET operation I have success response with NSURLSessionDataTask and id responseData.

And I would like to have responseString and responseObject.

Thanks for your help.

2

There are 2 best solutions below

4
Davy GRACIA On

there is my code not the full code but it's like that

void(^wsFailure)(NSURLSessionDataTask *, NSError *) = ^(NSURLSessionDataTask *failedOperation, NSError *error) {

         NSLog(@"failed %@",failedOperation);

        [self failedWithOperation:failedOperation error:error];
      };
      void (^wsSuccess)(NSURLSessionDataTask *, id) = ^(NSURLSessionDataTask * _Nonnull succeedOperation, id _Nullable responseObject) {
               NSLog(@"responseData: %@", responseObject);
            NSString *str = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
            NSLog(@"responseData: %@", str);

    }}


AFHTTPResponseSerializer *responseSerializer = [self responseSerializerFromResponseType];
    AFHTTPRequestSerializer *requestSerializer = [self requestSerializerFromRequestType];

operationManager.requestSerializer = requestSerializer;
operationManager.responseSerializer = responseSerializer;
- (AFHTTPResponseSerializer *)responseSerializerFromResponseType{    
if ([self.request.parameters[@"responseType"] isEqualToString:@"xml"]) {
        return [AFXMLParserResponseSerializer serializer];
    }
    else if ([self.request.parameters[@"responseType"] isEqualToString:@"html"]) {
        return [AFHTTPResponseSerializer serializer];
    }}
0
Larme On

Quickly done, I implemented my own ResponseSerializer, which is just a way to encapsulate a AFNetworkingSerializer (~AFHTTPResponseSerializer which is the superclass of the other ones, and respects the AFURLResponseSerialization protocol) which will return a custom serialized object, which will have the 2 properties you want in addition to the NSDictionary/NSArray serialized object: a NSData and a NSString.

.h

@interface CustomResponseSerializer : NSObject <AFURLResponseSerialization>
-(id)initWithResponseSerializer:(id<AFURLResponseSerialization>)serializer;
@end

.m

@interface CustomResponseSerializer()
@property (nonatomic, strong) id<AFURLResponseSerialization> serializer;
@end

@implementation CustomResponseSerializer

-(id)initWithResponseSerializer:(id<AFURLResponseSerialization>)serializer {
    self = [super init];
    if (self)
    {
        _serializer = serializer;
    }
    return self;
}

- (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response data:(nullable NSData *)data error:(NSError * _Nullable __autoreleasing * _Nullable)error {

    id serialized = nil;
    if ([_serializer respondsToSelector:@selector(responseObjectForResponse:data:error:)]) {
        NSError *serializationError = nil;
        serialized = [_serializer responseObjectForResponse:response data:data error:&serializationError];
    }
    //You could put NSError *serializationError = nil; before, and set it into the `CustomSerializedObject` `error` property, I didn't check more about AFNetworking and how they handle a parsing error
    
    return [[CustomSerializedObject alloc] initWithData:data
                                                 string:[[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding]
                                                 object:serialized];
}

+ (BOOL)supportsSecureCoding {
    return YES;
}

- (void)encodeWithCoder:(nonnull NSCoder *)coder {
    [coder encodeObject:self.serializer forKey:NSStringFromSelector(@selector(serializer))];
}

- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {
    self = [self init];
    if (!self) {
        return nil;
    }

    self.serializer = [coder decodeObjectForKey:NSStringFromSelector(@selector(serializer))];
    return self;

}

- (nonnull id)copyWithZone:(nullable NSZone *)zone {
    CustomResponseSerializer *serializer = [[CustomResponseSerializer allocWithZone:zone] init];
    serializer.serializer = [self.serializer copyWithZone:zone];
    return serializer;
}
@end

And the object:

@interface CustomSerializedObject: NSObject
@property (nonatomic, strong) NSData *rawData;
@property (nonatomic, strong) NSString *string;
@property (nonatomic, strong) id object;
@property (nonatomic, strong) NSError *error; //If needed

-(id)initWithData:(NSData *)data string:(NSString *)string object:(id)object;
@end
@implementation CustomSerializedObject

-(id)initWithData:(NSData *)data string:(NSString *)string object:(id)object {
    self = [super init];
    if (self)
    {
        _rawData = data;
        _string = string;
        _object = object;
    }
    return self;
}
@end

How to use:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

NSURL *URL = [NSURL URLWithString:@"https://httpbin.org/get"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

CustomResponseSerializer *responseSerializer = [[CustomResponseSerializer alloc] initWithResponseSerializer:[AFJSONResponseSerializer serializer]];
[manager setResponseSerializer: responseSerializer];
NSURLSessionDataTask *task = [manager dataTaskWithRequest:request
                                           uploadProgress:nil
                                         downloadProgress:nil
                                        completionHandler:^(NSURLResponse * _Nonnull response, CustomSerializedObject * _Nullable responseObject, NSError * _Nullable error) {
    NSLog(@"Response: %@", response);
    NSLog(@"ResponseObject data: %@", responseObject.rawData); //If you want hex string ouptut see https://stackoverflow.com/questions/1305225/best-way-to-serialize-an-nsdata-into-a-hexadeximal-string
    NSLog(@"ResponseObject str: %@", responseObject.string);
    NSLog(@"ResponseObject object: %@", responseObject.object);
    NSLog(@"error: %@", error);
}];
[task resume];