Maybe someone can help ...
I have a problem with the fact that during the parsing of the XML file we have two arrays. Such is the construction of TWO identical returns an array:
xmlcont = [[XMLController alloc] loadXMLByURL:#"http://link_to_XML_file.xml"];
I have the following files:
Constants.h
#import <Foundation/Foundation.h>
extern NSString * const ITEM;
extern NSString * const TITLE;
extern NSString * const IMAGE;
extern NSString * const DESCRIPTION;
extern NSString * const TEXT;
#interface Constants : NSObject
{
}
#end
Constants.m
#import "Constants.h"
#implementation Constants
NSString * const ITEM = #"item";
NSString * const TITLE = #"title";
NSString * const IMAGE = #"image";
NSString * const DESCRIPTION = #"description";
NSString * const TEXT = #"text";
- (void)dealloc
{
[super dealloc];
}
#end
myNews.h
#import <Foundation/Foundation.h>
#interface myNews : NSObject
{
NSString *itemTitle;
NSString *itemImageUrl;
NSString *itemDescription;
NSString *itemText;
}
#property (nonatomic, retain) NSString *itemTitle;
#property (nonatomic, retain) NSString *itemImageUrl;
#property (nonatomic, retain) NSString *itemDescription;
#property (nonatomic, retain) NSString *itemText;
#end
myNews.m
#import "myNews.h"
#implementation myNews
#synthesize itemTitle;
#synthesize itemImageUrl;
#synthesize itemDescription;
#synthesize itemText;
#end
XMLController.h
#import <Foundation/Foundation.h>
#class Constants;
#class myNews;
#interface XMLController : NSObject
{
NSMutableString *currentNodeContent;
NSMutableArray *newsArray;
NSXMLParser *parser;
myNews *currentNew;
}
#property (readonly, retain) NSMutableArray *newsArray;
-(id)loadXMLByURL:(NSString *)urlString;
#end
XMLController.m
#import "XMLController.h"
#import "Constants.h"
#import "myNews.h"
#implementation XMLController
#synthesize newsArray;
-(id)loadXMLByURL:(NSString *)urlString
{
newsArray = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString: urlString];
parser = [[NSXMLParser alloc] initWithContentsOfURL: url];
[parser setDelegate:(id)self];
[parser parse];
return self;
}
-(void) parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString: ITEM])
{
currentNew = [myNews alloc];
currentNodeContent = [[NSMutableArray alloc] init];
}
}
-(void) parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString: TITLE])
{
currentNew.itemTitle = currentNodeContent;
}
if ([elementName isEqualToString: IMAGE])
{
currentNew.itemImageUrl = currentNodeContent;
}
if ([elementName isEqualToString: DESCRIPTION])
{
currentNew.itemDescription = currentNodeContent;
}
if ([elementName isEqualToString: TEXT])
{
currentNew.itemText = currentNodeContent;
}
if ([elementName isEqualToString: ITEM])
{
[newsArray addObject:currentNew];
[currentNew release];
currentNew = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
-(void) parser:(NSXMLParser *)parser
foundCharacters:(NSString *)string
{
currentNodeContent = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
#end
myAppDelegate.h
#import <UIKit/UIKit.h>
#import "MainViewController.h"
#import "DetailViewController.h"
#class MainViewController;
#class DetailViewController;
#interface myAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
UINavigationController *myNavigationController;
MainViewController *myMainViewController;
DetailViewController *myDetailViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *myNavigationController;
#property (nonatomic, retain) IBOutlet MainViewController *myMainViewController;
#property (nonatomic, retain) IBOutlet DetailViewController *myDetailViewController;
#end
myAppDelegate.m
#import "myAppDelegate.h"
#import "myNews.h"
#import "MainViewController.h"
#import "DetailViewController.h"
#implementation myAppDelegate
#synthesize window;
#synthesize myNavigationController;
#synthesize myMainViewController;
#synthesize myDetailViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[window addSubview:myNavigationController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)dealloc
{
[window release];
[myNavigationController release];
[myMainViewController release];
[myDetailViewController release];
[super dealloc];
}
#end
MainViewController.h
#import <UIKit/UIKit.h>
#import "XMLController.h"
#interface MainViewController : UIViewController
{
XMLController *xmlcont;
}
#end
MainViewController.m
#import "MainViewController.h"
#import "myNews.h"
#implementation MainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
xmlcont = [[XMLController alloc] loadXMLByURL:#"http://link_to_XML_file.xml"];
NSLog(#"array = %#", [xmlcont newsArray]);
for (myNews *oneNew in [xmlcont newsArray]) {
NSLog(#"URL = %#", [oneNew itemImageUrl]);
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)dealloc
{
[super dealloc];
}
#end
XML file:
<?xml version="1.0" encoding="UTF-8"?>
<channel>
<item>
<title>news 1</title>
<image>http://link_to_JPG_file_1.jpg</image>
<description>description 1</description>
<text>text 1</text>
</item>
<item>
<title>news 2</title>
<image>http://link_to_JPG_file_2.jpg</image>
<description>description 2</description>
<text>text 2</text>
</item>
</channel>
As a result, the implementation of the output I see:
2011-07-14 13:18:27.785 my[18673:207] array = (
"<myNews: 0x4e28dc0>",
"<myNews: 0x4e29080>"
)
2011-07-14 13:18:27.787 my[18673:207] URL = http://link_to_JPG_file_1.jpg
2011-07-14 13:18:27.818 my[18673:207] URL = http://link_to_JPG_file_2.jpg
2011-07-14 13:18:27.959 my[18673:207] array = (
"<myNews: 0x4b5a010>",
"<myNews: 0x4b5a310>"
)
2011-07-14 13:18:27.960 my[18673:207] URL = http://link_to_JPG_file_1.jpg
2011-07-14 13:18:27.963 my[18673:207] URL = http://link_to_JPG_file_2.jpg
MainWindow.xib
Screenshot MainWindow.xib
Please tell me where I could be wrong?
You're getting viewDidLoad called twice (which isn't necessarily a bug). You just need to add some logic to only load your XML once.
- (void)viewDidLoad
{
[super viewDidLoad];
if (nil == xmlcont) {
xmlcont = [[XMLController alloc] loadXMLByURL:#"http://link_to_XML_file.xml"];
NSLog(#"array = %#", [xmlcont newsArray]);
for (myNews *oneNew in [xmlcont newsArray]) {
NSLog(#"URL = %#", [oneNew itemImageUrl]);
}
}
}
PS If you add this code and still get the output twice then you're making two versions of the ViewController.
Related
I want to store the array of urls in my appdelegate array i.e. logoArray from myMutableArray and then use it in other viewcontroller, but i am uable to copy as may be i am doing shallow copy, i have tried othes ways also like initwithArray:copyItems.
code:-
#class FirstViewController;
#interface AppDelegate_iPhone : NSObject <UIApplicationDelegate> {
UIWindow *window;
FirstViewController *viewController;
NSMutableArray *logoArray;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) NSMutableArray *logoArray;
#end
// NO initialization of logoArra is done in .M file
#class AppDelegate_iPhone;
#interface FirstViewController : UIViewController {
NSMutableArray *array;
NSString *logoString;
AppDelegate_iPhone *appDelegate;
}
#end
#implementation FirstViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
int x=5,y=10;
UIApplication *app = [UIApplication sharedApplication];
appDelegate=app.delegate;
NSLog(#" Array ====== %d",[appDelegate.logoArray count]);
array = [[NSMutableArray alloc]initWithArray:appDelegate.logoArray];
NSLog(#"array at 0 ===== %#",[array objectAtIndex:0]);
for (int i=0; i<[array count]; i++) {
logoString = [array objectAtIndex:i];
NSLog(#"%#",logoString);
UIImage *imageFromUrl = [UIImage imageWithContentsOfFile:[NSURL fileURLWithPath:logoString]];
UIImageView *imgView = [[UIImageView alloc] initWithImage:imageFromUrl];
[imgView setFrame:CGRectMake(x, y, 196, 90)];
[self.view addSubview:imgView];
// UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onTapImage)];
// [imgView addGestureRecognizer:tgr];
// [tgr release];
//Do the rest of your operations here, don't forget to release the UIImageView
x = x + 200;
// [imgView release];
}
}
#class Litofinter,AppDelegate_iPhone;
#interface ParsingViewController : NSObject<NSXMLParserDelegate> {
NSString *myString;
NSMutableArray *myMutableArray;
Litofinter *obj;
NSString *currentElement;
AppDelegate_iPhone *appDelegate;
}
#property(nonatomic, retain) NSString *myString;
#property(nonatomic, retain) NSArray *myMutableArray;
#end
#import "ParsingViewController.h"
#import "Litofinter.h"
#import "AppDelegate_iPhone.h"
#implementation ParsingViewController
#synthesize myMutableArray, myString;
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
myMutableArray = [[NSMutableArray alloc]init];
}
// I have parsed here my XML and array gets stored in myMutableArray
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
UIApplication *app = [UIApplication sharedApplication];
appDelegate=app.delegate;
appDelegate.logoArray = [[NSMutableArray alloc]initWithArray:myMutableArray];
// NSLog(#"appDelegate.logoArray count %d",[appDelegate.logoArray count]);
for (Litofinter *lito in appDelegate.logoArray) {
NSLog(#"Array Elements :----- %#",lito.cLogo);
}
}
Personally I wouldn't create an array in a viewcontroller and then store it in the appdelegate. I'd be more inclined to create a model for the data ( a class that gets and stores the data and provides it to the view controllers).
this thread may help:
iPhone: Using a NSMutableArry in the AppDelegate as a Global Variable
Help find out how to solve the problem using the memory in my application, may have another way to implement my task.
Have the following code:
Constants.h
#import <Foundation/Foundation.h>
extern NSString * const ITEM;
extern NSString * const TITLE;
extern NSString * const IMAGE;
extern NSString * const DESCRIPTION;
extern NSString * const TEXT;
#interface Constants : NSObject
{
}
#end
Constants.m
#import "Constants.h"
#implementation Constants
NSString * const ITEM = #"item";
NSString * const TITLE = #"title";
NSString * const IMAGE = #"image";
NSString * const DESCRIPTION = #"description";
NSString * const TEXT = #"text";
- (void)dealloc
{
[super dealloc];
}
#end
myNews.h
#import <Foundation/Foundation.h>
#interface myNews : NSObject
{
NSString *itemTitle;
NSString *itemImageUrl;
NSString *itemDescription;
NSString *itemText;
}
#property (nonatomic, retain) NSString *itemTitle;
#property (nonatomic, retain) NSString *itemImageUrl;
#property (nonatomic, retain) NSString *itemDescription;
#property (nonatomic, retain) NSString *itemText;
#end
myNews.m
#import "myNews.h"
#implementation myNews
#synthesize itemTitle;
#synthesize itemImageUrl;
#synthesize itemDescription;
#synthesize itemText;
#end
XMLController.h
#import <Foundation/Foundation.h>
#class Constants;
#class myNews;
#interface XMLController : NSObject
{
NSMutableString *currentNodeContent;
NSMutableArray *newsArray;
NSXMLParser *parser;
myNews *currentNew;
}
#property (readonly, retain) NSMutableArray *newsArray;
-(id)loadXMLByURL:(NSString *)urlString;
#end
XMLController.m
#import "XMLController.h"
#import "Constants.h"
#import "myNews.h"
#implementation XMLController
#synthesize newsArray;
-(id)loadXMLByURL:(NSString *)urlString
{
newsArray = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString: urlString];
parser = [[NSXMLParser alloc] initWithContentsOfURL: url];
[parser setDelegate:(id)self];
[parser parse];
return self;
}
-(void) parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString: ITEM])
{
currentNew = [myNews alloc];
currentNodeContent = [[NSMutableArray alloc] init];
}
}
-(void) parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString: TITLE])
{
currentNew.itemTitle = currentNodeContent;
}
if ([elementName isEqualToString: IMAGE])
{
currentNew.itemImageUrl = currentNodeContent;
}
if ([elementName isEqualToString: DESCRIPTION])
{
currentNew.itemDescription = currentNodeContent;
}
if ([elementName isEqualToString: TEXT])
{
currentNew.itemText = currentNodeContent;
}
if ([elementName isEqualToString: ITEM])
{
[newsArray addObject:currentNew];
[currentNew release];
currentNew = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
-(void) parser:(NSXMLParser *)parser
foundCharacters:(NSString *)string
{
currentNodeContent = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
#end
myAppDelegate.h
#import <UIKit/UIKit.h>
#import "MainViewController.h"
#import "DetailViewController.h"
#class MainViewController;
#class DetailViewController;
#interface myAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
UINavigationController *myNavigationController;
MainViewController *myMainViewController;
DetailViewController *myDetailViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *myNavigationController;
#property (nonatomic, retain) IBOutlet MainViewController *myMainViewController;
#property (nonatomic, retain) IBOutlet DetailViewController *myDetailViewController;
#end
myAppDelegate.m
#import "myAppDelegate.h"
#import "myNews.h"
#import "MainViewController.h"
#import "DetailViewController.h"
#implementation myAppDelegate
#synthesize window;
#synthesize myNavigationController;
#synthesize myMainViewController;
#synthesize myDetailViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[window addSubview:myNavigationController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)dealloc
{
[window release];
[myNavigationController release];
[myMainViewController release];
[myDetailViewController release];
[super dealloc];
}
#end
MainViewController.h
#import <UIKit/UIKit.h>
#import "XMLController.h"
#interface MainViewController : UIViewController
{
XMLController *xmlcont;
UILabel *myTitleLabel;
// declared here some 10 objects
}
#property (nonatomic, retain) UILabel *myTitleLabel;
#end
MainViewController.m
#import "MainViewController.h"
#import "myNews.h"
#implementation MainViewController
#synthesize myTitleLabel;
- (void)completeRefresh
{
[myMainViewController viewDidLoad];
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *myRefreshButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 35.0f, 23.0f)];
[myRefreshButton setImage:[UIImage imageNamed:#"ButtonRefresh.png"] forState:UIControlStateNormal];
[myRefreshButton addTarget:self
action:#selector(completeRefresh)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *myRefreshBarButton = [[[UIBarButtonItem alloc] initWithCustomView:myRefreshButton] autorelease];
[self.navigationItem setRightBarButtonItem: myRefreshBarButton];
[myRefreshButton release];
xmlcont = [[XMLController alloc] loadXMLByURL:#"http://link_to_XML_file.xml"];
NSLog(#"array = %#", [xmlcont newsArray]);
for (myNews *oneNew in [xmlcont newsArray]) {
CGRect frameTitleLabel = CGRectMake(0.0f, 200.0f, 320.0f, 60.0f);
myTitleLabel = [[UILabel alloc] initWithFrame:frameTitleLabel];
myTitleLabel.backgroundColor = [UIColor blackColor];
myTitleLabel.text = [myOneNew itemTitle];
myTitleLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size: 17.0];
myTitleLabel.textColor = [UIColor whiteColor];
[self.view addSubview:myTitleLabel];
[myTitleLabel release];
}
}
- (void)viewDidUnload
{
self.myTitleLabel = nil;
[super viewDidUnload];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)dealloc
{
[myTitleLabel release];
[super dealloc];
}
#end
During the test the application using the Instruments: Activity Monitor shows that when you click refresh and call 'completeRefresh' memory (Real Mem) is not cleared when reload viewDidLoad, and accumulates with every touch and calling 'completeRefresh'
Maybe someone has a possible solution?
To avoid leaking memory you need to release your retained ivars/properties in dealloc. For example:
myNews.m
- (void)dealloc {
// Setting these properties to nil releases them because they're (nonatomic, retain)
self.itemTitle = nil;
self.itemImageUrl = nil;
self.itemDescription = nil;
self.itemText = nil;
[super dealloc];
}
XMLController.m
- (void)dealloc {
self.newsArray = nil;
// These ivars aren't properties so you just have to call release on them
[currentNodeContent release];
[parser release];
[currentNew release];
[super dealloc];
}
etc. Do this for all your classes.
hello i want to parse html an with this information another html file...
after 1-5 call the program crashes...
header:
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController <ZBarReaderDelegate, NSXMLParserDelegate>{
UIImageView *resultImage;
UITextView *resultText;
NSString *product_link;
NSXMLParser *parseHTML;
NSXMLParser *parseHTML2;
NSMutableArray *myMutableArray;
id <NSXMLParserDelegate> testkollege, asdf;
}
#property (nonatomic, retain) IBOutlet UIImageView *resultImage;
#property (nonatomic, retain) IBOutlet UITextView *resultText;
#property (nonatomic, assign) IBOutlet NSString *product_link;
#property (nonatomic, assign) NSXMLParser *parseHTML;
#property (nonatomic, assign) NSXMLParser *parseHTML2;
#property (nonatomic, retain) NSMutableArray *myMutableArray;
#property (nonatomic, assign) id <NSXMLParserDelegate> testkollege;
#property (nonatomic, assign) id <NSXMLParserDelegate> asdf;
- (IBAction) scanButtonTapped;
#end
m-file:
#import "FirstViewController.h"
#import "/System/Library/Frameworks/Foundation.framework/Headers/NSDebug.h"
#implementation FirstViewController
#synthesize resultImage, resultText;
#synthesize product_link;
#synthesize parseHTML, parseHTML2;
#synthesize myMutableArray;
#synthesize testkollege, asdf;
bool link_is_here = false;
bool allergy_is_here = false;
bool parse_one_ok = true;
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results = [info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
// EXAMPLE: do something useful with the barcode data
resultText.text = symbol.data;
// EXAMPLE: do something useful with the barcode image
resultImage.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissModalViewControllerAnimated: YES];
parseHTML = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:[#"http://url.com/suche/?q=" stringByAppendingString:symbol.data]] ];
NSLog(#"parser 1 start");
[parseHTML setDelegate:self];
[parseHTML parse];
NSLog(#"parser 1 ready");
[parseHTML release];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
for(NSString *key in [attributeDict allKeys]) {
if ([[attributeDict valueForKey:key] isEqualToString:#"search-result"]) {
link_is_here = true;
}
if ([key isEqualToString:#"href"] && link_is_here) {
product_link = [attributeDict valueForKey:key];
[parser abortParsing];
parseHTML2 = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:[#"http://url.com" stringByAppendingString:product_link]]];
[parseHTML2 setDelegate:self];
parse_one_ok = true;
link_is_here = false;
[parseHTML2 parse];
}
if ([key isEqualToString:#"id"] && [[attributeDict valueForKey:key] isEqualToString:#"nutrition-allergy"]) {
allergy_is_here = true;
}
if ([key isEqualToString:#"title"] && allergy_is_here) {
NSLog(#"keys: %#",[attributeDict valueForKey:key]);
}
if ([key isEqualToString:#"id"] && [[attributeDict valueForKey:key] isEqualToString:#"another string"]) {
allergy_is_here = false;
parse_one_ok = true;
NSLog(#"Parser off");
[parser abortParsing];
}
}
}
-(void) parserDidEndDocument:(NSXMLParser *)parser{
if (parse_one_ok) {
[parseHTML2 release];
parse_one_ok = false;
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[parseHTML release];
[parseHTML2 release];
self.product_link = nil;
self.resultImage = nil;
self.resultText = nil;
[super dealloc];
}
#end
that is simple. You are releasing ParseHTML NSXMLPArsetwice.
-(void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
in the lastline
-(void)dealloc.
A object should be release only if you have earned the ownership. by retain copy etc. But you have allocated it only once so should release only once. But you did two releases .
You are also releasing NSXMLParser object parseHTML2 thrice. As per your code at any stage parseHTML2 will be released at least twice which is retained only once. ParseHTML1 objects case have been mentioned above
Regards,
Jackson Sunny Rodrigues
Turn on NSZombieEnabled. You are obviously releasing something you shouldn't be. When you do this, it will show you exactly where the bad access is occurring and you can trace back to where you are releasing the object. Check out this tutorial:
http://www.codza.com/how-to-debug-exc_bad_access-on-iphone
Best to learn how to fix it and what's wrong :)
This is similar to my previous question. I didn't get an answer, maybe by changing the question I might get an answer.
Here is my parsing code:
-(void) parser:(NSXMLParser *) parser didStartElement:(NSString *) elementName
namespaceURI:(NSString *) namespaceURI
qualifiedName:(NSString *) qName
attributes:(NSDictionary *) attributeDict
{
if ([elementName isEqualToString:kimgurl]
|| [elementName isEqualToString:kone_x]
|| [elementName isEqualToString:kone_y]
|| [elementName isEqualToString:kone_radius]
|| [elementName isEqualToString:ktwo_x]
|| [elementName isEqualToString:ktwo_y]
|| [elementName isEqualToString:ktwo_radius])
{
elementFound = YES;
theItems = [[Items alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:kimgurl])
{
theItems.imageURL = self.currentValue;
[self.currentValue setString:#""];
}
else if([elementName isEqualToString:kone_x])
{
theItems.iOne_X = self.currentValue;
[self.currentValue setString:#""];
}
else if([elementName isEqualToString:kone_y])
{
theItems.iOne_Y = self.currentValue;
[self.currentValue setString:#""];
}
else if([elementName isEqualToString:kone_radius])
{
theItems.iOne_Radius = self.currentValue;
[self.currentValue setString:#""];
}
else if([elementName isEqualToString:ktwo_x])
{
theItems.iTwo_X = self.currentValue;
[self.currentValue setString:#""];
}
else if([elementName isEqualToString:ktwo_y])
{
theItems.iTwo_Y = self.currentValue;
[self.currentValue setString:#""];
}
else if([elementName isEqualToString:ktwo_radius])
{
theItems.iTwo_Radius = self.currentValue;
[self.currentValue setString:#""];
}
}
-(void) parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(#"enddocument: %#", theItems.imageURL);
}
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string
{
if (elementFound == YES) {
if(!currentValue)
{
currentValue = [NSMutableString string];
}
[currentValue appendString: string];
}
}
When I get to parserDidEndDocument. The theItems class is empty.
Here is Items.h
#import <Foundation/Foundation.h>
#interface Items : NSObject {
#private
//parsed data
NSString *imageURL;
NSString *iOne_X;
NSString *iOne_Y;
NSString *iOne_Radius;
NSString *iTwo_X;
NSString *iTwo_Y;
NSString *iTwo_Radius;
}
#property (nonatomic, retain) NSString *imageURL;
#property (nonatomic, retain) NSString *iOne_X;
#property (nonatomic, retain) NSString *iOne_Y;
#property (nonatomic, retain) NSString *iOne_Radius;
#property (nonatomic, retain) NSString *iTwo_X;
#property (nonatomic, retain) NSString *iTwo_Y;
#property (nonatomic, retain) NSString *iTwo_Radius;
#end
here is Items.m
#import "Items.h"
#implementation Items
#synthesize imageURL;
#synthesize iOne_X;
#synthesize iOne_Y;
#synthesize iOne_Radius;
#synthesize iTwo_X;
#synthesize iTwo_Y;
#synthesize iTwo_Radius;
-(void)dealloc
{
[imageURL release];
[iOne_X release];
[iOne_Y release];
[iOne_Radius release];
[iTwo_X release];
[iTwo_Y release];
[iTwo_Radius release];
[super dealloc];
}
#end
here is my RootViewController.h
#import <UIKit/UIKit.h>
#class Items;
#interface RootViewController : UIViewController <NSXMLParserDelegate> {
NSMutableData *downloadData;
NSURLConnection *connection;
BOOL elementFound;
NSMutableString *currentValue;
NSMutableDictionary *pictures;
//---xml parsing---
NSXMLParser *xmlParser;
Items *theItems;
NSMutableArray *aItems;
}
#property (nonatomic, retain) Items *theItems;
#property (nonatomic, retain) NSMutableArray *aItems;
#property (nonatomic, retain) NSMutableString *currentValue;
#property (nonatomic, retain) NSMutableData *downloadData;
#property (nonatomic, retain) NSURLConnection *connection;
#end
xml file example
<?xml version="1.0" encoding="utf-8"?>
<data>
<test>
<url>url</url>
<one_x>83</one_x>
<one_y>187</one_y>
<one_radius>80</one_radius>
<two_x>183</two_x>
<two_y>193</two_y>
<two_radius>76</two_radius>
</test>
</data>
It looks like there are a couple of potential problems. In your didStartElement method you are alloc/init'ing a new Items object for every element and overwriting your previous one. Perhaps you can move the Items init into your –parserDidStartDocument: method. When you init, it should also look more like this:
Items *items = [[Items alloc] init];
self.theItems = items;
[items release];
Then you'll have the correct retain count when you are done.
I'd also recommend changing your NSString #property declarations to be copy instead of retain. The code:
theItems.imageURL = self.currentValue;
[self.currentValue setString:#""];
... isn't doing what you think. theItems.imageURL is going to be pointing at your NSMutableString and then you clear the mutable string right after which means imageURL is pointing at an empty mutable string. Then after all of the other iterations, all of them are pointing at the same NSMutableString which is empty. If you change the #property declarations to copy, then it'll set imageURL to an immutable NSString copy of the contents of self.currentValue.
this code is from a sample
in .h part :
#interface ViewController : UITableViewController < NSNetServiceBrowserDelegate > {
NSMutableArray * tableData;
NSNetServiceBrowser * _browser;
NSMutableArray * _foundServices;
NSURLConnection * _connection;
NSInputStream * _consumerStream;
NSString * controllerHostName;
}
#property (nonatomic, retain) NSMutableArray * tableData;
#property (nonatomic, retain) NSNetServiceBrowser * _browser;
#property (nonatomic, retain) NSMutableArray * _foundServices;
#property (nonatomic, retain) NSURLConnection * connection;
#property (nonatomic, retain) NSInputStream * consumerStream;
#property (nonatomic, retain) NSString * controllerHostName;
in the .m part
#import "ViewController.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <CFNetwork/CFNetwork.h>
#synthesize tableData;
#synthesize _browser;
#synthesize _foundServices;
#synthesize consumerStream = _consumerStream;
#synthesize connection = _connection;
#synthesize controllerHostName;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_browser = [[NSNetServiceBrowser alloc] init];
[_browser setDelegate:self];
[_browser searchForServicesOfType:#"_service._tcp" inDomain:#""];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[_browser stop];
_browser.delegate = nil;
[_browser release];
_browser = nil;
[_foundServices removeAllObjects];
}
- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing
{
self.controllerHostName = [NSString stringWithFormat:#"%#.%#", netService.name, netService.domain];
NSLog(#"ControllerHost String is: %#", self.controllerHostName);
NSLog(#"URL to use is === %#.%#", netService.name, netService.domain);
if (!_foundServices) {
_foundServices = [[NSMutableArray alloc] init];
}
[_foundServices addObject:netService];
[self.tableView reloadData];
}
- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didRemoveService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing
{
[_foundServices removeObject:netService];
}
- (void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)aNetServiceBrowser
{
[_foundServices removeAllObjects];
}
I declaration all the header as the sample does
But I got error message "Cannot find protocol declaration for "NSNetServiceDelegate"
in .h
interface ViewController : UITableViewController < NSNetServiceBrowserDelegate >
So did I missing anything to declaration ?
The sample doesn't has any warning or error
I thought it's defined in "NSNetServices.h" instead?
Add this to your header:
#import <Foundation/NSNetServices.h>
I got this from the BonjourWeb Apple sample code project.
The problem is a unused function. Just delete:
[self.tableView reloadData];
It will be fine!
I found something like answer ,JUST REMOVE
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[_browser stop];
_browser.delegate = nil;
[_browser release];
_browser = nil;
[_foundServices removeAllObjects];
}
The program will get Netservice I want...
WHY ?