JSON parsing with AFNetworking and model Class - ios

I am bit confused in fetching data and displaying data from json into my App using Model.
I am having this kind of json data :
{
result
[
{
key : value
key : value
key : value
}
{
key : value
key : value
key : value
}
]
}
I am trying this kind of code:
json = [[NSMutableArray alloc]init];
NSError *writeError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:&writeError];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&writeError];
json = dic[#"Result"];
int i;
for (i = 0; i <= json.count; i++)
{
NSMutableArray *array = json[i];
[json enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop)
{
// Dim = [[DimEntityFull alloc]initWithJSONDictionary:obj];
saveSearch = [[SaveSearchMaster alloc]initWithJSONDictionary:obj];
} ];
}
I am using "AFNetworking" and I am trying to fetch data and store into model class and then display to custom cell labels.
How can I get it.
Thank You.

In your view controller
- (void)viewDidLoad
{
[super viewDidLoad];
[self getUsersList];
}
-(void)getUsersList
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"application/json"];
[manager POST:[NSString stringWithFormat:#"http://www.yourdomainname.com/getUserList"] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject)
{
//we will add Modal class objects of users in this array
usersArray=[[NSMutableArray alloc]init];
//getting result dictionary from response
NSDictionary *resultDictinary = [responseObject objectForKey:#"result"];
for (NSDictionary *userDictionary in resultDictinary)
{
//allocating new user from the dictionary
User *newUSer=[[User alloc]initWithDictionary:userDictionary];
[usersArray addObject:newUSer];
}
//in users array, you have objects of User class
//reload your tableview data
[self.TableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
Now Create New file Called 'User'
in User.h
#interface User : NSObject
{
NSString *userID;
NSString *firstName;
NSString *lastName;
}
#property (nonatomic, retain)NSString *userID;
#property (nonatomic, retain)NSString *firstName;
#property (nonatomic, retain)NSString *lastName;
-(id)initWithDictionary:(NSDictionary *)sourceDictionary;
#end
in User.m
#import "User.h"
#implementation User
#synthesize userID,firstName,lastName;
-(id)initWithDictionary:(NSDictionary *)sourceDictionary
{
self = [super init];
if (self != nil)
{
self.firstName=[sourceDictionary valueForKey:#"firstName"];
self.lastName=[sourceDictionary valueForKey:#"lastName"];
self.userID=[sourceDictionary valueForKey:#"userID"];
}
return self;
}
#end
in your numberOfRowsInSectionmethod
return usersArray.count;
in your cellForRowAtIndexPath method
User *user=(User *)[usersArray objectAtIndex:indexPath.row];
yourLabel.text=user.firstName;

Related

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

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.
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];
}}
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];

Instance of ViewController returns nil

I have the instance of HomeViewController as follows. I am trying to access its properties, which hold dataset. However, whenever I check in the other class -GlobalFunctions all of the HomeViewController properties are nil.
HomeViewController.h
#property (nonatomic, strong) NSMutableArray *pTempElements;
+(HomeViewController*) homeDataInstance;
HomeViewController.m
+(HomeViewController*) homeDataInstance {
static HomeViewController *dataInstance;
#synchronized(self) {
if(!dataInstance){
dataInstance = [[HomeViewController alloc] init];
}
}
return dataInstance;
}
-(void)loadFromURL {
NSString *path = [[NSBundle mainBundle] pathForResource:#"Settings" ofType:#"plist"];
NSDictionary *settings = [[NSDictionary alloc] initWithContentsOfFile:path];
NSString *PRODUCT_ALL_URL = [settings objectForKey: #"PRODUCT_ALL_URL"];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:PRODUCT_ALL_URL parameters:nil progress: nil success:^(NSURLSessionTask * _Nonnull operation, id responseObject) {
if(responseObject != NULL) {
ProductData *dicItem = [[ProductData alloc]init];
for ( id jsonItem in responseObject)
{
dicItem = [[ProductData alloc]initWithDictionary:jsonItem];
[self.pElements addObject:dicItem];
}
self.pTempElements = pElements;
[self.productCollectionView reloadData];
}
} failure:^(NSURLSessionTask * _Nullable operation, NSError * _Nonnull error) {
}];
}
GlobalFunctions.m
HomeViewController *restaurantData = [HomeViewController homeDataInstance];
// the following is nil
NSLog(#"%#", restaurantData.pTempElements);
restaurantData is all nil as follows in the GlobalFunctions class.
From the code snippet and screenshot you have shared, we can clearly see that your instance is successfully created.
The property values are showing nil because you have not assigned any values to them. Try assigning initial values to those properties.
For UI related properties either you should map them in your .xib or .storyboard file so that they are initialised with some value or initialize them in your code somewhere before using them.
e.g In your case: productCollectionView and categoryCollectionView
Similarly incase of other properties.
Hope my answer helps!
your problem is with singleton object. try this class method:
+(instancetype)sharedInstance{
static storeViewController *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[storeViewController alloc] init];
});
return sharedInstance;
}
Try like this!
#import "WebService.h"
static WebService *webService;
#implementation WebService
+(WebService *)sharedWebService{
if(!webService){
webService = [[WebService alloc] init];
}
return webService;
}
In .h file
#import <Foundation/Foundation.h>
#interface WebService : NSObject
+(WebService *)sharedWebService;
#property (nonatomic, strong) NSMutableArray *pTempElements;
Try this funtion using block
-(void)loadFromURLWithCallback:(void(^)(NSArray *pTempElements))callback {
// add this condition if your dont need to refresh data
if (self.pElements) {
callback(self.pElements)
[self.productCollectionView reloadData];
return;
}
NSString *path = [[NSBundle mainBundle] pathForResource:#"Settings" ofType:#"plist"];
NSDictionary *settings = [[NSDictionary alloc] initWithContentsOfFile:path];
NSString *PRODUCT_ALL_URL = [settings objectForKey: #"PRODUCT_ALL_URL"];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:PRODUCT_ALL_URL parameters:nil progress: nil success:^(NSURLSessionTask * _Nonnull operation, id responseObject) {
if(responseObject != NULL) {
ProductData *dicItem = [[ProductData alloc]init];
for ( id jsonItem in responseObject)
{
dicItem = [[ProductData alloc]initWithDictionary:jsonItem];
[self.pElements addObject:dicItem];
}
self.pTempElements = pElements;
[self.productCollectionView reloadData];
callback(elf.pTempElements)
}
} failure:^(NSURLSessionTask * _Nullable operation, NSError * _Nonnull error) {
callback(nil);
}];
}
calling of method
[self loadFromURLWithCallback:^(NSArray *pTempElements) {
}];

AFNetworking 3.0 GET request save into class in iOS

After searching the internet for how to use AFNetworking 3.0 to save the response object inside a custom class, all that I found is the basic usage of AFNetworking library with GET requests such as GET request using AFNetworking and saving response and AFNetworking send array in JSON parameters of GET request.
Code:
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
listOfEventsObjects = [#[] mutableCopy];
self.tableView.delegate = self;
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:#"http://api.com.getevents.php" parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSArray *h = [responseObject objectForKey:#"events"];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:h options:0 error:&error];
NSArray *json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
for (int i = 0 ; i < [json count]; i++) {
geeksEvent *h1 = [geeksEvent new];
//h1.eventId = [];
//h1.eventId = [[json valueForKey:#"eventId"] intValue];
//NSLog(#"json data is: %#",h1);
}
// events = [responseObject objectForKey:#"events"];
if ([responseObject isKindOfClass:[NSArray class]]) {
// NSArray *responseArray = responseObject;
NSLog(#"array");
/* do something with responseArray */
} else if ([responseObject isKindOfClass:[NSDictionary class]]) {
NSLog(#"dictionary");
NSDictionary *responseDict = responseObject;
// NSDictionary *responseDict = responseObject;
/* do something with responseDict */
}
// AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
//
// responseSerializer = [AFJSONResponseSerializer serializer];
// responseSerializer.acceptableContentTypes = [NSSet setWithObjects:#"application/json; charset=UTF-8", nil];
//
// // NSArray *data = (responseObject *) NSArray;
// NSError *error;
// NSData *data = (NSData *) responseObject;
// // NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:errno error:&error];
//
//
// NSLog(#"JSon arrays is: %#",data);
//NSDictionary *jsonDict = (NSDictionary *) responseObject;
//
// NSLog(#"%lu",(unsigned long)events.count);
//
// for (int i = 0; i < [events count]; i ++) {
//
// geeksEvent *event = [events objectAtIndex:i];
//
//
// NSLog(#"event %d is %#",i,event);
//
//
// #try {
//
// event.eventId = [[events valueForKey:#"eventId"]intValue];
//
// event.eventTitle = [[events valueForKey:#"eventTitle"] componentsJoinedByString:#""];
//
// event.eventShortDiscription = [[event valueForKey:#"eventShortDesc"] componentsJoinedByString:#""];
// event.eventDescription = [[event valueForKey:#"eventDescription"] componentsJoinedByString:#""];
//
// event.eventDate = [events valueForKey:#"eventDate"];
// event.eventTime = [events valueForKey:#"eventTime"];
// event.eventUrl = [events valueForKey:#"eventUrl"];
//
// [listOfEventsObjects addObject:event];
//
// } #catch (NSException *exception) {
//
// NSLog(#"%#",exception);
//
// } #finally {
//
// }
//
// }
[self.tableView reloadData];
I cannot figure out how to save the response object into custom class.
geeksEvent ## custom class:
.h
#import <Foundation/Foundation.h>
#interface GeeksLocations : NSObject
#property (nonatomic) int geeksBranchId;
#property(nonatomic) double *geeksLongtitude;
#property (nonatomic) double *geeksLatitude;
#property (nonatomic,strong) NSString *geeksAddress;
#property (nonatomic,strong) NSString *geeksMobile;
#property (nonatomic,strong) NSString *geeksTel;
#property (nonatomic,strong) NSString *geeksOpenDays;
#property (nonatomic,strong) NSDate *geeksOpenTime;
#end
.m
#import "GeeksLocations.h"
#implementation GeeksLocations
#synthesize geeksBranchId;
#synthesize geeksLongtitude;
#synthesize geeksLatitude;
#synthesize geeksMobile;
#synthesize geeksTel;
#synthesize geeksAddress;
#synthesize geeksOpenDays;
#synthesize geeksOpenTime;
#end
Response
{"success":1,"events":[{"eventId":"1","eventTitle":"Open Wings Tuesday","eventShortDesc":"we are offering open wings all the day","eventDiscription":null,"eventDate":"2016-05-22","eventTime":"12:49:00","eventUrl":"http://www.code-bee.net/geeks/images/cover-7.jpg"},{"eventId":"2","eventTitle":"Testing","eventShortDesc":"Testing","eventDiscription":null,"eventDate":"2016-05-22","eventTime":"12:49:00","eventUrl":"http://www.code-bee.net/geeks/images/cover-8.jpg"}]
Add all events to an array, you will then have an array of dictionaries. Also make a new array which will hold your new instances.
Now:
for (NSDictionary *dictionary in myArrayContainingAllEvents){
GeeksLocation *location = [GeeksLocation alloc] initWithDictionary:dictionary];
[newArrayForInstances addObject: location];
}
In the GeeksLocation class add the following initializer:
-(instanceType)initWithDictionary: (NSDictionary *) dictionary{
self = [super init];
if(self){
self.geeksAddress = [dictionary objectForKey:address];
self..... = [dictionary objectForKey:.......];
}
return self;
}
Hope this helps

Why is there a long delay between json data being retrieved and viewcontroller being displayed

I have a problem with a long delay between a JSON data retrieval and the starting of a UITableViewController.
The method below uses a hardcoded query that is called from the UITableViewControllers initializer, and retrieves and displays the data within 2 seconds.
- (void)productsQuery
{
NSString *requestString = #"http://192.168.2.10/testQueries.php?Product_Description=tea";
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSArray *returnedItems =
[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
for (int i = 0; i < [returnedItems count]; i++) {
NSDictionary *item = [returnedItems objectAtIndex:i];
NSNumber *nBay = [item objectForKey:#"Bay_Number"];
NSNumber *nShelf = [item objectForKey:#"Shelf_Number"];
NSNumber *coordX = [item objectForKey:#"CoordinateX"];
NSNumber *coordY = [item objectForKey:#"CoordinateY"];
TNWProduct *product =[[TNWProduct alloc]
initWithProductDescription:[item objectForKey:#"Product_Description"]
aisleNumber:[item objectForKey:#"Aisle_Number"]
bay:[nBay intValue]
shelf:[nShelf intValue]
nonAisleLocation:[item objectForKey:#"Location_Description"]
coordinateX:[coordX intValue]
coordinateY:[coordY intValue]];
[self.productList addObject:product];
}
NSLog(#"%#", self.productList);
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}];
[dataTask resume];
}
The method was then adapted and moved to a UIView controller so that the query could be input by the user.
The JSON data is still retrieved and added to the NSMutableArray _productList in 2 seconds, as it shows in the console from the NSLog call, but then appears to do nothing for 5-15 seconds until starting the ProductListViewController.
#interface TNWSearchViewController () <UITextFieldDelegate>
#property (weak, nonatomic) NSString *userQuery;
#property (weak, nonatomic) IBOutlet UIToolbar *toolbar;
#property (weak, nonatomic) IBOutlet UITextView *informationMessages;
#property (nonatomic) NSURLSession *session;
#property (nonatomic, strong) NSMutableArray *productList;
#property (nonatomic, strong) NSArray *returnedItems;
#end
#implementation TNWSearchViewController
.
.
.
.
- (void)productQuery:(NSString *)query
{
if ([_productList count] > 0 ) {
[_productList removeAllObjects];
}
NSMutableString *requestString = [#"http://192.168.2.10/testQueries.php?Product_Description=" mutableCopy];
[requestString appendString:query];
NSString *escapedRequestString = [requestString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#", escapedRequestString);
NSURL *url = [NSURL URLWithString:escapedRequestString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
_returnedItems =
[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
//NSLog(#"Returned items = %#", _returnedItems);
for (int i = 0; i < [_returnedItems count]; i++) {
NSDictionary *item = [_returnedItems objectAtIndex:i];
//NSLog(#"Item = %#", item);
NSNumber *nBay = [item objectForKey:#"Bay_Number"];
NSNumber *nShelf = [item objectForKey:#"Shelf_Number"];
NSNumber *coordX = [item objectForKey:#"CoordinateX"];
NSNumber *coordY = [item objectForKey:#"CoordinateY"];
TNWProduct *product =[[TNWProduct alloc]
initWithProductDescription:[item objectForKey:#"Product_Description"]
aisleNumber:[item objectForKey:#"Aisle_Number"]
bay:[nBay intValue]
shelf:[nShelf intValue]
nonAisleLocation:[item objectForKey:#"Location_Description"]
coordinateX:[coordX intValue]
coordinateY:[coordY intValue]];
NSLog(#"%#", product);
[_productList addObject:product];
}
NSLog(#"Product list = %#", self.productList);
if ( [_productList count] > 0 ) {
TNWProductListViewController *plvc =
[[TNWProductListViewController alloc] initWithStyle:UITableViewStylePlain];
plvc.productList = [self.productList mutableCopy];
[self.navigationController pushViewController:plvc animated:YES];
} else {
_informationMessages.text = #"No matches found";
}
}];
[dataTask resume];
}
Moving the code blocks from the for loop and the if/else statement below [dataTask resume] result in the app loading the UITableView as expected, but the data from _returnedItems is no longer accessible.
Assistance appreciated.
for (int i = 0; i < [_returnedItems count]; i++) {
.
.
.
} else {
_informationMessages.text = #"No matches found";
}
Moving the creation and call of the ViewController to the dispatch_async block as below fixed the issue.
Thanks Fonix.
dispatch_async(dispatch_get_main_queue(), ^{
if ( [[[TNWProductList productsStore] allProducts] count] > 0 ) {
TNWProductListViewController *plvc =
[[TNWProductListViewController alloc] initWithStyle:UITableViewStylePlain];
[self.navigationController pushViewController:plvc animated:YES];
} else {
_informationMessages.text = #"No matches found";
}

Issue with AFNetworking

My client webservice send me a result like this:
{"login":{"EMAIL":"none","ID":"none","NOME":"none"}}
So, in AFN doesn't work.
But, if have one more result works:
{"login":[{"EMAIL":"none","ID":"none","NOME":"none"},{"EMAIL":"none","ID":"none","NOME":"none"}]}
My code:
NSDictionary *paramLogin = [NSDictionary dictionaryWithObjectsAndKeys:_txtEmail.text, #"email",_txtSenha.text, #"senha", nil];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://webservice.info" parameters:paramLogin success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#" , responseObject );
for (NSDictionary *retLogin in [responseObject valueForKeyPath:#"login"]) {
nome = [retLogin objectForKey:#"nome"];
email = [retLogin objectForKey:#"email"];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
why it is like this? or what I've to do ?
Sometimes [responseObject valueForKeyPath:#"login"] returns and array, sometimes it returns a dictionary. You need to test for this.
id loginValue = [responseObject valueForKeyPath:#"login"];
if ([loginValue isKindOfClass:[NSDictionary class]]) {
nome = [loginValue objectForKey:#"nome"];
email = [loginValue objectForKey:#"email"];
} else if ([loginValue isKindOfClass:[NSArray class]]) {
for (NSDictionary *retLogin in [responseObject valueForKeyPath:#"login"]) {
nome = [retLogin objectForKey:#"nome"];
email = [retLogin objectForKey:#"email"];
}
} else {
// ERROR: Unexpected value
}
When you have 1 value, then loginValue is an NSDictionary. It contains {"EMAIL":"none","ID":"none","NOME":"none"}.
When you have more than 1 value, then loginValue is an NSArray. The array contains [<NSDictionary>, <NSDictionary>]. Each of of these dictionaries contains {"EMAIL":"none","ID":"none","NOME":"none"}.
Problem is with your json data structure. It's not consistent.
{"login":{"EMAIL":"none","ID":"none","NOME":"none"}}
Here [responseObject valueForKeyPath:#"login"] is a single NSDictionary object.
But here,
{"login":[{"EMAIL":"none","ID":"none","NOME":"none"},{"EMAIL":"none","ID":"none","NOME":"none"}]}
Here [responseObject valueForKeyPath:#"login"] is an NSArray. So your fast enumeration works.
Best solution is to ask your webservice developer to send an array all the time, even 'login' has a single object. so it should look like this,
{"login": [{"EMAIL":"none","ID":"none","NOME":"none"}]} //notice square brackets
Otherwise you have to modify your code to check for an NSDictionary instead of array when there's only one object.
I suspect the issue is that you aren't retaining the AFHTTPRequestOperationManager object.
Assuming this code is in something like viewDidAppear:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:...];
Then manager will be destroyed before it has a chance to complete.
Instead add a property and store the manager object in that:
#interface MyViewController ()
#property (nonatomic) AFHTTPRequestOperationManager *manager;
#end
and use:
self.manager = [AFHTTPRequestOperationManager manager];
[self.manager GET:...];
if you are getting response like that than use below code
NSMutableArray *category = [[NSMutableArray alloc]init];
category = [responseObject objectForKey:#"login"];
for(int i = 0; i < [category count]; i++)
{
NSDictionary *dic = [category objectAtIndex:i];
nome = [dic objectForKey:#"nome"];
email = [dic objectForKey:#"email"];
}

Resources