Error on saving object in AFIncrementalStore. ResponseObject is an NSArray instead if NSDictionary despite valid JSON resposne - afnetworking

All,
I am trying to solve an issue now for the last two days and seem incapable. Apologies in advance if asking for the obvious.
In a very simple data model I try to insert a new object user. (attributes: name, password and id which are respectively a NSString, a NSString and a NSNumber). The new object gets successfully created
in the API and the external MySQL server. However, in the completion block of the HTTPrequest when
(I think) the backing store is populated it tries to create the resource identifier.
This is were the app crashes in this method when it is trying to get allKeys from the representation dictionary:
(NSString *)resourceIdentifierForRepresentation:(NSDictionary *)representation ofEntity:(NSEntityDescription *)entity fromResponse:(NSHTTPURLResponse *)response
The JSON response getting back from the server is as follows:
[{"id":20,"name":"john doe","password":"secret"}]
Anyone a clue? Would be very grateful if I could solve the issue this year!!!
Side notes: Matt great job!
Side question: How will AFIS deal with local storage, local changes and synching with the server when a connection is back?
All,
Thanks in advance and enjoy 2013!!!
[Update]
The issue is that I get an NSArray back instead of a NSDictionary. I can simply fix it by changing the code in AFIS savecontext to pass the responseObject[0] however I prefer not to change the AFIS code and I still find it odd that I dont get an NSDictionary back when I have a valid JSON response

You can override the method that AFIS uses to get the resulting object from the json data.
- (id)representationOrArrayOfRepresentationsOfEntity:(NSEntityDescription*)entity
fromResponseObject:(id)responseObject
The response object should be your array with dictionary at index 0.

Related

NSDictionary inconsistent behaviour as params

I've found that when using NSDictionary to create the params for an AFNetworking POST request the behaviour is inconsistent. I have multiple POSTs where the params arrive at the server in the same order I created them in the NSDictionary and now creating a new request they are arriving at the server in a different order.
This is how I send them:
NSDictionary *params = #{#"username": #"testuser", #"count": #"6"};
But this is how it arrives on the server:
{"count":"6","username":"testuser"}
Its important for me that it arrive at the server exactly the same as it leaves my app as I hash together values for integrity and can't verify if it arrives in a different order to how it leaves.
I know NSDictionary is by nature not expected to keep the order, is there anyway using NSDictionary or another way I can guarantee the order?
Thanks in advance
You'd have to use an ordered dictionary class. Unfortunately, there's not one in the Foundation framework, but it's fairly easy to create (or even download) your own. This article describes how to create an ordered dictionary class in Objective-C, and includes source code.

Parse Product Link Returns null

