How can i read first item inside multiple arrays in IOS - ios

I have this Array, and i need all first elements.
I can only read one with this
vc.ArrayListaFotos = [[listaImagens objectAtIndex:(indexPath.row * 3)] valueForKey:#"Caminho"];
But I can't read others first itens inside array 1,2,3...
Can someone help me please ?

You are using the wrong reference. You should do that:
NSMutableArray *arrayDeImagensParaOProdutoSelecionado = [NSMutableArray arrayWithObjects:nil];
for (NSArray *tempArray in listaImagens) {
if ([[NSString stringWithFormat:#"%#", [tempArray valueForKey:#"idProduto"]] isEqualToString:[NSString stringWithFormat:#"%#", [[produtos objectAtIndex:(indexPath.row * 3)] valueForKey:#"id"]]]) {
[arrayDeImagensParaOProdutoSelecionado addObject:tempArray];
}
}
Hope it help.

for(NSArray *innerArray in outerArray) {
NSObject *firstObject = [innerArray firstObject];
// do whatever you need to with firstObject
NSLog(#"%#",firstObject);
}

Related

Unable to retrieve the data from Dictionary

In my project I am getting response from the server in the form
response:
<JKArray 0x7fa2e09036b0>(
{
id = 23;
name = "Name1";
},
{
id = 24;
name = "Name2";
}
)
From this response array i am retrieving the objects at different indexes and then adding them in a mutableArray and then into a contactsDictionary.
self.contactsDictionary = [[NSMutableDictionary alloc] init];
for(int i=0 ; i < [response count] ; i++)
{
NSMutableArray *mutableArray=[[NSMutableArray alloc] init];
[mutableArray addObject:[response objectAtIndex:i]];
[self.contactsDictionary setObject:mutableArray forKey:[NSString stringWithFormat:#"%i",i]];
}
I want to retrieve data for Key #"name" from the contactsDictionary at some other location in the project. So how to do it.
Thanks in advance....
this is the wrong way like you are setting your contactsDictionary.
replace below line
[self.contactsDictionary setObject:mutableArray forKey:[NSString stringWithFormat:#"%i",i]];
with
[self.contactsDictionary setObject:[mutableArray objectAtIndex :i] forKey:[NSString stringWithFormat:#"%i",i]];
becuase everytime your array have new objects so your contacts dictionary's first value have one object then second value have two object. so you shouldn't do that.
now, if you want to retrieve name then call like
NSString *name = [[self.contactsDictionary objectForKey : #"1"]valueForKey : #"name"];
avoid syntax mistake if any because have typed ans here.
Update as per comment:
just take one mutablearray for exa,
NSMutableArray *arr = [[NSMutableArray alloc]init];
[arr addObject : name]; //add name string like this
hope this will help :)
Aloha from your respond I can give you answer Belo like that according to you response.
for(int i=0;i<[arrRes count];i++);
{
NSString *strId = [NSString stringWithFormat:#"%#",[[arrRes obectAtIndex:i]objectForKey:#"id"]];
NSString *StrName = [NSString stringWithFormat:#"%#",[[arrRes objectAtIndex:i]objectForKey:#"name"]];
NSLog(#"The ID is -%#",strId);
NSLog(#"The NAME is - %#",strName);
}

How to detect if a dictionary is empty or null

I am receiving a JSON string that I need to iterate to retrieve some objects values.
This is the structure
-meta
-objects
|_cabdriver
|_employee
|client
There are objects under the objects tree and there are also child nodes, like cabdriver and client. The child node cabdriver has also another child node called employee.
This is the way I am iterating it:
NSArray *messageArray = [json objectForKey:#"objects"];
historialServicios = [[NSMutableArray alloc]init];
// Parse and loop through the JSON
for (dictionary in messageArray) {
//datos de nivel objects
NSString * date = [dictionary objectForKey:#"date"];
NSString * origin = [dictionary objectForKey:#"origin"];
NSString * destiny = [dictionary objectForKey:#"destiny"];
NSString * rate = [dictionary objectForKey:#"service_rate"];
NSString * state = [dictionary objectForKey:#"state"];
NSString * time_service = [dictionary objectForKey:#"time_service"];
NSString * id_service = [dictionary objectForKey:#"id"];
//datos de nivel cliente
NSDictionary *level2Dict = [dictionary objectForKey:#"client"];
NSString *client_id = [level2Dict objectForKey:#"id"];
//datos de nivel cabdriver
NSDictionary *cabdriverLevelDict=[dictionary objectForKey:#"cabdriver"];
//datos de nivel employee
NSDictionary *employeeLevelDict = [cabdriverLevelDict objectForKey:#"employee"];
//datos del employee
NSString *driverName = [employeeLevelDict objectForKey:#"name"];
NSString *driverLastname = [employeeLevelDict objectForKey:#"lastname"];
NSString *driverPhone = [employeeLevelDict objectForKey:#"phone"];
NSString *driverId = [employeeLevelDict objectForKey:#"id"];
[historialServicios addObject:#{
#"time_service": time_service,
#"id_service": id_service,
#"rate": rate,
#"destiny": destiny,
#"state": state,
#"origin": origin,
#"client_id":client_id,
#"date": date,
#"driverName":driverName,
#"driverLastname": driverLastname,
#"driverPhone": driverPhone,
#"driverId": driverId
}];
NSLog(#"DESPUES DE ANADIR OBJETOS");
NSLog(#"OBJETO ANADIDO==>TIME SERVICE = %#, ID SERVICE=%#, SERVICE RATE=%#,SERVICE DATE=%#,DESTINY=%#, STATE =%#,CLIENT ID=%#, ORIGIN=%#,DRIVER NAME=%#, DRIVER LASTNAME=%#,DRIVER PHONE=%#, DRIVER ID=%#",time_service,id_service,rate,date,destiny,state,client_id,origin,driverName,driverLastname,driverPhone,driverId);
//insertamos objetos en diccionario historialServicios
}
Everything works fine if the object has all nodes but some times, the node cabdriver is empty and doesn't have the employee child node. If it is the case I get an exception is thrown and the app crashes.
How can I determined if the node employee doesn't exist and avoid to get the exception?
Thank you.
You could declare a category to deal with the [NSNull null] values that are injected into your json.
#interface NSDictionary (NilNull)
- (id)optionalObjectForKey:(id)key;
- (id)optionalObjectForKey:(id)key defaultValue:(id)defaultValue;
#end
#implementation NSDictionary (NilNull)
- (id)optionalObjectForKey:(id)key {
return [self optionalObjectForKey:key defaultValue:nil];
]
- (id)optionalObjectForKey:(id)key defaultValue:(id)defaultValue {
id obj = [self objectForKey:key];
return (obj == [NSNull null] || !obj) ? defaultValue : obj;
}
#end
Then use that instead:
NSDictionary *cabdriverLevelDict = [dictionary optionalObjectForKey:#"cabdriver"];
NSDictionary *employeeLevelDict = [cabdriverLevelDict optionalObjectForKey:#"employee"];
You haven't posted the contents of your exception, but from the looks of it, it's probably related to trying to add nil values to your new dictionary.
Then use a default value of [NSNull null] for all your data lookups that produce objects with which you will construct your final dictionary. The full lookup source will now be like this:
NSString * date = [dictionary optionalObjectForKey:#"date" defaultValue:[NSNull null]];
NSString * origin = [dictionary optionalObjectForKey:#"origin" defaultValue:[NSNull null]];
NSString * destiny = [dictionary optionalObjectForKey:#"destiny" defaultValue:[NSNull null]];
NSString * rate = [dictionary optionalObjectForKey:#"service_rate" defaultValue:[NSNull null]];
NSString * state = [dictionary optionalObjectForKey:#"state" defaultValue:[NSNull null]];
NSString * time_service = [dictionary optionalObjectForKey:#"time_service" defaultValue:[NSNull null]];
NSString * id_service = [dictionary optionalObjectForKey:#"id" defaultValue:[NSNull null]];
//datos de nivel cliente
NSDictionary *level2Dict = [dictionary optionalObjectForKey:#"client" defaultValue:[NSDictionary dictionary]];
NSString *client_id = [level2Dict optionalObjectForKey:#"id" defaultValue:[NSNull null]];
//datos de nivel cabdriver
NSDictionary *cabdriverLevelDict=[dictionary optionalObjectForKey:#"cabdriver" defaultValue:[NSDictionary dictionary]];
//datos de nivel employee
NSDictionary *employeeLevelDict = [cabdriverLevelDict optionalObjectForKey:#"employee" defaultValue:[NSDictionary dictionary]];
//datos del employee
NSString *driverName = [employeeLevelDict optionalObjectForKey:#"name" defaultValue:[NSNull null]];
NSString *driverLastname = [employeeLevelDict optionalObjectForKey:#"lastname" defaultValue:[NSNull null]];
NSString *driverPhone = [employeeLevelDict optionalObjectForKey:#"phone" defaultValue:[NSNull null]];
NSString *driverId = [employeeLevelDict optionalObjectForKey:#"id" defaultValue:[NSNull null]];
Try this here:
if( cabdriverLevelDict.allkeys.count ){
// Do something with the dict
} else {
// dict is empty
}
Basically, you need to check every single result that you get. If you don't do that, your app is open to attacks, and one attack might allow a hacker into the user's device and cause unlimited damage. Where you expect a dictionary, you might get nil, you might get a null, you might get a number, or a string, just anything. It's quite simple.
NSDictionary* dict = ...;
if (! [dict isKindOfClass:[NSDictionary class]]) dict = nil;
In Objective-C, nil objects are quite safe. You can use objectForKey [#"employee"], for example, and all that will happen is that you get nil as the result. And you could have received nil anyway.
There is no point checking for [NSNull null] only, because any other result that the server gave you will crash your app just the same. Just check for what you actually expect. Throwing away incorrect data is fine, after all the JSON deserialiser will throw away everything if just a single byte of data is wrong.
Sometimes you need to do a bit more care because servers misbehave and you have to cope with it. For example, a server supposed to return an array of dictionaries might give you just a dictionary if there is only one, so you would check for example
NSArray* arrayOfDicts = ...;
if ([arrayOfDicts isKindOfClass:[NSDictionary class]] arrayOfDicts = #[arrayOfDicts];
else if (! [arrayOfDicts isKindOfClass:[NSArray class]] arrayOfDicts = nil;
As others have pointed out, if any of the objects passed into the dictionary are nil, that will throw an exception that crashes your app. By doing the following:
[historialServicios addObject:#{
#"time_service": time_service,
#"id_service": id_service,
#"rate": rate,
#"destiny": destiny,
#"state": state,
#"origin": origin,
#"client_id":client_id,
#"date": date,
#"driverName":driverName,
#"driverLastname": driverLastname,
#"driverPhone": driverPhone,
#"driverId": driverId
}];
You're depending that all these objects (eg time_service, id_service, etc) are not nil. As you've pointed out, they can be nil, so you need to have a means of checking for each object you do. I would recommend using an NSMutableDictionary, making a category method that only adds the key/value pair if they are both not nil:
#implementation NSMutableDictionary (Util)
-(void)setObjectOrRemoveIfNil:(id)anObject forKey:(id<NSCopying>)aKey
{
if (anObject == nil)
{
[self removeObjectForKey:aKey];
}
else
{
[self setObject:anObject forKey:aKey];
}
}
#end
And then put together your dictionary like so:
NSMutableDictionary* values = [NSMutableDictionary dictionary];
[values setObjectOrRemoveIfNil:time_service forKey:#"time_service"];
[values setObjectOrRemoveIfNil:id_service forKey:#"id_service"];
//Keep going with the rest of your values.
Finally we use that dictionary like you did already:
[historialServicios addObject:values];
check the count for the dictionary
if ([cabdriverLevelDict count] == 0) {
NSLog("empty");
}
else{
// Do your stuff !!
}
if (![cabdriverLevelDict isKindOfClass:[NSNull class]] ){
//do something
}
try this
You can try
NSDictionary *employeeLevelDict = [cabdriverLevelDict objectForKey:#"employee"];
if (employeeLevelDict.count != 0)
{
// do something if dict is not empty
}
else
{
}];

How do you find characters in an NSArray and return YES in Objective-C?

I am trying to find "Worf" inside the array of strings and then returning the BOOL of "YES" if I do find it, but if not, then return a BOOL of "NO".
So far this is what I have but it isn't working.
NSArray *myArray = #[#"Worf", #"son of Mogh", #"slayer of Gowron"];
NSString *myWorfString = #"Worf";
BOOL yesOrNo = NO;
for (NSString *task in myArray) {
if ([task isEqualToString: myWorfString]) {
yesOrNo = YES;
return yesOrNo;
} else {
return yesOrNo;
}
How would I input "return [myArray containsObject:myWolfString];" into my equation?
First of all you shouldn't compare objects with == unless you know what you are doing, since it compares memory addresses (where they are allocated) and not the contents. So two NSString* which points to two different instances which contain the same value are not equal according to ==.
You should use isEqualToString: or isEqualTo:.
In addition NSArray already contains this functionality, you don't need to reinvent the wheel:
NSArray *myArray = #[#"Worf", #"son of Mogh", #"slayer of Gowron"];
BOOL yesOrNo = [myArray containsObject:#"Worf"];
You have a logic error - you return immediately if the first item in the array is not #"Worf". While others have proposed solutions that will work, this one is most like your original code:
NSArray *myArray = #[#"Worf", #"son of Mogh", #"slayer of Gowron"];
NSString *myWorfString = #"Worf";
for (NSString *task in myArray)
if ([task isEqualToString: myWolfString])
return YES;
return NO;
Rather than go through the items one at a time, you can search the array concurrently, with lots of searches happening in parallel.
NSArray *myArray = #[#"Worf", #"son of Mogh", #"slayer of Gowron"];
NSString *myWorfString = #"Worf";
__block BOOL searchStringFound = NO;
[myArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString *string, NSUInteger idx, BOOL *stop) {
if ([string isEqualToString:myWorfString]) {
searchStringFound = YES;
*stop = YES;
}
}];
What's the advantage of this? It's faster, rather than search the array serially, you are doing it concurrently. Okay, so in this instance with such a small array it's unlikely to make much difference, but for larger arrays it could.
It's also a useful technique to use when looking for objects in collections. Because once you have found the object, you just set the stop parameter to YES to signal that no more enumerations need to be performed.
If you are looking for a substring:
- (BOOL)array:(NSArray *)array containsSubstring:(NSString *)substringToSearchFor
{
for (NSString *string in array) {
if (! [string isKindOfClass:[NSString class]])
continue; // skip objects that are not an NSString
if ([string rangeOfString:substringToSearchFor].location != NSNotFound)
return YES;
}
return NO;
}
Never compare strings with == use isEqualToString: instead.
You can just write:
return [myArray containsObject:myWolfString];
If you need to also check substring, you can use NSPredicate :
NSArray *myArray = #[#"Worf", #"son of Mogh", #"slayer of Gowron"];
NSString *myWolfString = #"Worf";
NSPredicate *pred = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"SELF CONTAINS [c] '%#'",myWolfString]];
NSArray *filteredArray = [myArray filteredArrayUsingPredicate:pred];
if ([filteredArray count])
{
NSLog(#"Index Of Object in main Array : %lu",(unsigned long)[myArray indexOfObject:filteredArray[0]]);
}
There are various ways you can find characters in NSArray and return YES in objective-c:-
1) By using NSPredicate
NSPredicate *pd=[NSPredicate predicateWithFormat:#"self MATCHES[CD] %#",myWorfString];
BOOL yesOrNo=[[NSNumber numberWithUnsignedLong:[[myArray filteredArrayUsingPredicate:pd]count]]boolValue];
2) Second using containsObjectapi
BOOL yesOrNo = [myArray containsObject:myWorfString];
3) Refer #EricS answer
NSArray *myArray = #[#"Worf", #"son of Mogh", #"slayer of Gowron"];
NSString *myWorfString = #"Worf";
BOOL yesOrNo = NO;
for (NSString *task in myArray)
{
if (([task isEqualToString: myWorfString]) || ([task rangeOfString:myWorfString].location != NSNotFound)) {
yesOrNo = YES;
break;
}
}
return yesOrNo;
Above code will return either array will contain as string or substring in array.

how to check NSString in NSMutableArray [duplicate]

This question already has answers here:
How might I check if a particular NSString is present in an NSArray?
(3 answers)
Closed 9 years ago.
I want search (to check) one NSString in NSMutableArray. but I dont know about it.
NSMutableArray *a = [[NSMutableArray alloc]initWithObjects:#"Marco",#"christian",#"hon",#"John",#"fred",#"asdas", nil];
NSString *name = #"John";
I want to see is there name variable in a NSMutableArray variable ?
Use containsObject: method to check this :
NSMutableArray *a = [[NSMutableArray alloc]initWithObjects:#"Marco",#"christian",#"hon",#"John",#"fred",#"asdas", nil];
NSString *name = #"John";
if ([a containsObject:name]) {
// Your array cotains that object
}
Hope it helps you.
run a loop and check .
-(BOOL)array:(NSArray*)array containsString:(NSString*)name
{
for(NSString *str in array)
{
if([name isEqualToString:str])
return YES;
}
return NO;
}
In this way array find out object that it contains.
you can also use a single line
[array containsObject:name]
If you are also interested in the position of your element you can use
- (NSUInteger)indexOfObject:(id)anObject
it will return NSNotFound if the object is not in the array, or the index of the object
You can use the following code
if([a containsObject: name])
{
//here your code
}
[a containsObject:name]
This might help you.
I suggest you to use indexOfObject:. Because using this way you can not only check whether it exists but also get the index if it indeed exists.
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"Marco",#"christian",#"hon",#"John",#"fred",#"asdas", nil];
NSString *name = #"John";
NSInteger index = [array indexOfObject:name];
if (index != NSNotFound) {
NSLog(#"Find name %#", name);
} else {
NSLog(#"Name %# not fount", name);
}

Separate two strings from one array element

I was wondering if anyone could lend some assistance. Basically I am calling a web service and then trying to get the large hosted image url. The output from the web service is so:
images = (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
);
The main problem is that the two strings are in only one of my array elements when I think they should be in 2. Also I'm not 100% but possibly they may be a dictionary :-S I'm just not sure. My code is as follows:
NSArray *imageArray = [[NSArray alloc]init];
imageArray = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSLog(#"imageArray: %#", imageArray);
NSLog(#"count imageArray: %lu", (unsigned long)[imageArray count]);
NSString *hostedLargeurlString = [imageArray objectAtIndex:0];
NSLog(#"imageArrayString: %#", hostedLargeurlString);
The output (nslog's) from the above code is:
2013-04-28 18:59:52.265 CustomTableView[2635:11303] imageArray: (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
)
2013-04-28 18:59:52.266 CustomTableView[2635:11303] count imageArray: 1
2013-04-28 18:59:52.266 CustomTableView[2635:11303] imageArrayString: {
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
Does anyone have any idea how I can seperate the one element into hostedlargeUrl and hostedsmallUrl respectively?
Any help you can provide is greatly appreciated!
Actually the images array contains a dictionary
images = (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
);
so :
NSDictionary *d = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"][0];
NSString *largeURL = d[#"hostedLargeUrl"];
NSString *smallURL = d[#"hostedSmallUrl"];
The value of [imageArray objectAtIndex:0] is a NSDictionary. You've incorrectly specified it as a NSString. You need the following:
NSDictionary *hostedLarguerDictionary =
(NSDictionary *) [imageArray objectAtIndex:0];
and then to access the 'large url' use:
hostedLarguerDictionary[#"hostedLargeUrl"]
or, equivalently
[hostedLarguerDictionary objectForKey: #"hostedLargeUrl"];
looks like an array with in an array so
NSArray* links = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSString* bigLink = [links objectAtIndex:0];
NSString* smallLink = [links objectAtIndex:1];
or it could be a dictionary
NSDictionary* links = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSString* bigLink = [links objectForKey:#"hostedLargeUrl "];
NSString* smallLink = [links objectForKey:#"hostedSmallUrl "];
you can see the class of the object by printing out the class name
NSLog(#"Class Type: %#", [[self.detailedSearchYummlyRecipeResults objectForKey:#"images"] class]);

Resources