how to append String in Array in incremental order - ios

i have some api call which returns some values and store it into Array while receiving i may get repeated values from the server which i suppose not to append when its already in Array and insert new Values,
here my sample codes :
-(void)getIdValue:(NSString*)getIdVal {
getTagIdList = [[NSMutableArray alloc]init];
BOOL isTheObjectThere = [getTagIdList containsObject: getIdVal];
NSLog(isTheObjectThere ? #"Yes" : #"No");
if (isTheObjectThere == NO){
[getTagIdList addObject:getIdVal];
NSLog(#"getTagIdList -->%#",getTagIdList);
} if (isTheObjectThere == YES){
return;
}
}
I want all the new data should be Stored in getTagIdList but i am getting only one record is storing

You are initialising the array within the method which is wrong. You should not be initiating the array where you try to store data.(which will remove all the old data stored in previous calls)

NSInteger count=[ArrayData count];
for (int i=0; i<count; i++) {
NSString *StringValue= ArrayData[i];
BOOL contains = [getTagIdList containsObject: StringValue];
if (contains==YES) {
NSLog(#"fail");
}
else{
[getTagIdList addObject: StringValue];
}
}
Here "ArrayData" is a json responce. getTagIdList is saving the string values.Try it i think this one is work.

From jegadeesh answer i updated your code
getTagIdList = [[NSMutableArray alloc]init];
-(void)getIdValue:(NSString*)getIdVal {
BOOL isTheObjectThere = [getTagIdList containsObject: getIdVal];
NSLog(isTheObjectThere ? #"Yes" : #"No");
if (isTheObjectThere == NO){
[getTagIdList addObject:getIdVal];
NSLog(#"getTagIdList -->%#",getTagIdList);
} if (isTheObjectThere == YES){
return;
}
}

Related

ios call back block return value

I am testing the call back and block function.
I'm using the objective-c in iOS.
I write a call back method name is "dosomethingProcessWithCompletion".
dosomethingProcessWithCompletion do something , then it will get the NSMutableDictionary value, I will use the nsmutabledictionary value to check something and return the value yes or no.
If the value is yes(------- AAAAA-------), I need break the
for( NSInteger i = 0 ; i < myAry.count; i++ ).. for loop .
and return the yes using tryToCallBlockMethod method.
If the value is no, the for loop will run to last item and return the no using tryToCallBlockMethod method.
But I don't known how to write the call back return value .
have anyone can give some hand?
My code below:
My AppTool declare:
typedef BOOL(^DoMyProcessCompletion)(NSMutableDictionary *completeresult);
+ (void) dosomethingProcessWithCompletion:(NSURL*)theUrl andUserPsd:(NSString*)psd withCompletion:(DoMyProcessCompletion) completion{
.....
....
..
NSMutableDictionary *resultDic = [NSMutableDictionary dictionary];
if( something == YES ){
[resultDic setObject:[NSNumber numberWithBool:YES] forKey:#"resultDicKey"];
[resultDic setObject:myData forKey:#"myDataDicKey"];
}else{
[resultDic setObject:[NSNumber numberWithBool:NO] forKey:#"resultDicKey"];
[resultDic setObject:[NSNull null] forKey:#"myDataDicKey"];
}
completion(resultDic)
}
My use and implement function is below:
-(BOOL) tryToCallBlockMethod{
for( NSInteger i = 0 ; i < myAry.count; i++ ){
userPsd = myAry[i];
[AppTool dosomethingProcessWithCompletion:[NSURL URLWithString:theUrl] andUserPsd:userPsd withCompletion:^(NSMutableDictionary *completeResult) {
BOOL result = [[completeResult objectForKey:#"resultDicKey"] boolValue];
if( result == YES){
//------- AAAAA-------
//------- if result is YES, will break the for look , and tryToCallBlockMethod will return YES.
return YES;
}else{
//------- BBBBBBB-------
return NO;
}
}];
}
}
Thank you very much.
You need to return boolean as below while you have used the Block inside the fuction.
-(void) tryToCallBlockMethod:(void(^)(BOOL isResult))callback{
if( result == YES){
callback(YES)
return YES;
}else{
callback(NO)
}
}

How to check if json object contains <null>?

I am getting a Json from server by making a network request in my app.I am getting <null> value for some keys in Json object.My app gets crashed if this type of response is received.Please tell me how can i validate>?
I have tried this but it does not work all time.
if(!(user_post.username==(id)[NSNull null]) )
{
user_post.username=[dict_user_info objectForKey:#"name"];
if(user_post.username!=nil)
{
ser_post.username=[dict_user_info objectForKey:#"name"];
}
else
{
user_post.username=#"Username";
}
}
Consider testing the value for null so your program won't crash. Like this:
if([dict_user_info objectForKey:#"name"] != [NSNull null])
{
ser_post.username=[dict_user_info objectForKey:#"name"];
}
Create a Category of NSDictionary and add following method in it, which replaces null value with empty string for each key in dictionary.
- (NSDictionary *)dictionaryByReplacingNullsWithStrings
{
const NSMutableDictionary *replaced = [self mutableCopy];
const id nul = [NSNull null];
const NSString *blank = #"";
for(NSString *key in self) {
const id object = [self objectForKey:key];
if(object == nul || object == NULL) {
//pointer comparison is way faster than -isKindOfClass:
//since [NSNull null] is a singleton, they'll all point to the same
//location in memory.
[replaced setObject:blank
forKey:key];
}
}
return [replaced copy];
}
Usage :
[yourJSONDictionary dictionaryByReplacingNullsWithStrings];
Read more about Category in iOS Tutorial 1 and Tutorial 2
yourJsonObject = [myDic valueforkey#"key"];
if(yourJsonObject != [NSNull null])
{
//not null
}
** you can also check whether object exist or not
if(yourJsonObject)
{
//exist
}
I think you've confused your logic. I am trying to stay true to your code, but let me know if the following is not what you intended:
if (dict_user_info[#"name"] != nil && [dict_user_info[#"name"] isKindOfClass:[NSNull class]] == NO) {
user_post.username = dict_user_info[#"name"];
if (user_post.username != nil) {
ser_post.username = user_post.username;
} else {
user_post.username = #"Username";
}
}
These are a couple of methods I wrote for my projects, try them :
/*!
* #brief Makes sure the object is not NSNull or NSCFNumber, if YES, converts them to NSString
* #discussion Sometimes JSON responses can contain NSNull objects, which does not play well with Obj-C. So when you access a value from a JSON and expect it to be an NSString, pass it through this method just to make sure thats the case.
* #param str The object that is supposed to be a string
* #return The object cleaned of unacceptable values
*/
+ (NSString *)cleanedJsonString:(id)str
{
NSString *formattedstr;
formattedstr = (str == [NSNull null]) ? #"" : str;
if ([str isKindOfClass:[NSNumber class]]) {
NSNumber *num = (NSNumber*) str;
formattedstr = [NSString stringWithFormat:#"%#",num];
}
return formattedstr;
}
/*!
* #brief Makes Sure the object is not NSNull
* #param obj Sometimes JSON responses can contain NSNull objects, which does not play well with Obj-C. So when you access a value from a JSON ( NSArray, NSDictionary or NSString), pass it through this method just to make sure thats the case.
* #return The object cleaned of unacceptable values
*/
+ (id)cleanedObject:(id)obj
{
return (obj == [NSNull null]) ? nil : obj;
}
/*!
* #brief A JSON cleaning function for NSArray Objects.
* #discussion Sometimes JSON responses can contain NSNull objects, which does not play well with Obj-C. So when you access a value from a JSON and expect it to be an NSArray, pass it through this method just to make sure thats the case. This method first checks if the object itself is NSNull. If not, then it traverses the array objects and cleans them too.
* #param arr The Objects thats supposed to be an NSArray
* #return The NSNull Cleaned object
*/
+ (NSArray *)cleanedJsonArray:(id)arr
{
if (arr == [NSNull null]) {
return [[NSArray alloc] init];
}
else
{
NSMutableArray *arrM = [(NSArray*)arr mutableCopy];
int i=0;
for (id __strong orb in arrM)
{
if (orb == [NSNull null])
{
[arrM removeObjectAtIndex:i];;
}
i++;
}
return arrM;
}
}
Just pass a JSON string, array or object to the appropriate method and the method will clean it for you.
Do yourself a favour and write a method that handles this and put it into an extension. Like
- (NSString*)jsonStringForKey:(NSString*)key
{
id result = self [key];
if (result == nil || result == [NSNull null]) return nil;
if ([result isKindOfClass:[NSString class]]) return result;
NSLog (#"Key %#: Expected string, got %#", key, result);
return nil;
}
You might even add some code that accepts NSNumber* results and turns them into strings, if that is what your server returns (some poster here had the problem that his server returned dress sizes as numbers like 40 or strings like "40-42" which makes something like this useful).
And then your code becomes one readable line
user_post.username = [dict_user_info jsonStringForKey:#"name"] ?: #"username";
I actually use several slightly different methods depending on whether I expect null, expect no value, expect an empty string or not, which gives me warnings when my assumptions are wrong (but always returns something that doesn't break).
try this:
if(!(user_post.username == (NSString *)[NSNull null]) )

Effective way of knowing if a dictionary has more than two of the same values

I have a dictionary that contains events. The format for one event looks like this
{
eventTime = 53';
eventType = "Yellow Card";
gameID = 0;
name = Mike;
selectedTeam = homeTeam;
}
And i have saved all of the events into an NSMutableArray. The clients will insert events as the time goes (for a soccer game). Now i need to check when populating my UITableView if a player has got two yellow cards so i can change the image to a different image. The way I'm doing it now looks like this and i don't really like it and it does not really work.
if ([typeEvent isEqualToString:#"Yellow Card"]){
int i= 0;
for (id obj in _events)
{
if ([[obj valueForKeyPath:[NSString stringWithFormat:#"eventType"]] isEqualToString:#"Yellow Card"] && [[obj valueForKeyPath:[NSString stringWithFormat:#"name"]] isEqualToString:[gameInfoObject valueForKeyPath:[NSString stringWithFormat:#"name"]]] ) {
i++;
if (i >= 2) {
imageType = [UIImage imageNamed:#"Yellow&Red.png"];
}
}
}
}
and in my UITableView i do this so you know what is what in the code above
NSMutableDictionary *gameInfoObject =[_events objectAtIndex:indexPath.row];
So basically if there is more than 1 event in EVENTS array where the eventType equals "Yellow Card" and the name of those matches i need to change the image to "Yellow&Red"
Thank you for you help
I would start by using one of the fast enumerator methods provided by NSArray.
NSIndexSet *matchingSet = [_events indexesOfObjectsPassingTest:^BOOL(id obj,
NSUInteger idx,
BOOL *stop){
return ([gameInfoObject[#"name"] isEqualToString:obj[#"name"] && [obj[#"eventType"] isEqualToString:#"Yellow Card"])
}];
if (matchingSet.count >= 2) {
imageType = [UIImage imageNamed:#"Yellow&Red.png"];
}
Look into using an NSCountedSet for your objects. You'll get a constant time lookup and a count.
You could do this in a few different ways. Personally, I think that having an event object is going to be the most readable for your code, but if you want to use simple objects like NSArray and NSDictionary, you could solve this easily with two extra NSMutableArrays or one extra NSMutableDictionary or one extra NSCountedSet.
NSMutableSets:
NSMutableSet *yellowCardPlayers;
NSMutableSet *redCardPlayers;
- (void)receiveEvent:(NSDictionary *)event {
[_events addObject:event];
if ([event[#"eventType"] isEqualToString:#"Yellow Card"]) {
if ([yellowCardPlayers containsObject:event[#"name"]]) {
if ([redCardPlayers containsObject:event[#"name"]]) {
// How did a player get a yellow card after already being ejected from the game?! :)
} else {
[redCardPlayers addObject:event[#"name"]];
}
} else {
[yellowCardPlayers addObject:event[#"name"]];
}
}
}
NSMutableDictionary:
NSMutableDictionary *playerYellowCards;
- (void)receiveEvent:(NSDictionary *)event {
[_events addObject:event];
if ([event[#"eventType"] isEqualToString:#"Yellow Card"]) {
NSNumber *numberOfYellowCards = [playerYellowCards objectForKey:event[#"name"]];
if (![[playerYellowCards allKeys] containsObject:event[#"name"]]) {
[playerYellowCards addObject:#(1) forKey:event[#"name"]];
} else {
[playerYellowCards addObject:#([playerYellowCards[event[#"name"]] integerValue]+1) forKey:event[#"name"]];
}
}
}
NSCountedSet:
NSCountedSet *playerYellowCards;
- (void)receiveEvent:(NSDictionary *)event {
[_events addObject:event];
if ([event[#"eventType"] isEqualToString:#"Yellow Card"]) {
[playerYellowCards addObject:event[#"name"]];
}
}
Use NSPredicate to filter your array, and then count the results:
NSPredicate *yellowFlagFilter = [NSPredicate predicateWithFormat:#"eventType == %# AND name == %#",#"Yellow Card", gameInfoObject.name];
NSArray *yellowCards = [_events filteredArrayUsingPredicate:yellowFlagFilter];
if ([yellowCards count] > 1) {
imageType = [UIImage imageNamed:#"Yellow&Red.png"];
}

In Objective-C Check an array of Integer Values and see if at least ONE is > 0

I asked a similar question to test an Array of Bool values here but now I have changed it so the values are now Integer values and I want to see if any of them are positive.
Example, I add 10 new objects in a loop like below, then at some point some may change and then I need to do a test. It may be that I do not use NSNumber, as long as I cna get an int out of it.
// I create an array like
NSMutableArray *MyArray = [[NSMutableArray alloc]init];
for (int count = 0; count < 10; count++)
{
[MyArray addObject:[NSNumber numberWithInt:0]];
}
// At some point I change a value or two
[MyArray replaceObjectAtIndex:3 withObject:[NSNumber numberWithInt:5]];
....
....
....
....
[MyArray replaceObjectAtIndex:3 withObject:[NSNumber numberWithInt:7]];
if([MyArray containsPositiveObject])
{
// Get the integer
int MyValue = [MyArray[4]integerValue];
}
EDIT
I have tried this and it works but wondered if there was a faster method.
if([self containsPositiveValue:selectedItems])
{
// Do my stuff
}
And then
-(bool)containsPositiveValue:(NSArray *)numberArray
{
bool result = NO;
for (NSNumber *obj in numberArray)
{
if([obj integerValue])
{
result = YES;
break;
}
}
return result;
}
Try this.
NSArray *array = #[ #(-1) , #(-3) , #(0) , #(-4) , #(2) , #(-1) ]; // zero is not positvie or negitive
NSArray *newArray = [array filteredArrayUsingPredicate: [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return ( [evaluatedObject isKindOfClass:[NSNumber class]] && ([evaluatedObject integerValue] > 0) );
return NO;
}]];
if (newArray.count)
{
NSLog(#"There are positive values");
}
else
{
NSLog(#"There are no positive values") ;
}
Surely the simplest way would be to go:
NSArray * array = #[#(-1), #(-5), #(-5)];
for (NSNumber * number in array) {
if (number.intValue > 0) {
NSLog(#"Positive Values");
// Add custom code here
break;
}
}
This will then check if at least one item in the array is greater than zero and custom code can then be implemented.
I suppose it depends if you want to perform something if there are no positive values and something different if there is?
You could always add something like this:
NSArray * array = #[#(-1), #(-5), #(-5)];
NSInteger largestValue = 0;
for (NSNumber * number in array) {
if (number.intValue > largestValue) {
largestValue = number.intValue;
}
if (largestValue > 0) {
break;
}
}
if (largestValue > 0) {
NSLog(#"Positive Value");
}
else {
NSLog(#"All Negative Values");
}
Anyway it gets more complicated the more complicated you want it to work but it should be incredibly simple

When i click on map its get crashed at the initial time in iOS5?

for (int i = 0; i< [delarsInfoArray count] ; i++)
{
NSString *lattitudeValue;
NSString *longitudeValue;
if ([[delarsInfoArray objectAtIndex:i]count]>1) {
lattitudeValue = [[[delarsInfoArray objectAtIndex:i]valueForKey:#"LATITUDE"]objectAtIndex:1];
longitudeValue = [[[delarsInfoArray objectAtIndex:i]valueForKey:#"LONGITUDE"]objectAtIndex:0];
}
else
{
lattitudeValue = #"";
longitudeValue = #"";
}
CLLocationCoordinate2D pinLocation;
if(([lattitudeValue floatValue] != 0) && ([longitudeValue floatValue] != 0) ) {
mapRegion.center.latitude = [lattitudeValue floatValue];
mapRegion.center.longitude = [longitudeValue floatValue];
if(pinLocation.latitude !=0 && pinLocation.longitude !=0) {
myAnnotation1 = [[MyAnnotation alloc] init];
if ([[delarsInfoArray objectAtIndex:i] count] == 0) {
myAnnotation1.title = #"";
myAnnotation1.subtitle = #"";
}
else
{
// NSLog(#"====== delears array is===%#",delarsInfoArray);
NSLog(#"===== delears array count is %d",[delarsInfoArray count]);
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"Address"]objectAtIndex:2] !=nil)
{
myAnnotation1.title = [[[delarsInfoArray objectAtIndex:i]valueForKey:#"Address"]objectAtIndex:2];
}
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"City"]objectAtIndex:3]!= nil) {
myAnnotation1.subtitle = [[[delarsInfoArray objectAtIndex:i]valueForKey:#"City"]objectAtIndex:3];
}
NSLog(#"%#",[[[delarsInfoArray objectAtIndex:i]valueForKey:#"City"]objectAtIndex:3]);
}
[dealerMapView setRegion:mapRegion animated:YES];
[dealerMapView addAnnotation:myAnnotation1];
myAnnotation1.coordinate = mapRegion.center;
[myAnnotation1 release];
}
}
}
The above code is written in the viewWillAppear.After loading the map in to the view,when i clicked on the map.app gets crashed.How can solve this crash?
There are a lot of issues here, but the one that leaps out to the top of the list are the lines that read:
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"Address"]objectAtIndex:2] !=nil)
...
and
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"City"]objectAtIndex:3]!= nil) {
...
The problem is that objectAtIndex of a valueForKey of an array will never be nil. You can't store a nil in an array, so what valueForKey does, if it doesn't find a value, is it uses a NSNull object, [NSNull null]. That designates that there was no value found, but uses NSNull (which can be added to the array) instead of nil (which can't).
The problem is likely that there is some subsequent code (for example, the code that tries to figure out the size of the callout bubble) which tries to get the length of the string, but since you stored a NSNull, it's trying to call the length method and it's failing.
You could fix this a number of ways, such as:
if ([[[delarsInfoArray objectAtIndex:i]valueForKey:#"Address"]objectAtIndex:2] != [NSNull null])
...

Resources