how to call a function within class in objective c - iphone

i am new to objective c programming I want to call a function within anothor method please give me idea.
-(void) grabRSSFeed:(NSString *)blogAddress {
// Initialize the blogEntries MutableArray that we declared in the header
myBlogEntries = [[NSMutableArray alloc] init];
// Convert the supplied URL string into a usable URL object
NSURL *url = [NSURL URLWithString: blogAddress];
// Create a new rssParser object based on the TouchXML "CXMLDocument" class, this is the
// object that actually grabs and processes the RSS data
CXMLDocument *rssParser = [[[CXMLDocument alloc] initWithContentsOfURL:url options:0 error:nil] autorelease];
// Create a new Array object to be used with the looping of the results from the rssParser
NSArray *resultNodes = NULL;
// Set the resultNodes Array to contain an object for every instance of an node in our RSS feed
resultNodes = [rssParser nodesForXPath:#"//item" error:nil];
// Loop through the resultNodes to access each items actual data
for (CXMLElement *resultElement in resultNodes) {
// Create a temporary MutableDictionary to store the items fields in, which will eventually end up in blogEntries
NSMutableDictionary *blogItem = [[NSMutableDictionary alloc] init];
// Create a counter variable as type "int"
int counter;
// Loop through the children of the current node
for(counter = 0; counter < [resultElement childCount]; counter++) {
// Add each field to the blogItem Dictionary with the node name as key and node value as the value
[blogItem setObject:[[resultElement childAtIndex:counter] stringValue] forKey:[[resultElement childAtIndex:counter] name]];
}
// Add the blogItem to the global blogEntries Array so that the view can access it.
[myBlogEntries addObject:[blogItem copy]];
}
}
want to call above function in Babes Method
-(IBAction)babes
{
myview.hidden = FALSE;
[myview startAnimating];
feedurl = #"http://www.luxury.net/feed/rss/babes.xml";
//want to call it here.....
[self performSelector:#selector(moveAlert:) withObject:nil afterDelay: 0.7f];
}
but its not working please help me out thanks in advance.

You need to read the beginner documentation, start here: Learning Obj-C
For your problem specifically, try this:
NSString* aBlogAdress = #"http://anAdress.com";
[self grabRSSFeed:aBlogAddress];

You use self just as you are doing already, but you have to supply the argument correctly.
[self grabRSSFeed:#"http://someurl.com"];
The blogAddress is an NSString that you must supply somehow. For example, if you have a text view called textViewRSSFeed in your app, you would supply the value for that field.
[self grabRSSFeed:textViewRSSFeed.text];

-(void)grabRssFeed:(NSString *)str
{
}
-(void)ViewDidLoad
{
NSString *Str=#"www.anyUrl.com";
[Self grabRssFeed:Str];
}

Related

Modifying content from new dictionary also modifies the parent dictionary data

As I have a requirement to add similar objects into the array, I have created new dictionary in such a way.
NSMutableDictionary* existingStepDict = [[[arrayForSteps objectAtIndex:0] mutableCopy] autorelease];
[arrayForSteps addObject:existingStepDict];
[existingStepDict release];
Now, what happens here is that later when I change something in any one of the dictionary, the other one also gets updated. I require both these dictionaries to behave independently.
For that I went through Deep-copy of dictionaries whose code is like this.
NSMutableDictionary* existingStepDict = [[[arrayForSteps objectAtIndex:0] mutableCopy] autorelease];
NSMutableDictionary* destination = [NSMutableDictionary dictionaryWithCapacity:0];
NSDictionary *deepCopy = [[NSDictionary alloc] initWithDictionary:existingStepDict copyItems: YES];
if (deepCopy) {
[destination addEntriesFromDictionary: deepCopy];
[deepCopy release];
}
//add Properties array to Steps Dictionary
[arrayForSteps addObject:destination];
But this too didn't reflect the difference. I know I am making some minor mistake here.
But could some one help me getting my result?
Thanks a lot!
There's an easy way to get a full deepcopy of an NSDictionary o NSArray using the NSCoding (serialization) protocol.
- (id) deepCopy:(id)mutableObject
{
NSData *buffer = [NSKeyedArchiver archivedDataWithRootObject:mutableObject];
return [NSKeyedUnarchiver unarchiveObjectWithData: buffer];
}
In this way you can duplicate any object plus all the obects it contains in a single step.
when I need a mutable deep copy of a NSDictionary I create a Category with this method:
- (NSMutableDictionary *)mutableDeepCopy
{
NSMutableDictionary *returnDict = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
NSArray *keys = [self allKeys];
for (id key in keys) {
id oneValue = [self valueForKey:key];
id oneCopy = nil;
if ([oneValue respondsToSelector:#selector(mutableDeepCopy)]) {
oneCopy = [oneValue mutableDeepCopy];
} else if ([oneValue respondsToSelector:#selector(mutableCopy)]) {
oneCopy = [oneValue mutableCopy];
}
if (oneCopy == nil) {
oneCopy = [oneValue copy];
}
[returnDict setValue:oneCopy forKey:key];
}
return returnDict;
}
EDIT
and searching the web I found this, I haven't tested
NSMutableDictionary *mutableCopy = (NSMutableDictionary *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)originalDictionary, kCFPropertyListMutableContainers);

How to display Xpath on the iPhone

I'm trying to extract the weather information from here using Xpath on the iPhone. As of now it parses all the data but I'm stuck on how to extract the content and display it in a table.
This is what I have so far:
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[ #"http://aviationweather.gov/adds/metars/?station_ids=1234&std_trans=translated&chk_metars=on&hoursStr=most+recent+only&submitmet=Submit"stringByReplacingOccurrencesOfString:#"1234" withString:self.title]]];
TFHpple * doc = [[TFHpple alloc] initWithHTMLData:data];
NSArray * elements = [doc searchWithXPathQuery:#"//table[1]//tr"];
NSLog(#"%#", elements);
TFHppleElement * element = [elements objectAtIndex:0];
[element content]; // Tag's innerHTML
[element tagName]; // "a"
[element attributes]; // NSDictionary of href, class, id, etc.
[element objectForKey:#"href"]; // Easy access to single attribute
If anybody needs to see what its outputting so far, let me know.
Thanks,
Andrew
I had the same issue I got to the point your at and didn't no where to go but I end up implementing this code. Hope it helps there is still little bits need to make it work correctly but do to the nature of the app I have developed this is all I can give you. its not much more its just the actual implementation into your code that you need really.
#import "XPathQuery.h"
NSMutableArray *weatherArray = [[NSMutableArray arrayWithArray:0]retain]; // Initilize the NSMutableArray can also be done with just an NSArray but you will have to change the populateArray method.
NSString *xPathLookupQuery = #"//table[1]//tr"; // Path in xml
nodes = PerformXMLXPathQuery(data, xPathLookupQuery); // Pass the data in that you need to search through
[self populateArray:weatherArray fromNodes:nodes]; // To populate multiple values into array.
session = [[self fetchContent:nodes] retain]; // To populate a single value and returns value.
- (void)populateArray:(NSMutableArray *)array fromNodes:(NSArray *)nodes
{
for (NSDictionary *node in nodes) {
for (id key in node) {
if ([key isEqualToString:#"nodeContent"]) {
[array addObject:[node objectForKey:key]];
}
}
}
}
You only need either the above code or below code unless you want both.
- (NSString *)fetchContent:(NSArray *)nodes
{
NSString *result = #"";
for (NSDictionary *node in nodes) {
for (id key in node) {
if([key isEqualToString:#"nodeContent"]) {
result = [node objectForKey:key];
}
}
}
return result;
}

EXC_BAD_ACCESS error in during fetching data from custome objects

I had stored custom objects data in Array. I am fetching data from Array of custom objects in a function. when I am calling function for first time it is working good but When I am calling it again and again I am getting EXC_BAD_ACCESS.
Here is function details.
-(void) facebookDisplayFunction:(int)atIndex {
FacebookWallData *wall = (FacebookWallData *)[facebook_wallDataArray objectAtIndex:atIndex];
NSString *friendID= wall.actor_id;
NSString *linkFetch= wall.permalink;
NSString* postID=wall.postId;
NSNumber *countNumber;
NSString *friendName=#"";
NSString* profileThumImage=#"";
for(int i=0; i< [facebook_LikesArray count];i++) {
FacebookLikes* countValues=[[FacebookLikes alloc]init];
countValues=[facebook_LikesArray objectAtIndex:i];
// NSLog(#" postId_wall %# LikePostId = %#",postID,countValues.PostID);
if([postID isEqualToString:countValues.PostID]) {
countNumber=countValues.Count;
if(countNumber>0)
friendID=countValues.Friends;
[countValues release];
break;
}
[countValues release];
}
for(int i=0;i< [facebook_FreindsArray count];i++) {
FacebookFreinds* friendsRecord=[[FacebookFreinds alloc]init];
friendsRecord=[facebook_FreindsArray objectAtIndex:i];
if([friendID isEqualToString:friendsRecord.UID]) {
friendName=friendsRecord.name;
profileThumImage=friendsRecord.pic_smal;
[friendsRecord release];
break;
}
[friendsRecord release];
}
// Adding values in table //
[imageData addObject:#"facebook.png"];
[tableList addObject:wall.messages];
[profileUserName addObject:friendName];
[linksOfFacebookData addObject:linkFetch];
[RetweetAndLikeData addObject:#"5"];
[favedProfileThumb addObject:profileThumImage];
[twitterPostID addObject:#""];
[eachPostUID addObject:friendID];
[wall release];
}
And here I am calling function.
[self facebookDisplayFunction:0];
[self facebookDisplayFunction:0]; // EXC_BAD_ACCESS error here.
Why are you allocating an object like this FacebookLikes* countValues=[[FacebookLikes alloc]init] and then assigning to this same variable the instance inside the array with this code countValues=[facebook_LikesArray objectAtIndex:i] and later on you release it with this [countValues release]? You don't know what you are doing.
Try changing this:
FacebookLikes* countValues=[[FacebookLikes alloc]init];
countValues=[facebook_LikesArray objectAtIndex:i];
to this
FacebookLikes* countValues = [facebook_LikesArray objectAtIndex:i];
and remove all occurrences of [countValues release]. Do the same for the friendsRecord in the second for-loop. Also, what is the [wall release]? Remove it!
You should not allocate any of these objects because you are actually obtaining them from that array, and not creating a new instance. That just creates a leak in your code. You should not release any of these objects because they are retained by the array, and it is responsible for releasing them whenever they are removed from the array or after the array is destroyed/deallocated. Please, rtfm
If you get the error on the line:
[self facebookDisplayFunction:0];
it seems to me that most likely the object pointed by self has been deallocated. So, the problem would not be in facebookDisplayFunction...
Could you review how you create the object pointed by self, or post the code if you need more help?

Unable to parser using TouchXML

I am unable to parse response recieve using Touch XML My response from SOAP
<CXMLDocument 0x4b30110 [0x4b34c90]> <?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetImagesResponse xmlns="http://tempuri.org/">
<GetImagesResult>;http://www.google.com;http://www.hotmail.com;http://www.yahoo.com</GetImagesResult>
</GetImagesResponse>
</soap:Body>
</soap:Envelope>
/// Touch XML function
-(void) grabRSSFeed:(NSData *)responseData {
// Initialize the blogEntries MutableArray that we declared in the header
self.rssEntries = [[[NSMutableArray alloc] init] autorelease];
// Create a new rssParser object based on the TouchXML "CXMLDocument" class, this is the
// object that actually grabs and processes the RSS data
CXMLDocument *rssParser = [[CXMLDocument alloc] initWithData:responseData options:0 error:nil];
//CXMLDocument *rssParser = [[CXMLDocument alloc] initWithContentsOfURL:url options:0 error:nil];
NSLog(#"rssParser %#",rssParser);
//NSLog(#"url %#",url);
// Create a new Array object to be used with the looping of the results from the rssParser
NSArray *resultNodes = NULL;
// Set the resultNodes Array to contain an object for every instance of an node in our RSS feed
resultNodes = [rssParser nodesForXPath:#"//GetImagesResult" error:nil];
// Loop through the resultNodes to access each items actual data
for (CXMLElement *resultElement in resultNodes) {
// Create a temporary MutableDictionary to store the items fields in, which will eventually end up in blogEntries
NSMutableDictionary *blogItem = [[[NSMutableDictionary alloc] init] autorelease];
// Create a counter variable as type "int"
int counter;
// Loop through the children of the current node
for(counter = 0; counter < [resultElement childCount]; counter++) {
//[resultElement initWithXMLString:#""];
NSString *strValue = [[resultElement childAtIndex:counter] stringValue];
//strValue = [strValue stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSString *strName = [[resultElement childAtIndex:counter] name];
if ([resultNodes containsObject:#""] || resultNodes == nil || resultElement == nil || [resultElement isEqual:#""] || [resultElement children] == nil) {
NSLog(#"Null Object");
}
else {
if (strValue && strName) {
// Add each field to the blogItem Dictionary with the node name as key and node value as the value
[blogItem setObject:[[resultElement childAtIndex:counter] stringValue] forKey:[[resultElement childAtIndex:counter] name]];
}
}
}
// Add the blogItem to the global blogEntries Array so that the view can access it.
[self.rssEntries addObject:[blogItem copy]];
NSLog(#"RSS Entries %#",self.rssEntries);
}
[[rssParser retain] release];
}
Being "unable to parse response" is a very vague description of your problem. However, at first glance I noticed that this XPath query...
resultNodes = [rssParser nodesForXPath:#"//GetImagesResult" error:nil];
...is most likely not matching any elements and thus returning an empty array.
Why? Your XML has a namespace. Use nodesForXPath:namespaceMappings:error: method instead of nodesForXPath:error:. The former has an extra parameter that lets you provide a namespace mapping dictionary. Then edit your XPath query accordingly. See the example below:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
#"http://tempuri.org/",
#"tempuri",
nil];
// Set the resultNodes Array to contain an object for every instance of an node in our RSS feed
resultNodes = [rssParser nodesForXPath:#"//tempuri:GetImagesResult" namespaceMappings:dict error:nil];
Also, the last statement of the method is nonsense:
[[rssParser retain] release];
To balance the alloc-init, it should be:
[rssParser release];

how do I create fresh NSMutableArray?

I have an NSMutableArray which only lasts during the session.
Currently I create it like this
NSMutableArray *temp = [[NSMutableArray alloc] initWithCapacity:10];
[self setScoreArray:temp];
[temp release];
Problem is when I go to check each index I'm getting an array outofbounds error
NSNumber *previousScore = [[self scoreArray] objectAtIndex:[self quizNum]];
if ( previousScore != nil )
{
[self clearQuizBtns];
NSInteger previousScoreValue = [previousScore integerValue];
[self selectButtonAtTag:previousScoreValue];
}else {
[self clearQuizBtns];
}
I've read in other posts that initWithCapacity doesn't actually create the array. So what can I populate the array with initially?
Thanks in advance.
Two ways:
first: to initiate array with default values of NSNull class
NSMutableArray *temp = [[NSMutableArray alloc] initWithCapacity:10];
for (int i = 0 ; i < 10 ; i++)
{
[temp insertObject:[NSNull null] atIndex:i];
}
[self setScoreArray:temp];
[temp release];
and then to check: if object is kind of NSNull class means it was a never set before
id previousScore = [[self scoreArray] objectAtIndex:[self quizNum]];
if (![previousScore isKindOfClass:[NSNull class]])
{
[self clearQuizBtns];
NSInteger previousScoreValue = [(NSNumber *)previousScore integerValue];
[self selectButtonAtTag:previousScoreValue];
}else {
[self clearQuizBtns];
}
second: store scores in NSMutableDictionary and use NSNumber's as keys
// scoreDictionary property of NSMutableDictionary class must be declared in self
NSNumber *previousScore = [self.scoreDictionary objectForKey:[NSNumber numberWithInt:[self quizNum]]];
if (previousScore != nil)
{
[self clearQuizBtns];
NSInteger previousScoreValue = [previousScore integerValue];
[self selectButtonAtTag:previousScoreValue];
}else {
[self clearQuizBtns];
}
NSArray does not support "holes". The capacity is just a hint to the initializer.
You could either fill the array with placeholder objects or, more typically, change your algorithm to either fully prepopulate the array or to lazy load it linearly.
Your problem seems to be that you're never actually setting any score in the score array.. are you? NSArrays have an actual count of items in them, and accessing an index beyond that count will blow up, as you've seen. If there will only ever be a fixed (small) number of scores, like 10, then you could set them all initially to something default like:
for (int i = 0; i < 10; i++) {
[temp addObject:[NSNumber numberWithInt:0]];
}
P.S. -initWithCapacity does "create the array", it just doesn't create any objects in the array. The capacity is a hint only.
Using the arrayWithObject: or arrayWithObjects: methods can provide an array with pre-populated values.
One cool thing about NSMutableArrays is that you can just do an "init" and the array will handle adding and removing objects on the fly. Remember that you generally addObject: or removeObjectAtIndex: when dealing with mutable arrays.