Parsing a config file - objective-c

I have a config file whose content is something like this:
main = {
delay = 10000;
inputs = (
{
enabled = true;
ip = "127.0.0.1";
port = 10001;
file = "c:\abc.txt";
},
{
enabled = true;
ip = "127.0.0.1";
port = 10002;
file = "c:\myfile.txt";
},
);
}
Now, I want to parse this file, and for example, get the port number of the second input (i.e., 10002 in this example), etc.
Do you know what is the easiest way to do so in objective C?
Thanks!

Make sure it's a valid JSON file and then create a NSJSONSerialization object from the NSData of the file after opening it.
NSJSONSerialization *config = [[NSJSONSerialization JSONObjectWithData:DATAFROMFILE options:NSJSONReadingMutableContainers error:nil];
Then to access the second input port:
config[#"inputs"][1][#"port"]
But the best way to do this would be to create a model from each input so you could access the properties as strongly typed properties instead of by key.
ie. config.port instead of configInput[#"port"]

Looks like your config contents were output by NSLog, which results in invalid JSON hence assuming that your actual config file is a valid JSON object, following code should get you what you need:
//Don't forget to replace "configfile" with your config file name in the project
NSString *configPath = [[NSBundle mainBundle] pathForResource:#"configfile" ofType:nil];
NSData *data = [[NSFileManager defaultManager] contentsAtPath:configPath];
NSDictionary *config = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSArray *ports = [config valueForKeyPath:#"main.inputs.port"];
//ports[0] is 10001
//ports[1] is 10002
Here you can verify if your JSON is valid: http://jsonlint.com. This is how your valid JSON confi should look like:
{
"main": {
"delay": "10000",
"inputs": [
{
"enabled": true,
"ip": "127.0.0.1",
"port": 10001,
"file": "c: \\abc.txt"
},
{
"enabled": true,
"ip": "127.0.0.1",
"port": 10002,
"file": "c: \\myfile.txt"
}
]
}
}
EDIT:
I would personally use a model framework rather than just a json parser to save you from a ton of manual work that comes with built-in NSJSONSerialization class. Here are couple of pretty good ones:
1) GitHub Mantle - https://github.com/MantleFramework/Mantle
I use it where ever I can. It is very well written and thought out framework but has a little bit of learning curve involved, which probably is true to any new piece of software.
2) SBJson - https://github.com/stig/json-framework
You can use SBJson if you just wanna get the job done, it has been pretty popular, especially before Mantle and other frameworks became available.
I hope it helps.

If you are able to change or modify the configuration file format to json or plist, you could simply use built in readers an parsers.
Else, there are third party approaches like libconfig.
Also this question may help.

Related

Retrieving values from a multidimensional JSON array

Hi i am trying to get the subject name value out of the following JSON file (dataArray), which I have already run through NSJSONSERIALISATION:
-0: {
id: "55edc05848177ec741daf79e"
firstName: "Brad"
rating: 4.2
lessons: 5
text: "Lessons, they're yours take it"
-subjects: [4]
-0: {
name: "Indonesian"
pricePerHour: "500000"
}
-1: {
name: "Diving"
pricePerHour: "700000"
}
But am not able to access if using the indexPath and dot notation I have used for other elements. I'm understanding it must because I have to access an NSDictionary element within two arrays, however haven't been able to find the correct code to do this (though have looked a lot on here, most examples are for much simpler cases).
Here is the code I have been trying, but as I mentioned I now see that this code doesn't cover the array within array of the JSON. How should I modify this to get the value:
// Load and display subjects
UILabel *subjectLabel = (UILabel *)[cell viewWithTag:103];
NSString * subject1String = [dataArray[indexPath.row] valueForKeyPath: #"subjects.0.name"];
subjectLabel.text = [NSString stringWithFormat:#"%#", subject1String];
I think this is not valid Json. Print response as you are getting from the server end. And for getting name : you need to add loop.

NMSFTP contentsAtPath returns only a maximum of ~2kB of data

I'm using an SFTP library, https://github.com/Lejdborg/NMSSH, to connect to an SFTP server. Unfortunately when I try and retrieve the contents of a remote file, the data is clipped at about 2kB.
Here's the code I'm using:
NMSSHSession *session = [NMSSHSession connectToHost:host withUsername:username];
BOOL authenticated = [session authenticateByKeyboardInteractiveUsingBlock:^NSString*(NSString *request) {
return password;
}];
NMSFTP *sftpSession = [NMSFTP connectWithSession:session];
...
NSData *data = [sftpSession contentsAtPath:remoteFileName];
When remoteFileName is larger than 2kB, the length of data is always 2000.
Does anyone know why this would be the case?
NB: I've tested this on two different SFTP servers, with the exact same results.
The author of the library fixed the bug (https://github.com/Lejdborg/NMSSH/issues/35)

Top level JSON object attributes Objective-c

How can I access high level JSON object in Objective-c? Here's the JSON
{
user: "user",
id: 39,
image: "img.png",
caption: "",
lat: "37",
lng: "-122",
created_at: 1356910240
}
... and I need to do something like this [JSON valueFor???:????]
I can add object "identifier" and access it like [JSON valueForKeyPath:#"identifier"] but wondering if there is another way?
identifier: {
user: "user",
id: 39,
image: "img.png",
caption: "",
lat: "37",
lng: "-122",
created_at: 1356910240
}
Thanks!
Typically, a JSON parser will return a dictionary/hash/associative array, whatever the language being used uses for key/value pairs.
In ObjectiveC, that would be NSDictionary. So your parser should be doing this:
NSDictionary *data = [SomeJSONParser decodeJson:jsonString];
Now to get "user" from that we would do:
[data objectForKey:#"user"];
But you want the root node? Well you already have it. The root node is the dictionary your parser spits out. There is no magic method to call, the root node is simply the result of the parser.
If your "custom parser" works differently, I would suggest you change it. Making this do what you want is entirely dependent on the API of your parser and what types of objects it returns, both things you left incredibly vague in your question.

iOS – Facebook SDK, parsing results

In my -request:didLoad: delegate method I'm NSLoging the results but I can't figure out what's the content?
It looks like result is an NSArray but what is inside it? how do I parse the data?
A sample of the log looks like this:
result: (
{
"fql_result_set" = (
{
uid2 = 1234567;
},
{
uid2 = 12345678;
}
);
name = queryID;
},
{
"fql_result_set" = (
{
"birthday_date" = "05/12/1987";
name = "John Doe";
},
{
"birthday_date" = "03/01/1978";
name = "Jane Doe";
}
);
name = queryBirthday;
}
)
The Facebook iOS tutorial, in "Step 6: Using the Graph API", says
Note that the server response will be in JSON string format. The SDK uses an open source JSON library https://github.com/stig/json-framework/ to parse the result. If a parsing error occurs, the SDK will callback request:didFailWithError: in your delegate.
A successful request will callback request:didLoad: in your delegate. The result passed to your delegate can be an NSArray, if there are multiple results, or an NSDictionary if there is only a single result.
In your example, everything printed by NSLog inside "()" is part of an NSArray, while everything inside "{}" (which also have keys incidentally) is part of an NSDictionary and therefore accessible by key (name).
http://developers.facebook.com/docs/mobile/ios/build/
According to https://developers.facebook.com/docs/reference/api/, all 'responses' are JSON-Objects. To parse these, iOS 5 provides a class called NSJSONSerialization (NSJSONSerialization Class Reference)
You normally parse it as follows:
NSDictionary *dictionaryJSON = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];

How to parse this

I'm experimenting with googles url shortener goo.gl and at the moment it send the url to goo.gl and returns this:
{
"kind": "urlshortener#url",
"id": "http://goo.gl/kyPI",
"longUrl": "http://dsfsd.com/"
}
I think it's JSON but I'm having trouble with that because of ARC. Is there anyway else I could parse the string with key "id"?
If your app targets iOS 5 you can use NSJSONSeralization class of Apple.
(Let's assume youryour received is called theData)
NSError *error=nil;
id result=[NSJSONSerialization JSONObjectWithData:theData options:
NSJSONReadingMutableContainers error:&error];
//to retrieve the 'kind' value of the object
NSLog("Kind: %#",[result objectForKey:#"kind"]);
It's JSON, you can use a framework like SBJson to parse it. See http://stig.github.com/json-framework/