How to generate a multi-line UILabel - objective-c

I have a json call and I parse the results into a UILabel. In my json response I have a 4 Names under Clients.
I am trying to put all the Clients into my UILabel.
Currently I only see the last of the 4 clients from my json response but in my log I can see all 4 clients.
If you see the photo below you see brithouse which is the 4th client in the json call. I would like to view all 4 clients in mu uilabel? Currently I only see the last client.
Thanks
{
"ProfileID":34,
"ProfilePictureID":20,
"Name":"Bilbo Baggins",
"Clients":
[
{
"ClientID":91,
"Name":"Fnurky"
},
{
"ClientID":92,
"Name":"A different client"
},
{
"ClientID":95,
"Name":"Second Community"
},
{
"ClientID":96,
"Name":"Britehouse"
}
]
}
My objective C code
NSDictionary* json1 = [NSJSONSerialization JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray* latestLoans = [json1 objectForKey:#"Clients"]; //2
NSLog(#"Clients: %#", latestLoans); //3
NSArray *performersArray = [json1 objectForKey:#"Clients"];
for (NSDictionary *performerDic in performersArray) {
NSLog(#"%#", [performerDic objectForKey:#"Name"]);
jsonSummary.text = [NSString stringWithFormat:#"The clients under this user are: %# ",
[performerDic objectForKey:#"Name"]];
NSLOG
2013-05-16 13:03:52.820 com.barloworld.atajo[5137:907] Fnurky
2013-05-16 13:03:52.821 com.barloworld.atajo[5137:907] A different client
2013-05-16 13:03:52.821 com.barloworld.atajo[5137:907] Second Community
2013-05-16 13:03:52.822 com.barloworld.atajo[5137:907] Britehouse

Use this
NSDictionary* json1 = [NSJSONSerialization JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray* latestLoans = [json1 objectForKey:#"Clients"]; //2
NSArray *performersArray = [json1 objectForKey:#"Clients"];
NSMutableArray *array=[[NSMutableArray alloc]initWithCapacity:3];
for (NSDictionary *performerDic in performersArray) {
[array addObject:[performerDic objectForKey:#"Name"]];
}
NSString *output=[array componentsJoinedByString:#","];
jsonSummary.text = [NSString stringWithFormat:#"The clients under this user are: %# ",
output];

YOu can use this..
before the Loop:
NSString *tempString = #"";
In the Loop:
tempString = [tempString stringByAppendingFormat:#"%#", [performerDic objectForKey:#"Name"]];
After the Loop:
jsonSummary.text = [NSString stringWithFormat:#"The clients under this user are: %#", tempString];

This below of code will only add the last value into the label
jsonSummary.text = [NSString stringWithFormat:#"The clients under this user are: %# ",
[performerDic objectForKey:#"Name"]];
You have to APPEND each client name into string and then display the string value into the label... For appending into the string do,
JsonString =[NSString stringByAppendingFormat: [performerDic objectForKey:#"Name"]];
Now this string will have all Client values, Now
jsonSummary.text =[NSString stringWithFormat : #"YOUR OWN LINES %# " JsonString];

Related

How to format brackets of nested JSON

I'm trying to create a string which holds JSON data. I'm having an issue formatting the inner nested data, it currently has square brackets '[]' and I'm trying to change it to '{}', so it is valid JSON. Are there better approaches/solutions to parsing this data?
Actual Results:
[
[
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
],
[
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
]
]
Desired Results
[
{
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
},
{
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
}
]
Code
// Parse and loop through the JSON
for (NSDictionary * dataDict in eventArray) {
NSMutableArray *array = [[NSMutableArray alloc] init];
eventTime = [NSString stringWithFormat:#"%#%#",#"eventtime\":\"",[self eventTimeConversion:[dataDict objectForKey:#"event_time"]]];
keyID = [NSString stringWithFormat:#"%#%#",#"keyid\":\"",[dataDict objectForKey:#"key_id"]];
editTime = [NSString stringWithFormat:#"%#%#",#"edittime\":\"",[self eventTimeConversion:[dataDict objectForKey:#"event_time"]]];
projectID = [NSString stringWithFormat:#"%#%#",#"projectid\":\"",[gotHeaders objectAtIndex:0]];
lockID = [NSString stringWithFormat:#"%#%#",#"doorid\":\"",[dataDict objectForKey:#"lock_id"]];
eventType = [NSString stringWithFormat:#"%#%#",#"eventid\":\"",[dataDict objectForKey:#"event_type"]];
[array addObject:eventTime];
[array addObject:keyID];
[array addObject:editTime];
[array addObject:projectID];
[array addObject:lockID];
[array addObject:eventType];
[event_array addObject:array];
}
}
NSData *jsonnData = [NSJSONSerialization dataWithJSONObject:event_array options:NSJSONWritingPrettyPrinted error:&error];
NSString *eventsString = [[NSString alloc] initWithData:jsonnData encoding:NSUTF8StringEncoding];
Don't create a JSON string manually, create dictionaries, this is a simplified example for the keys eventtime and keyid
The code uses modern Objective-C syntax (introduced at least 6 years ago)
NSMutableArray *array = [[NSMutableArray alloc] init];
for (NSDictionary * dataDict in eventArray) {
NSString *eventTime = [self eventTimeConversion: dataDict[#"event_time"]];
NSString *keyID = dataDict[#"key_id"];
[array addObject:#{#"eventtime":eventTime, #"keyid":keyID}];
}
NSError *error;
NSData *jsonnData = [NSJSONSerialization dataWithJSONObject: array options:NSJSONWritingPrettyPrinted error:&error];
NSString *eventsString = [[NSString alloc] initWithData:jsonnData encoding:NSUTF8StringEncoding];
Instead of using an array to store the JSON id and value parameters, use a NSDictionary:
NSDictionary *d1 = [NSDictionary dictionaryWithObjectsAndKeys:
#"eventtime", #"2019-09-20 09:52:47",
#"keyid", #"15", nil];
[event_array addObject:d1];
...
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:event_array
options:NSJSONWritingPrettyPrinted error:&error];
NSString *eventsString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"%#", eventsString);
You will need to obviously replace the hardcoded values I have put on the dictionary in the example with your values.
This will output:
[
{
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
},
{
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
}
]

Objective C NSDictionary JSON in One line

i'm working on one objective C application where i'm taking JSON data and i need to insert this data(date) inside Dictionary fillDefaultColors. My fillDefaultColors should be in format like this:
self.fillDefaultColors = #{ #"2017/06/18":greenColor,
#"2017/06/19":orangeColor,
#"2017/06/20":greenColor,
...
};
but when i print in console log they are each in separate row and in application i can see colour just for last item from JSON
2017-06-19 15:30:12.310 CalendarTest[1905:364525] {
"2017/06/20" = "greenColor";
}
2017-06-19 15:30:12.311 CalendarTest[1905:364525] {
"2017/06/18" = "orangeColor";
}
So in application i see background for last date in console 2017/06/18
Here is my code
NSError *error = nil;
NSURL *url = [NSURL URLWithString: #"http://..."];
NSData *data = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:&error];
if(!error)
{
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
NSMutableArray *array= [json objectForKey:#"horses"];
for(int i=0; i< array.count; i++)
{
NSDictionary *horsedata = [array objectAtIndex:i];
NSString *date = [horsedata objectForKey:#"date"];
NSNumber *averagetemp = [horsedata objectForKey:#"averagetemperature"];
if([averagetemp isEqual:#(28)]) {tempColor = greenColor;} else {
tempColor = orangeColor;
}
self.fillDefaultColors = #{date: tempColor};
NSLog(#"%#", _fillDefaultColors);
}
}
JSON: {"horses":[{"id":1,"name":"Horse","date":"2017/06/17","averagetemperature":28},{"id":1,"name":"Horse","date":"2017/06/18","averagetemperature":25}]}
Thanks
it s because you are allocating a new dictionary in each iteration:
self.fillDefaultColors = #{date: tempColor};
you need to append instead:
NSMutableArray *array= [json objectForKey:#"horses"];
self.fillDefaultColors = [[NSMutableDictionary alloc]init];
for(int i=0; i< array.count; i++)
{
NSDictionary *horsedata = [array objectAtIndex:i];
NSString *date = [horsedata objectForKey:#"date"];
NSNumber *averagetemp = [horsedata objectForKey:#"averagetemperature"];
if([averagetemp isEqual:#(28)]) {tempColor = greenColor;} else {
tempColor = orangeColor;
}
[self.fillDefaultColors setObject:tempColor forKey:date];
NSLog(#"%#", _fillDefaultColors);
}
This is the same solution as in Hussein's answer but with Modern Objective-C Syntax – which has been introduced at least 5 years ago.
NSArray *horses = json[#"horses"];
self.fillDefaultColors = [[NSMutableDictionary alloc] init];
for (NSDictionary *horsedata in horses)
{
NSString *date = horsedata[#"date"];
NSNumber *averagetemp = horsedata[#"averagetemperature"];
self.fillDefaultColors[date] = (averagetemp.integerValue == 28) ? greenColor : orangeColor;
NSLog(#"%#", _fillDefaultColors);
}

Unable to convert UTF-8 text from NSDictionary in Objective-C

Im using foursquare API to get some locations around me, but when the name of that place wasn't in english, the name will be like follows:
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
i tried to convert the response to a UTF-8 but nothing changed.
Here is my code:
-(void)setUpLocations{
NSURL *url = [NSURL URLWithString: #"https://api.foursquare...."];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"Response: %#",[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"]);
}
And the log result is:
contact = {
};
id = 51712507498ec4e8c5ae9f48;
likes = {
count = 0;
groups = (
);
};
location = {
address = Abdoun;
cc = JO;
city = Amman;
country = Jordan;
distance = 3819;
lat = "31.95406043797281";
lng = "35.88095228186612";
};
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
restricted = 1;
stats = {
checkinsCount = 43;
tipCount = 2;
usersCount = 23;
};
verified = 0;
},
Any Suggestions ??
EDIT:
here is how i extract the data from the dictionary:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
namesArray = [[NSArray alloc]initWithArray:[self removeWhiteSpaces:[dic valueForKey:#"name"]]];
-(NSArray *)removeWhiteSpaces:(NSDictionary *)dic{
NSString *str = [NSString stringWithFormat:#"%#",dic];
NSString *str2 = [str stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSString *secondString = [str2 stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *thirdString = [secondString stringByReplacingOccurrencesOfString:#"(" withString:#""];
NSString *forthString = [thirdString stringByReplacingOccurrencesOfString:#")" withString:#""];
NSString *fifthString = [forthString stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSArray *items = [fifthString componentsSeparatedByString:#","];
return items;
}
And in the UITableView:
cell.textLabel.text = [NSString stringWithFormat:#"Name: %# ",[namesArray objectAtIndex:indexPath.row] ];
Update
After trying #Martin R answer i got the same results:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
NSString *value =[dic valueForKey:#"name"];
NSLog(#"%#", value);
UILabel *lbl = [[UILabel alloc]initWithFrame:self.view.frame];
lbl.numberOfLines = 0;
lbl.text = [NSString stringWithFormat:#"%#",value];;
[self.view addSubview:lbl];
and here is an image of the result
There is no problem.
NSLog() calls the description method of NSDictionary and NSArray, and that prints all non-ASCII characters as \Unnnn escape sequence.
If you extract the string values from the dictionary and print that you will see
that everything is correct.
Simple example:
NSDictionary *dict = #{ #"currency": #"€" };
NSLog(#"%#", dict);
// Output: { currency = "\U20ac"; }
NSString *value = dict[#"currency"];
NSLog(#"%#", value);
// Output: €
UPDATE: The problem seems to be in your removeWhiteSpaces: method, because
NSString *str = [NSString stringWithFormat:#"%#",dic];
already uses the description method to convert the dictionary to a string,
and the following stringByReplacingOccurrencesOfString calls are a (sorry!) very bad
method to fix that.
You should access the dictionary keys with objectForKey instead, or enumerate
the dictionary with for (NSString *key in dic) { ... } and build the desired
array.
UPDATE 2: From the JSON data (posted in chat discussion) it seem that you just need
NSArray *itemsArray = json[#"response"][#"groups"][0][#"items];
NSArray *namesArray = [itemsArray valueForKey:#"name"];
Note that "groups" is an array with one element.
Try to use this one..
[NSString stringWithUTF8String:]

Add dictionaries to nsdictionary as value for key

I have to prepare a dictionary for serialization and then post it to server. Dictionary may have several other dictionaries as values for #"items" key. But some brackets interrupt. And server response me an error html.
NSMutableArray *a = [[NSMutableArray alloc]init];
for(int i = 0; i < [self.cartCopy count]; i++) {
NSString *itemNumber = [NSString stringWithFormat:#"%d", i + 1];
NSDictionary *tempDict = #{ itemNumber : #{
#"item_id" : [[self.cartCopy objectAtIndex:i]objectForKey:#"id"],
#"quantity" : [[self.cartCopy objectAtIndex:i]objectForKey:#"quantity"],
#"type" : [[self.cartCopy objectAtIndex:i]objectForKey:#"type"],
#"color_id" : #"0",
}
};
[a addObject:tempDict];
}
NSDictionary *dict = #{
#"date":oDate,
#"address":oAddress,
#"name":oName,
#"shipping_date":oShippingDate,
#"receiver_phone":oReceiverPhone,
#"customer_phone":oCustomerPhone,
#"total_price": oTotalPrice ,
#"additional_info": #"asd",
#"items": a
};
UPDATE: My NSLog of string after [NSJSONSerialization dataWithJSONObject:dict options:kNilOptions error:nil] :
{"address":"asd",
"name":"asd",
"receiver_phone":"123",
"customer_phone":"123",
"total_price":"1",
"date":"2013-03-05 21:22:55",
"additional_info":"asd",
"items":[
{"1":{
"type":"2",
"color_id":"0",
"item_id":10,
"quantity":"3"
}
},
{"2":{
"type":"1",
"color_id":"0",
"item_id":74,
"quantity":"3"
}
}
],
"shipping_date":"2030-03-03 12:12:12"
}
I think the reason is square brackets. How can i delete them?
For example, it works perfectly with dictionary:
NSDictionary *dict = #{
#"date":oDate,
#"address":oAddress,
#"name":oName,
#"shipping_date":oShippingDate,
#"receiver_phone":oReceiverPhone,
#"customer_phone":oCustomerPhone,
#"total_price": oTotalPrice ,
#"additional_info": #"asd",
#"items": #{
#"1":#{
#"type":#"1",
#"color_id":#"0",
#"item_id":#"1",
#"quantity":#"1"
},
#"2":#{
#"type":#"1",
#"color_id":#"0",
#"item_id":#"1",
#"quantity":#"1"
}
}
};
In your example that works perfectly the items object is a dictionary with keys {1, 2}.
In your output JSON your items object is an array.
This array contains 2 objects, each one is a dictionary.
The first contains a single key {1}.
The second contains a single key {2}.
You just need to remove the array and use a dictionary instead to store these dictionaries.
That looks as if you want to send JSON to the server. You can create JSON data from your dictionary with
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
If you need it as a string:
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

Extracting number from NSString

I have an NSString which when logged gives me an answer like this one:
Response: oauth_token_secret=6h8hblp42jfowfy&oauth_token=9tmqsojggieln6z
The two numbers change every single time.
Is there a way to extract the two numbers and create two strings with one of each??
Like:
NSString *key = #"9tmqsojggieln6z";
//copy the string in a new string variable
NSMutableString *auth_token = [NSMutableString stringWithString:response];
NSRange match = [auth_token rangeOfString: #"&oauth_token="];
[auth_token deleteCharactersInRange: NSMakeRange(0, match.location+13)];
//auth_token will now have the auth token string
NSMutableString *auth_token_secret = [NSMutableString stringWithString:response];
NSRange range1 = [auth_token_secret rangeOfString:[NSString stringWithFormat:#"&oauth_token=%#", auth_token]];
[auth_token_secret deleteCharactersInRange:range1];
NSRange range2 = [auth_token_secret rangeOfString:#"oauth_token_secret="];
[auth_token_secret deleteCharactersInRange: range2];
//auth_token_secret will have the required secret string.
I had the same problem. As response I get the ids of objects sometimes as string sometimes as numbers. Then I wrote a category for NSDictionary which has the following method:
- (NSString *)stringFromStringOrNumberForKey:(NSString *)key
{
id secret = [self objectForKey:key];
if ([secret isKindOfClass:[NSNumber class]]) {
NSNumberFormatter * numberFormatter = [[NSNumberFormatter alloc] init];
secret = [numberFormatter stringFromNumber:secret];
}
return secret;
}
I would try the following:
NSString *_response = #"oauth_token_secret=6h8hblp42jfowfy&oauth_token=9tmqsojggieln6z";
NSMutableDictionary *_dictionary = [[NSMutableDictionary alloc] init];
NSArray *_parameters = [_response componentsSeparatedByString:#"&"];
for (NSString *_oneParameter in _parameters) {
NSArray *_keyAndValue = [_oneParameter componentsSeparatedByString:#"="];
[_dictionary setValue:[_keyAndValue lastObject] forKey:[_keyAndValue objectAtIndex:0]];
}
// reading the values
NSLog(#"token_secret : %#", [_dictionary valueForKey:#"oauth_token_secret"]);
NSLog(#"token : %#", [_dictionary valueForKey:#"oauth_token"]);