Exception while passing float value from array to coordinates - iphone

i am getting exception over these lines of code dont know why its giving so ..Help me out ..
reason is:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[__NSArrayI floatValue]: unrecognized selector sent to instance 0x7c57840'
coord.latitude = [[[self.holdingArray objectAtIndex:k]
valueForKey:#"latitude"]floatValue];
coord.longitude = [[[self.holdingArray objectAtIndex:k] valueForKey:#"longitude"]
floatValue];
Edit 1
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[appDelegate.dealerDataGlobalArray removeAllObjects];
NSString *requestString;
requestString = [NSString stringWithFormat:#"http://www.hvinfotech.net/projects/carwash
/search.php?search=%#",textField.text];
NSString *strCOntents1 = [NSString stringWithContentsOfURL:[NSURL
URLWithString:requestString] encoding:NSUTF8StringEncoding error:nil];
NSLog(#"Data: %#",strCOntents1);
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL
URLWithString:requestString]];
DealerDetailParser *parser = [[DealerDetailParser alloc]
initDealerDetailParserXMLParser];
[xmlParser setDelegate:parser];
[xmlParser parse];
appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSLog(#"dealerDataGlobalArray...... %#",[appDelegate.dealerDataGlobalArray
description]);
[holdingArray addObject:appDelegate.dealerDataGlobalArray];
NSLog(#"holdingArray...... %#",holdingArray);
flagForHoldingArray = YES;
[self loadOurAnnotations];
[textField resignFirstResponder];
return YES;
}
i have edited so that it can be more clear. I am calling the webservice to get the data corresponding to what is entered in text field. After that i call the method in which previous line o code were posted...
Edit2
it gives like
2012-01-23 00:27:35.475 CarWashApp[2584:11603] (
{
businessdesc = "having a garage and teamof 10members, originaly belongs to mumbai
maharashtra.";
"businessdesc_de" = "having a garage and teamof 10members, originaly belongs to
mumbai maharashtra.";
city = vadodra;
"city_de" = "dadar_de";
companyname = "Maruti Suzki Ltd";
"companyname_de" = "Maruti Suzki Ltd _de";
contactname = "bijju sharma";
"contactname_de" = "bijju sharma_de";
coupondetails = "10% Discount";
"coupondetails_de" = "10% Discount _de";
email = "bsharma#gmail.com";
friday = "Friday: Closed";
happyhour = "10:00 AM to 5:00 PM";
id = 5;
latitude = "22.30731";
logo = "http://www.hvinfotech.net/projects/carwash/upload/images/Sunset.jpg";
longitude = "73.181098";
monday = "Monday: Closed";
payment = Visa;
payments = "";
phone1 = 07932453453;
phone2 = 07934344444;
postcode = JU113;
saturday = "Saturday:9:30 AM - 4:00 PM";
services = "";
state = Groningen;
"state_de" = Groningen;
streetaddress1 = "500 golf Road,";
"streetaddress1_de" = "sectore 5 d_de";
streetaddress2 = "airport Road";
"streetaddress2_de" = "";
sunday = "Sunday:9:30 AM - 4:00 PM";
thursday = "Thursday: Closed";
tuesday = "Tuesday:9:30 AM - 4:00 PM";
website = "http://hvinfotechPvtLtd.com";
wednesday = "Wednesday: Closed";
}
)
2012-01-23 00:27:43.434 CarWashApp[2584:11603] (
"22.30731"
)
i need only above value i.e "22.30731" as coordinate but its showing error if i also write like
coord.latitude = [[self.holdingArray objectAtIndex:k] valueForKey:#"latitude"];

What kind of objects are in self.holdingArray - dictionaries?
Ok, what kind of object is in the dictionary for key "longitude"? It appears that they are arrays.
It is often good practice to break apart these kinds of nested statements, so that you can easily debug.

As #Rayfleck said, the object in the array might be not be the kind of object you're expecting it to be. Use the debugger or NSLog() to find out what object it actually is.
Another possibility, is you might have a memory management bug somewhere. Do you have ARC enabled?
And finally, it could be a thread safety issue. In that case, best of luck finding it! There isn't really any easy way to track down threading issues, except read every line of code and try to find the mistake.
EDIT:
You have this line of code:
[holdingArray addObject:appDelegate.dealerDataGlobalArray];
It looks like you are adding an array object to the holdingArray array. Array objects will return another array when you send valueForKey: to them (lookup valueForKey in the documentation for NSArray...).
Anyway, the array object doesn't respond to floatValue. Only NSString and NSNumber objects respond to floatValue.
You should NSLog() these objects, because I think they are not what you expect them to be:
NSLog(#"%#", [self.holdingArray objectAtIndex:k]);
NSLog(#"%#", [[self.holdingArray objectAtIndex:k] valueForKey:#"latitude"]);

Related

combining 2 strings in objective-c

I have a problem when I try to combine 2 NSString
I extract 2 NSSring form a JSON and its diagrams are:
thumbList: ( "picture1.jpg", "picture2.jpg", "picture3.jpg" ... )
fullnameList: ("name1", "name2" , "name3" ... )
My intention is unite them into one using the following scheme:
("name1", "picture1.jpg", "name2", "picture2.jpg", "name3", "picture3.jpg"...)
NSArray *array_webdata=[[NSArray array] init];
NSString *searchStatus = [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];
array_webdata = [parsedata objectWithString:searchStatus error:nil];
//String with all data of each user
NSString *usersList = [array_webdata valueForKey:#"results"];
NSLog(#"\n results? = %# \n", usersList);
//String with thumbs
NSString *thumbList = [usersList valueForKey:#"thumb"];
NSLog(#"\n thumbs? = %# \n", thumbList);
//String with usernames
NSString *fullnameList = [usersList valueForKey:#"fullname"];
NSLog(#"\n fullnames? = %# \n", fullnameList);
NSMutableIndexSet *indexes = [NSMutableIndexSet indexSetWithIndex:1];
[indexes addIndex:3];
[fullnameList insertObjects:thumbList atIndexes:indexes];
NSLog(#"array: %#", fullnameList);
But when I try to execute shows the next error message: [__NSArrayI insertObjects:atIndexes:]: unrecognized selector sent to instance.
Can anyone help me?
You should use
NSMutableDictionary* dataDict = [NSMutableDictionary dictionaryWithObjects:picturesList forKeys:namesList];
// Whenever key needed for fetching record from Dictionary just write
NSArray* keyArr = [dataDict AllKey];
Now you have all key and you can fetch record with the help of above key.
All "unrecognized selector sent to instance." errors mean the same: you think some object has a method, but it really don't have it at runtime.
Due to the dynamic nature of Objective-C, if you're not sure of some object having a method you should always test it calling respondsToSelector: like this:
if ([myObj respondsToSelector:#selector(someMethod)]) {
[myObj someMethod];
}
In this case,
NSString *fullnameList = [usersList valueForKey:#"fullname"];
is a NSString. That class does not have a insertObjects:atIndexes: method. Maybe you have to declare it as an NSMutableArray

Writing an NSMutableArray to my documents directory fails

I am attempting to cache a web request. Basically I have an app that uses a facebook user's friend list but I don't want to grab it every single time they log in. Maybe refresh once per month. Caching the friend list in a plist in the documents directory seems to make sense for this functionality. I do this as follows:
- (void)writeToDisk {
NSLog(#"writing cache to disk, where cache = %#", cache);
BOOL res = [cache writeToFile:[FriendCache persistentPath] atomically:YES];
NSLog(#"reading cache from disk immediately after writing, res = %d", res);
NSMutableArray *temp = [[NSMutableArray alloc] initWithContentsOfFile:[FriendCache persistentPath]];
NSLog(#"cache read in = %#", temp);
}
+ (NSString *)persistentPath {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"FriendCache.plist"];
}
These are members of a FriendCache singleton I am using which basically wraps an NSMutableArray. I have verified that the peristentPath method is returning a valid path. As you you can see in the writeToDisk method, I verify there is data in the cache and then I print the result of the write and check if any data could be read back in. There is never data read back in, because the result of the file write is 0.
The output of the cache print is very long, but here is the abbreviated version:
2010-12-28 13:35:23.006 AppName[51607:207] writing cache to disk, where cache = (
{
birthday = "<null>";
name = "Some Name1";
pic = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs1324.snc4/7846385648654.jpg";
"pic_big" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs442.snc4/784365789465746.jpg";
"pic_square" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs1324.snc4/7846357896547.jpg";
sex = female;
status = "<null>";
uid = 892374897165;
},
{
birthday = "<null>";
name = "Some Name2";
pic = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs625.ash1/54636536547_s.jpg";
"pic_big" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs170.ash2/65465656365666_n.jpg";
"pic_square" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs625.ash1/654635656547_q.jpg";
sex = female;
status = "<null>";
uid = 7658436;
},
...
One thing I checked out is when using writeToFile, I must make sure the object I am writing has valid plist objects. I did check this and here is how I construct the cache object:
- (void)request:(FBRequest*)request didLoad:(id)result{
NSMutableArray *friendsInfo = [[[NSMutableArray alloc] init] autorelease];
for (NSDictionary *info in result) {
NSString *friend_id = [NSString stringWithString:[[info objectForKey:#"uid"] stringValue]];
NSString *friend_name = nil;
NSString *friend_sex = nil;
NSString *friend_relationship_status = nil;
NSString *friend_current_location = nil;
if ([info objectForKey:#"name"] != [NSNull null]) {
friend_name = [NSString stringWithString:[info objectForKey:#"name"]];
}
if ([info objectForKey:#"relationship_status"] != [NSNull null]) {
friend_relationship_status = [NSString stringWithString:[info objectForKey:#"relationship_status"]];
}
if ([info objectForKey:#"sex"] != [NSNull null]) {
friend_sex = [NSString stringWithString:[info objectForKey:#"sex"]];
}
if ([info objectForKey:#"current_location"] != [NSNull null]) {
friend_current_location = [[info objectForKey:#"current_location"] objectForKey:#"name"];
}
NSString *friend_pic_square = [info objectForKey:#"pic_square"];
NSString *friend_status = [info objectForKey:#"status"];
NSString *friend_pic = [info objectForKey:#"pic"];
NSString *friend_pic_big = [info objectForKey:#"pic_big"];
NSString *friend_birthday = [info objectForKey:#"birthday"];
NSDictionary *friend_info = [NSDictionary dictionaryWithObjectsAndKeys:
friend_id,#"uid",
friend_name, #"name",
friend_pic_square, #"pic_square",
friend_status, #"status",
friend_sex, #"sex",
friend_pic, #"pic",
friend_pic_big, #"pic_big",
friend_birthday, #"birthday",
friend_relationship_status, #"relationship_status",
friend_current_location, #"current_location",
nil];
// If the friend qualifies as a single of your gender, add to the friend cache
if ( [AppHelpers friendQualifies:friend_info] == YES) {
[[FriendCache sharedInstance] push:friend_info];
}
}
[[FriendCache sharedInstance] writeToDisk];
}
My push method just wraps the NSMutableArray push:
- (void)push:(id)o {
[cache addObject:o];
}
Can you think of any reason why the write would fail?
Thanks!
So as we already pointed out, it's because of the usage of the NSNull objects.
The best way to avoid this is to create an object Friend, with all of the needed properties. Then you can easily set nil values, something not possible with NSDictionary objects (well, you'd have to remove the key, which is not very good practice).
Then, by implementing the NSCoding protocol, you can easily archive (serialize) your custom object.
This is a much better way of handling your data, and it will become MUCH easier in the future. You'll be able to call messages on the Friend objects, something not possible with NSDictionary.
Use NSError-aware API for NSPropertyListSerialization to get the data and the NSData NSError aware write API so you get a meaningful error helping you understand what your problem might be.

Why do I get SIGABRT after the first iteration of this my for loop?

I feel very stupid for asking this, but I've been trying to figure this for about three hours and have gotten nowhere. See the code below. After the first iteration, my program crashes and all I get is SIGABRT. As you may get from the code, I'm just trying to build a string from other strings. It works fine on the first iteration, but on the second one, it just aborts.
Film* film = (Film *)managedObject;
for (NSManagedObject* crewMember in [film CastAndCrew])
{
castAndCrewMember = (CastOrCrewMember*)crewMember;
if ([[[castAndCrewMember talentType] typeName] isEqualToString:#"Director"])
{
fullName = [[NSMutableString alloc] initWithString:[[castAndCrewMember talent] firstName]];
[fullName appendString:[#" " stringByAppendingString:[[castAndCrewMember talent] lastName]]];
subtitle = [[NSMutableString alloc] initWithString:[[[[fullName description] stringByAppendingString:#" "] stringByAppendingString:[film runningTime]] stringByAppendingString:#" | "]];
[subtitle appendString:[[film category] categoryName]];
[subtitle retain];
[fullName release];
fullName = nil;
break;
}
}
TTTableItem* tableItem = [TTTableSubtitleItem itemWithText:[film title]
subtitle:subtitle
imageURL:[film imageURL]
defaultImage:[UIImage imageNamed:#"aff2010_l.png"]
URL:nil
accessoryURL:nil];
Thanks in advance.
Sorry, guys, I think I found my error. The record that's being returned for the castAndCrew object actually doesn't exist. My bad. Sorry :)

Iphone substring causing memory leak

Im just wrapping up my app, so im onto the stage of running instruments to identify leaks in the app. Ive come across a leak that I cannot work out why it is being registered as a leak.
I have the following lines for example:
NSString *imageType = [[[NSString alloc] initWithString:[loopString substringToIndex:[loopString rangeOfString:#"</IMAGE>"].location]] autorelease];
imageType = [imageType substringFromIndex:[imageType rangeOfString:#"<IMAGE>"].location + :#"<IMAGE>".length];
So basically all im doing is pulling out a section of the "loopstring" and putting that into the imagetype string than just cutting off the trailing fluff of the string using the SubstringFromIndex method.
When I run instruments it says "NSCFString substringwithRange" leak. It highlights the second line:
imageType = [imageType substringFromIndex:[imageType rangeOfString:#"<IMAGE>"].location + :#"<IMAGE>".length];
I would think the substringFromIndex method should return a string that is automatically added to the autorelease pool.
Any ideas on where im going wrong?
Thanks
Following is the refactored code:
- (void)SetupTop10:(NSString *)Top10Data
{
while (Top10Data != #"") {
NSLog(Top10Data);
if ([Top10Data rangeOfString:#"</TOP10ENTRY>"].location == NSNotFound){
Top10Data = #"";
}
else
{
NSString *loopString = [Top10Data substringToIndex:[Top10Data rangeOfString:#"</TOP10ENTRY>"].location + 13];
Top10Data = [Top10Data stringByReplacingOccurrencesOfString:loopString withString:#""];
//NOW CREATE A RECORD FOR THIS ITEM
NSString *imageType = [loopString substringToIndex:[loopString rangeOfString:#"</IMAGE>"].location];
imageType = [imageType substringFromIndex:[imageType rangeOfString:#"<IMAGE>"].location + 7];
NSString *displayText = [loopString substringToIndex:[loopString rangeOfString:#"</DISPLAYTEXT>"].location];
displayText = [displayText substringFromIndex:[displayText rangeOfString:#"<DISPLAYTEXT>"].location + 13];
NSString *link = [loopString substringToIndex:[loopString rangeOfString:#"</INTERESTID>"].location];
link = [link substringFromIndex:[link rangeOfString:#"<INTERESTID>"].location + 12];
[Top10Images addObject:imageType];
[Top10Links addObject:link];
[Top10s addObject:displayText];
Top10RowCount = Top10RowCount + 1;
}
}
[self.Top10Table reloadData];
Top10Table.hidden = NO;
loadingLabel.hidden = YES;
loadingIndicator.hidden = YES;
}
//******************
It doesn't look leaky. But why
NSString *imageType = [[[NSString alloc] initWithString:
[loopString substringToIndex:[loopString
rangeOfString:#"</IMAGE>"].location]
] autorelease];
if you effectively get the same with
NSString *imageType = [loopString substringToIndex:[loopString
rangeOfString:#"</IMAGE>"].location];
with half the memory usage?
Leaks will tell you where the leaked memory was allocated. If you click around (there's a right-arrow icon by the memory address, I think) then you can look at all the allocations/retains/releases for that addresses.
In this example, Leaks will point you to the first line, when it's the fifth one that "leaks" (actually it's a missing release in dealloc/on assignment that leaks):
NSString * s = [someString substringFromIndex:1];
[myArray addObject:s];
// ...
NSString * s2 = [myArray lastObject];
instanceVariable = [s2 retain];
// ... and forget to release in dealloc
What does tableView:cellForRowAtIndexPath: do?
I can't see any problem in the above code. Did you release Top10Images in your dealloc method?

MGTwitterEngine and iPhone

I downloaded MGTwitterEngine and added to my iPhone project. It's connecting and getting statues I can tell from dumping them into an NSLog. But, I can't figure out how how I need to parse the calls so I can add them to a table. They are returned as an NSString and look like this:
{
"created_at" = 2009-07-25 15:28:41 -0500;
favorited = 0;
id = 65;
source = "Twitter";
"source_api_request_type" = 0;
text = "The wolf shirt strikes again!! #sdcc :P http://twitpic.com/blz4b";
truncated = 0;
user = {
"created_at" = "Sat Jul 25 20:34:33 +0000 2009";
description = "Host of Tekzilla on Revision3 and Qore on PSN. Also, a geek.";
"favourites_count" = 0;
"followers_count" = 0;
following = false;
"friends_count" = 0;
id = 5;
location = "San Francisco";
name = "Veronica Belmont";
notifications = false;
"profile_background_tile" = false;
"profile_image_url" = "http://blabnow.com/avatar/Twitter_10350_new_twitter_normal.jpg";
protected = 0;
"screen_name" = Veronica;
"statuses_count" = 2;
"time_zone" = UTC;
url = "http://www.veronicabelmont.com";
"utc_offset" = 0;
};
Anybody used this that can tell me how everyone else uses it in their project?
Thanks
What you are seeing in your console is an NSLog of an NSDictionary and not an NSString. From Matt Gemmell's MGTwitterEngine Readme:
The values sent to these methods are all NSArrays containing an NSDictionary for each status or user or direct message, with sub-dictionaries if necessary (for example, the timeline methods usually return statuses, each of which has a sub-dictionary giving information about the user who posted that status).
So whatever object you passed to your NSLog() statement is actually a dictionary and you can access the fields with a call to:
NSString *createdAtDate = [record valueForKey:#"created_at"];
NSString *source = [record valueForKey:#"source"];
// etc...
Where record is the object. Keep in mind that the user field is a sub-dictionary. You access it this way:
NSDictionary *userDict = [record valueForKey:#"user"];
NSString *name = [userDict valueForKey:#"name"];
NSString *location = [userDict valueForKey:#"location"];
// etc...
You could actually use the NSArray returned in the request as your table view's data source and then just extract the one you need by the index in your -cellForRowAtIndexPath table view delegate.
Best Regards,
For anyone else who might find their way here, here's one way to parce the results. (From a newbie, so don't count of this being the standard or even correct way)
The key (pun intended :D) is to use the dictionary in the appropriate delegate method. Check out Matt Long's example code in another thread on the topic.
To parce something like this:
[myTwitterEngine getSearchResultsForQuery:#"#ironsavior"];
His example is this, in the delegate method:
- (void)searchResultsReceived:(NSArray *)searchResults
forRequest:(NSString *)connectionIdentifier
{
if ([searchResults count] > 0)
{
NSDictionary *result = [searchResults objectAtIndex:0];
NSString *fromUser = [result valueForKey:#"from_user"];
NSString *fromUserID = [result valueForKey#"from_user_id"];
// ...
NSString *text = [result valueForKey#"text"];
NSLog(#"User %#(%#): %#", fromUser, fromUserID, text);
}
}
This would give you a very simple message that goes "User username(userid): message".
I'm not sure what the best way to proceed would be, I'm thinking returning a dictionary or an array that you could use elsewhere in your implementation. Or just return the original array and parse it elsewhere.
Check out that other thread for more info.