I am using the Parse.com Store template and I am having trouble accessing parts of my data browser. I need to access a column called 'link' from the data browser and I do not seem to be able to. If I run linkLabel.text = self.product[#"link"]; and then NSLog it NSLog(#"%#", linkLabel.text]);
The value is returned as null.
So I decided to check what the value of 'link' is. I ran NSLog(#"%#", self.product[#"link"]); and still it returned null. I thought well there is something wrong with 'link' so i tried 'name' NSLog(#"%#", self.product[#"name"]);still... nothing (it returns (null)).
So I have no idea how to access link or name from my ViewController. I have even added #property (nonatomic, strong) PFObject *product; and still nothing.
I am able to access all of those objects but they do not get accessed by the servers. Now in my other view (that Parse.com built) when I run linkLabel.text = self.product[#"link"]; and then log it I get the value off of my data browser. So Basically I am doing something wrong and I need help! Thank you so much!
To access your data from parse ,you need to fire query and in return you get data for which you have provided a condition. Here's go with this link and parse and also go for google. You will find your way to fetch your data from parse. After receiving data you could populate the label's or view controller you want to.

How to prevent order changing in NSDictionary in ios

Hi In my application I have a login screen where I have to post credentials to C# server.The order which I used is as such below
username
password
domainname
Code:
NSDictionary*disPost=[[NSDictionary alloc]initWithObjectsAndKeys:#"naresh",#"UserName",#"n123",#"Password",#"naresh-in",#"DomainName",nil];
I can able to post the data to server successfully but the credentials order is changing like below.
Password
UserName
DomainName
Due to this reason I am getting an exceptional error from server. Please help me to resolve this issue as soon as possible.
NSDictionary has key-value pairs, it is not ordered. You need an array to keep the order of the elements. You could use 2 arrays (1 for keys the other for values) or use an array for keys (to know the order) and a dictionary for the key-value pairs.
NSDictionary is not an ordered container. If you really want an ordered dictionary then use OrderedDictionay from,
http://www.cocoawithlove.com/2008/12/ordereddictionary-subclassing-cocoa.html
Your question makes me think that its not NSDictionary that you want to use, because with dictionaries you really shouldn't care about the order.
And I think the glitch in your code is probably with the part that sends to the server, try sending them separately, or use another datatype than NSDictionary.
good luck!

How to retain order of JSON data retrieved with AFNetworking?

I am using AFNetworking to retrieve JSON data from a web service. Part of the response string I get is:
{"DATA":{"LEASE TYPE":"3 Yrs + 0 renew of 0 Yrs","LANDLORD":"","TENANT":"test comp"...
and so on. The order of the key values in the "DATA" dictionary ("LEASE TYPE","LANDLORD","TENANT"...) is important for presentation purposes. However, when AFNetworking calls NSJSONSerialization's:
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
method, the returned dictionary has the keys in a different order.
I notice that the AFJSONRequestOperation object has the server's response stored as an NSString, with everything in the correct order. However I'm not keen on parsing the JSON by hand if I can avoid it.
Can anyone suggest a way that will let me get at / keep the keys in their original order?
Thanks.
If the order is important use an array not a dictionary, dictionaries are be by their nature unordered. Or add an array of dictionary keys in the order desired.
If you have no control over the response that is sent you will have to parse the JSON yourself at least for the ordering.
When you'r creating an NSDictionary, the order will not be the same. I often recognized that dictionaries get ordered by key-name alphabetically.
But when using dictionaries the order doesn't really matter. And they shouldn't!
As the previous answers mentions dictionaries are by nature without order, but you can find here a nice class of OrderedDictionary:
http://www.cocoawithlove.com/2008/12/ordereddictionary-subclassing-cocoa.html
http://projectswithlove.com/projects/OrderedDictionary.zip

iOS - Strategy for saving and persisting JSON results with AFNetworking

I'm writing an iPhone app that loads Menu data from a database in the cloud. I am using AFNetworking (specifically AFJSONRequestOperation) to download the data in appDelegate.
Everything works fine up until this point, but I also need the app to be able to load the menu when the app is offline. To handle this, I want to save the returned JSON data to disc after it is retrieved by the AFJSONRequestOperation call.
My initial strategy was to save the returned JSON as a string, but I can't find a way to get the string response from an AFJSONRequestOperation. It seems silly to make two calls to the web service (one to return a JSON object and the other to return text) although it would be straightforward. I'd like to know if there is a better or more efficient way to do this. I could skip the AFJSONRequest and go for a plain AFHttpRequest but then I would need to construct the JSON object manually.
Is there a better option than either of the two I've thought up? In my opinion, the right answer would involve a single call that constructs the JSON object and also allows me to have access to the original text response, but I am open to hearing alternatives.
Don't save it as the JSON string level. AFNetworking will return the JSON as either an NSArray or an NSDictionary depending on your JSON structure.
You can just save the array or dictionary as a plist.
see -[NSDictionary writeToURL:atomically:] or -[NSArray writeToURL:atomically:]
I would try NSJSONSerialization to save NSData to disk.
Example:
NSData *dataToSave = [NSJSONSerialization dataWithJSONObject:responseObject options:nil error:nil];
id jsonObject = [NSJSONSerialization JSONObjectWithData:dataToSave options:nil error:nil];
Another option would be to take your responseObject from AFNetworking. Presumably a well-formed NSDictionary and simply place it in NSUserDefaults for semi-persistent storage. You need to make sure you don't have any null values in your dictionary as NSUserDefaults does not play nicely with null values.

Resources