0

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.

Pranav Kasetti
  • 8,770
  • 2
  • 50
  • 71
  • `responseObject` You need to use of the `AF...ResponseSerializer`(https://github.com/AFNetworking/AFNetworking/tree/c80dd7930ee24e4d072c012b22aac6f8eaef8acb#serialization), and you'll have a Dictionary, Array etc according to your parser. For the `responseString`, it's just `[[NSString alloc] initWithData: responseData encoding: NSUTF8StringEncoding]`, nothing fancy here. – Larme Nov 21 '20 at 11:49
  • bonjour en faite j'avais deja commencé a faire ça pour le responseString cependant j'ai cette erreur là de temps en temps et qui me fait cracher l'application. Exception NSException * "-[__NSSingleEntryDictionaryI bytes]: unrecognized selector sent to instance 0x600000ae1b60" 0x00006000000f65e0 – Davy GRACIA Nov 23 '20 at 14:32
  • I'm French, so I'm okay, but I suggest you write in English. "[__NSSingleEntryDictionaryI bytes] Where? It saying you think an object is a `NSData`, but it's in fact a `NSDictionary`, but we can't guess what's wrong. – Larme Nov 23 '20 at 14:33
  • So when I mage Get request and I receive success with NSURLSessionDataTask and id responseObject. and I recieve and XML value, but i would like to copy responseObject to change to responseString and when I made [[NSString alloc] initWithData: responseData encoding: NSUTF8StringEncoding] . The application crash with this error 'NSInvalidArgumentException', reason: '-[NSXMLParser dataUsingEncoding:]: or Exception NSException * "-[__NSSingleEntryDictionaryI bytes]: unrecognized selector if I have other format – Davy GRACIA Nov 24 '20 at 15:18
  • Could you show your full code? Because it seems that you put a response serialize, a JSON one if I had to guess.. – Larme Nov 24 '20 at 15:20

2 Answers2

0

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];
    }}
  • If you use the XML response serializer, you’ll get the Dictionary instead of NSData. Why do you need it by the way? – Larme Nov 24 '20 at 19:47
  • Some time I receive json reponse and some time I receive xml response in responseObject. But I would like to treat response to made responseString. and when I would like to treat the response I have this tow error NsxmlParser or NSdictionnary.'NSInvalidArgumentException', reason: '-[NSXMLParser dataUsingEncoding:]: or Exception NSException * "-[__NSSingleEntryDictionaryI bytes]: unrecognized selector. – Davy GRACIA Nov 25 '20 at 08:20
  • my responseObject is sometime like this value so I will to transform the response to made treatment data after responseObject _NSInlineData * 929 bytes – Davy GRACIA Nov 25 '20 at 08:28
  • for json request I receive responseObject __NSSingleEntryDictionaryI * 1 key/value pair so it's ok and for xml I have this responseObject NSXMLParser * – Davy GRACIA Nov 25 '20 at 08:31
0

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];
Larme
  • 24,190
  • 6
  • 51
  • 81