Parse local json to UILabels - ios

I'm trying to parse a JSON file so I can use it's contents as NSStrings and display in UILabels throughout my application.
My JSON:
{
"CustomText": [
{
"bodyText": "This is the body text",
"loginText": "This is the loginText",
"extraText": "This is the extra text"
}
]
}
My code:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"File" ofType:#"json"];
NSData *content = [[NSData alloc] initWithContentsOfFile:filePath];
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:content options:kNilOptions error:nil];
NSArray *customStrings = json[#"CustomText"];
NSString *body = [customStrings valueForKey:#"bodyText"];
NSString *login = [customStrings valueForKey:#"loginText"];
self.labelText.text = body;
I'm not sure why it breaks, I have looks and surprisingly didn't find much on how to best use a local JSON file. Any help would be great.
Error message:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSArrayI length]:
unrecognized selector sent to instance 0x7f8080781740'

NSString *filePath = [[NSBundle mainBundle] pathForResource:#"File" ofType:#"json"];
NSData *content = [[NSData alloc] initWithContentsOfFile:filePath];
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:content options:kNilOptions error:nil];
NSArray *customStrings = json[#"CustomText"];
NSString *body = [[customStrings objectAtIndex:0] valueForKey:#"bodyText"];
NSString *login = [[customStrings objectAtIndex:0] valueForKey:#"loginText"];
self.labelText.text = body;

Use keypath
NSString * body = [json valueForKeyPath:#"CustomText.bodyText"];
self.labelText.text = body;

Related

Create JSON format using NSString as a key and values

I have JSON format requirement something like this.
{
"first_name" : "XYZ",
"last_name" : "ABC"
}
I have values in NSString.
NSString strFName = #"XYZ";
NSString strLName = #"ABC";
NSString strKeyFN = #"first_name";
NSString strKeyLN = #"last_name";
And I use NSMutableDictionary
NSMutableDictionary* dict = [[NSMutableDictionary alloc]init];
[dict setObject:strFName forKey:strKeyFN];
[dict setObject:strLName forKey:strKeyLN];
then output is
{
first_name = XYZ,
last_name = ABC
}
So I don't want "=" separating key & values instead I want ":" to separate key and values
I have went most of the stack overflow questions but didn't help getting "=" only in output
So please any help ?
Here is your answer :
NSString *strFName = #"XYZ";
NSString *strLName = #"ABC";
NSInteger number = 15;
NSString *strKeyFN = #"first_name";
NSString *strKeyLN = #"last_name";
NSString *numValue = #"Number";
NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
[dic setObject:strFName forKey:strKeyFN];
[dic setObject:strLName forKey:strKeyLN];
[dic setObject:[NSNumber numberWithInt:number] forKey:numValue];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSArray arrayWithObject:dic] options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"JSON %#",jsonString);
You write this code after your NSDictionary
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonstr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSString *strFName = #"XYZ";
NSString *strLName = #"ABC";
NSString *strKeyFN = #"first_name";
NSString *strKeyLN = #"last_name";
NSDictionary *ictionary = [NSDictionary dictionaryWithObjectsAndKeys:
strKeyFN, strFName,strKeyLN, strLName,nil];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"dictionary as string:%#", jsonString);
NSString *strFName = #"ABC";
NSString *strLName = #"XYZ";
NSString *strKeyFN = #"last_name";
NSString *strKeyLN = #"first_name";
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
[dict setObject:strFName forKey:strKeyFN];
[dict setObject:strLName forKey:strKeyLN];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSArray arrayWithObject:dict] options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonStrng = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"Your required JSON is %#",jsonStrng);
try this:-
NSString *cleanedString1 =[strFName stringByReplacingOccurrencesOfString:#"/"" withString:#""];
NSString *cleanedString2 =[strLName stringByReplacingOccurrencesOfString:#"/"" withString:#""];
NSDictionary *Dict = [NSDictionary dictionaryWithObjectsAndKeys:
cleanedString1, strKeyFN,
cleanedString2, strKeyLN,nil];
NSData *jsonData2 = [NSJSONSerialization dataWithJSONObject:Dict options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData2 encoding:NSUTF8StringEncoding];
NSLog(#"jsonData as string:\n%#", jsonString);
this very robust code to achieve you goal
NSDictionary *userDic = #{strKeyFN:strFName,strKeyLN:strLName};
you have to convert NSMutableDictionary into NSData
then convert the NSData Into json string you want
NSString *strFName = #"XYZ";
NSString *strLName = #"ABC";
NSString *strKeyFN = #"first_name";
NSString *strKeyLN = #"last_name";
NSMutableDictionary* dict = [[NSMutableDictionary alloc]init];
[dict setObject:strFName forKey:strKeyFN];
[dict setObject:strLName forKey:strKeyLN];
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSString *jasonString= [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

Failed to parse

I tried to parse this:
{"event":[{"event_id":"9","title":"event 10","welcome_logo":"20140715130727_252.png"}],"succeed":1}
This is my code:
NSString *strURL=[NSString stringWithFormat:#"http://loc**host/summit/event_login.php"];
NSData *dataURL=[NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSString *strResult=[[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSArray *jsonArray=[NSJSONSerialization JSONObjectWithData:dataURL options:0 error:nil];
NSDictionary *element=[jsonArray objectAtIndex:0];
NSString *title = [element objectForKey:#"title"];
NSString *image = [element objectForKey:#"welcome_logo"];
But this guy came and disturbs me:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x9e7d010'
So I'm wondering what I did I do wrong. I tried to google it and many said that I assume to use an array when the data is actually a dictionary. Is that true? So what do I need to do?
Change
NSArray *jsonArray=[NSJSONSerialization JSONObjectWithData:dataURL options:0 error:nil];
NSDictionary *element=[jsonArray objectAtIndex:0];
to
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:dataURL options:0 error:nil];
NSArray *events = [jsonDict objectForKey:#"event"];
if ([events count] > 0) {
NSDictionary *element=[events objectAtIndex:0];
}
because your json data is in the form of dictionary. And event holds the list (array) of events. And do a count check before accessing objectAtIndex: from events.

Retrieve data from NSMutableArray

I am only starting with IOS Development and creating an IOS application (Final project) for my computer science class which uses JSON to get data from remote MySql database.
Here is the method I call from ViewDidLoad:
- (void)loadJSON
{
//-- Make URL request with server
NSHTTPURLResponse *response = nil;
NSString *jsonUrlString = [NSString stringWithFormat:#"http://vito-service.ru/studentsconnect/profile.php"];
NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//-- Get request and response though URL
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//-- JSON Parsing
NSMutableArray *result = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
NSLog(#"Result = %#",result);
}
and NSLog prints the correct data:
Result = {
users = (
{
IdUser = 1;
facebook = "";
fullname = "";
instagram = "";
phonenumber = "";
username = moderas;
},
{
IdUser = 2;
facebook = "fb.com/petroffmichael";
fullname = "Michael Perov";
instagram = "#petroffmichael";
phonenumber = "(650)557-6168";
username = petroffmichael;
},
{
IdUser = 3;
facebook = "fb.com/testuser";
fullname = "Test User";
instagram = "#testuser";
phonenumber = "111 111-1111";
username = testuser;
}
);
}
But how can I retrieve this data as Strings to put them to the labels then? I tried lots of different options of creating Data objects, which I found here on stack overflow but I always get an "unrecognized selector sent to instance" error. I also tried creating a separate NSObject
#synthesize IdUser, username, fullname, phonenumber, facebook, instagram;
- (id) initWithUsername: (NSString *)uUsername andUserFullName: (NSString *)uFullname andUserPhonenumber: (NSString *)uPhonenumber andUserFacebook: (NSString *)uFacebook andUserInstagram: (NSString *)uInstagram andUserId: (NSString *)uId
{
self = [super init];
if (self) {
username = uUsername;
fullname = uFullname;
phonenumber = uPhonenumber;
facebook = uFacebook;
instagram = uInstagram;
IdUser = uId;
}
return self;
}
and then retrieving data with this method:
-(void)retrieveData
{
NSURL *url = [NSURL URLWithString:getDataUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
usersArray = [[NSMutableArray alloc] init];
for (int i=0; i<jsonArray.count; i++) {
NSString * uId = [[jsonArray objectAtIndex: i] objectForKey:#"IdUser"];
NSString * uUsername = [[jsonArray objectAtIndex: i] objectForKey:#"username"];
NSString * uFullname = [[jsonArray objectAtIndex: i] objectForKey:#"fullname"];
NSString * uPhonenumber = [[jsonArray objectAtIndex: i] objectForKey:#"phonenumber"];
NSString * uFacebook = [[jsonArray objectAtIndex: i] objectForKey:#"facebook"];
NSString * uInstagram = [[jsonArray objectAtIndex: i] objectForKey:#"instagram"];
[usersArray addObject:[[User alloc] initWithUsername:uUsername andUserFullName:uFullname andUserPhonenumber:uPhonenumber andUserFacebook:uFacebook andUserInstagram:uInstagram andUserId:uId]];
}
}
I have all the important #import's but I still get the same error:
2014-04-23 18:35:26.612 testimage[47155:70b] -[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0xa72a8b0
2014-04-23 18:35:26.813 testimage[47155:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0xa72a8b0'
Can anybody please help to find the right solution?
Thanks!
After listening to multiple comments I changed the code but still receive an error..
I guess I am still doing something wrong
jsonArray is not an array anymore:
#property (nonatomic, strong) NSDictionary *jsonArray;
#property (nonatomic, strong) NSMutableArray *usersArray;
Then the method:
-(void)retrieveData
{
NSURL *url = [NSURL URLWithString:getDataUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
usersArray = [[NSMutableArray alloc] init];
for (NSDictionary *dict in jsonArray)
{
NSString * uId = [dict objectForKey:#"IdUser"];
NSString * uUsername = [dict objectForKey:#"username"];
NSString * uFullname = [dict objectForKey:#"fullname"];
NSString * uPhonenumber = [dict objectForKey:#"phonenumber"];
NSString * uFacebook = [dict objectForKey:#"facebook"];
NSString * uInstagram = [dict objectForKey:#"instagram"];
[usersArray addObject:[[User alloc] initWithUsername:uUsername andUserFullName:uFullname andUserPhonenumber:uPhonenumber andUserFacebook:uFacebook andUserInstagram:uInstagram andUserId:uId]];
}
}
And I am still getting the same error:
2014-04-23 20:44:43.971 testimage[48285:70b] -[__NSCFString objectForKey:]: unrecognized selector sent to instance 0xa5547d0
2014-04-23 20:44:44.053 testimage[48285:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0xa5547d0'
Look closely at that output. It isn't what you say. What you have there is not an array — it's a dictionary with one key, #"users", whose value is an array. That's what it's telling you when it starts with { users = …. If you want the array, you'll need to retrieve it from the dictionary.
Try this:
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
NSMutableArray *result = [res objectForKey:#"users"];
This will do. The response isn't a NSArray. It is a Dictionary. First get the array from the dictionary and then use it as you are using. Hope this helps... :)
EDIT:
You can rewrite the loop by this:
for (NSDictionary *dict in jsonArray)
{
//dict is a NSDictionary. Just get value for keys
}

Convert Localizable.strings to json

I want to convert Localizable.strings file to JSON:
"Key" = "Localized Str";
To
"Key" : "Localized Str",
Is there any ready solution? Or better write own script?
NSString *path = [[NSBundle mainBundle] pathForResource:#"Localizable"
ofType:#"strings"
inDirectory:nil
forLocalization:#"en"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict
options:NSJSONWritingPrettyPrinted
error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

Converting NSData to NSUrl nil string parameter

I am trying to convert NSdata to NSUrl, and I found this method on the internet:
NSString *urlString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
NSURL *url = [[NSURL alloc] initWithString:urlString];
[session sendResourceAtURL:url withName:#"Resource" toPeer:peerID withCompletionHandler:nil];
Seems all right to me, but the app crashes at the second line and gives the error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL initWithString:relativeToURL:]: nil string parameter'
Can't get why...
myData is not UTF-8 encoded.
From the NSString docs:
Returns nil if the initialization fails for some reason (for example
if data does not represent valid data for encoding).
You should always check for this type of condition...
NSString *urlString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
NSURL *url;
if (urlString) {
url = [[NSURL alloc] initWithString:urlString];
} else {
// handle failure
}
Additionally, make sure you're using UTF8 encoding when you create the myData object, or switch from NSUTF8StringEncoding to the correct encoding type.
If dict from [NSKeyedArchiver archivedDataWithRootObject:dict] is NSDictionary class then you must extract the urlString from that dictionary.
NSError* error;
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSString *urlString = [dictionary valueForKey:#"url"];
change the encoding, say to NSUTF16StringEncoding
your String returns null try these method
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:#".png"];
[fileManager createFileAtPath:fullPath contents:myData attributes:nil];
if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath])
{
NSURL *imageUrl = [NSURL fileURLWithPath:fullPath isDirectory:NO];
}

Resources