NSXMLParser values not being retained - iphone

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.

Related

Push TableView Url to webView

i have a problem with my table, i use LazyTableImages example from Apple before embed into my project.
Every work fine when load my xml like this
<im:title>1</im:title>
<content type="html">some desc</content>
<im:releaseDate label="October 23, 2013">2013-10-23T00:00:00-07:00</im:releaseDate>
<im:artist href="http:/facebook.com">Facebook</im:artist>
<im:name>1</im:name>
<im:image height="53">http://chingfong.com/Icon.png</im:image>
<url>http://facebook.com/url>
<im:date>Ene, 27 2013</im:date>
and here is my AppRecord.h
#property (nonatomic, strong) NSString *appName;
#property (nonatomic, strong) UIImage *appIcon;
#property (nonatomic, strong) NSString *artist;
#property (nonatomic, strong) NSString *imageURLString;
#property (nonatomic, strong) NSString *appURLString;
#property (nonatomic, strong) NSString *appURL;
ParseOperation.h - i also added
static NSString *kUrlStr = #"url";
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if (self.workingEntry)
{
if (self.storingCharacterData)
{
NSString *trimmedString = [self.workingPropertyString stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[self.workingPropertyString setString:#""]; // clear the string for next time
if ([elementName isEqualToString:kIDStr])
{
self.workingEntry.appURLString = trimmedString;
}
else if ([elementName isEqualToString:kNameStr])
{
self.workingEntry.appName = trimmedString;
}
else if ([elementName isEqualToString:kImageStr])
{
self.workingEntry.imageURLString = trimmedString;
}
else if ([elementName isEqualToString:kUrlStr])
{
self.workingEntry.appURL = trimmedString;
}
else if ([elementName isEqualToString:kArtistStr])
{
self.workingEntry.artist = trimmedString;
}
}
else if ([elementName isEqualToString:kEntryStr])
{
[self.workingArray addObject:self.workingEntry];
self.workingEntry = nil;
}
}
}
RootViewController.m in tableView didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
NSString *urlAddress = appRecord.appURL;
NSURL *url = [NSURL URLWithString:urlAddress];
WebViewController *detailViewController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:nil];
// WebViewController.sites= [_entries objectAtIndex:indexPath.row];
[detailViewController.webView loadRequest:[NSURLRequest requestWithURL:url]];
[self.navigationController pushViewController:detailViewController animated:YES];
}
WebViewController.h
#interface WebViewController : UIViewController <UIWebViewDelegate>
#property (nonatomic, strong) IBOutlet UIWebView *webView;
The table load fine, and it push to WebViewController when i selected cell but the UIWebView didn't load the web page, it's only blank (white).
can anyone help me to fix it?
thanks so much!
I think the best way for you is to pass the url from RootViewController to WebViewController and refresh your webview in WebViewController.
So you need to modify your code like this :
RootViewController.m in tableView didSelectRowAtIndexPath
// Add a #property of your detail view for lazing
#property (nonatomic, strong) WebViewController *detailViewController;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
if (!_detailViewController)
self.detailViewController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:nil];
self.detailViewController.websiteURL = appRecord.appURL;
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
WebViewController.h
#interface WebViewController : UIViewController <UIWebViewDelegate>
#property (nonatomic, strong) IBOutlet UIWebView *webView;
#property (nonatomic, strong) NSString *websiteURL;
WebViewController.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// URL Request Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:[NSURL URLWithString:_websiteURL]];
// Load the request in the UIWebView
[_webView loadRequest:requestObj];
}

Insert Managed Object into CoreData from xml

This is my first time trying to accomplish core data and been having some issues getting things working. I have a xml parser in my app that I have been trying to add all the info into core data from but keep crashing on start. I have my core data set up with 1 Entity as "Themes". In that entity I have 15 attributes. Below is the automatic file xcode can created for a ManagedObject after I created my .CoreData.
Themes.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface Themes : NSManagedObject
#property (nonatomic, retain) NSString * themeName;
#property (nonatomic, retain) NSString * themeArtist;
#property (nonatomic, retain) NSString * themeImage;
#property (nonatomic, retain) NSString * themeDescription;
#property (nonatomic, retain) NSString * twitterName;
#property (nonatomic, retain) NSString * themePrice;
#property (nonatomic, retain) NSString * screenshots;
#property (nonatomic, retain) NSString * cydiaLink;
#property (nonatomic, retain) NSString * themeVersion;
#property (nonatomic, retain) NSString * deciption;
#property (nonatomic, retain) NSString * repo;
#property (nonatomic, retain) NSString * hd;
#property (nonatomic, retain) NSString * sd;
#property (nonatomic, retain) NSString * ipad;
#end
#import "Themes.h"
#implementation Themes
#dynamic themeName;
#dynamic themeArtist;
#dynamic themeImage;
#dynamic themeDescription;
#dynamic twitterName;
#dynamic themePrice;
#dynamic screenshots;
#dynamic cydiaLink;
#dynamic themeVersion;
#dynamic deciption;
#dynamic repo;
#dynamic hd;
#dynamic sd;
#dynamic ipad;
-(void)setThemeName:(NSString *)themeName{
self.themeName = [themeName copy];
}
#end
Here is my xml Parser files where all the magic is supposed to happen. Overall everything works great with my parser it is just when I do
"themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:themesObjects.themeName"
inManagedObjectContext:managedObjectContext];"
the app will crash I assume because I am not correctly inserting the object into the coredata.
#import <Foundation/Foundation.h>
#import "ThemeParseObject.h"
#import "Themes.h"
#class ThemeParseObject;
#interface ThemeXMLParser : NSObject <NSXMLParserDelegate> {
NSMutableData *recivedData;
NSMutableArray *themes;
NSMutableString *currentNodeContent;
NSXMLParser *parser;
Themes *themesObjects;
NSManagedObjectContext *managedObjectContext;
NSMutableArray *themeArray;
ThemeParseObject *currentTheme;
}
#property (readonly, retain) NSMutableArray *themes;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain) NSMutableArray *themeArray;
-(id) loadXMLByURL:(NSString *)urlString;
#end
#import "ThemeXMLParser.h"
#implementation ThemeXMLParser
#synthesize themes;
#synthesize managedObjectContext;
#synthesize themeArray;
-(id) loadXMLByURL:(NSString *)urlString{
themesObjects = [[Themes alloc]init];
managedObjectContext = [[NSManagedObjectContext alloc] init];
themes = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
return self;
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"theme"])
{
currentTheme = [ThemeParseObject alloc];
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *ObjectsToInsert = [NSEntityDescription
insertNewObjectForEntityForName:#"Themes"
inManagedObjectContext:context];
if ([elementName isEqualToString:#"name"]) {
currentTheme.themeNameString = currentNodeContent;
themesObjects.themeName = currentTheme.themeNameString;
[ObjectsToInsert setValue:themesObjects.themeName forKey:#"themeName"];
}
if ([elementName isEqualToString:#"creator"]) {
currentTheme.themeCreator = currentNodeContent;
// themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:#"themeArtist"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:#"price"]) {
currentTheme.themePrice = currentNodeContent;
//themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:#"themePrice"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:#"twitter"]) {
currentTheme.creatorTwitterName = currentNodeContent;
//themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:#"twitterName"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:#"link"]) {
currentTheme.cydiaLink = currentNodeContent;
//themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:#"cydiaLink"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:#"deciption"]) {
currentTheme.deciption = currentNodeContent;
//themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:#"deciption"
inManagedObjectContext:managedObjectContext];
}
if ([elementName isEqualToString:#"screenshots"]) {
currentTheme.screenShots = currentNodeContent;
}
if ([elementName isEqualToString:#"promo"]) {
currentTheme.tblViewImage = currentNodeContent;
}
if ([elementName isEqualToString:#"description"]) {
currentTheme.themeDescription = currentNodeContent;
}
if ([elementName isEqualToString:#"version"]) {
currentTheme.themeVersion = currentNodeContent;
// NSLog(#"version: %#", currentNodeContent);
}
if ([elementName isEqualToString:#"repo"]) {
currentTheme.themeRepo = currentNodeContent;
// NSLog(#"repo: %#", currentNodeContent);
}
if ([elementName isEqualToString:#"HD"]) {
currentTheme.HD = currentNodeContent;
// NSLog(#"HD: %#", currentNodeContent);
}
if ([elementName isEqualToString:#"SD"]) {
currentTheme.SD = currentNodeContent;
// NSLog(#"SD: %#", currentNodeContent);
}
if ([elementName isEqualToString:#"iPad"]) {
currentTheme.ipad = currentNodeContent;
//NSLog(#"iPad: %#", currentNodeContent);
}
if ([elementName isEqualToString:#"iPhoneScreenshots"]) {
currentTheme.fullScreenShots = currentNodeContent;
// themesObjects = (Themes *)[NSEntityDescription
insertNewObjectForEntityForName:#"screenshots"
inManagedObjectContext:managedObjectContext];
// NSLog(#"fullScreenShots: %#", currentNodeContent);
}
if ([elementName isEqualToString:#"theme"])
{
[themes addObject:currentTheme];
[currentTheme release];
currentTheme = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
This is what gets logged when the app crashes
2012-01-06 08:02:18.619 ThemeCatcher[2667:207] CoreData: error: Failed to call
designated initializer on NSManagedObject class 'Themes'
2012-01-06 08:02:19.000 ThemeCatcher[2667:207] -[Themes themeName]: unrecognized
selector sent to instance 0x87072d0
If anyone has any suggestion or ideas where I can go from here that would be awesome. I apologize if this seems like a lot of code to look at but I felt it was nessicarry to give others an idea what really is going on inside the code... Thank you I appreciate any help given immensely!
themesObjects = [[Themes alloc]init];
managedObjectContext = [[NSManagedObjectContext alloc] init];
I see two things wrong in these two lines. First, you're not using the designated initializer for NSManagedObject in your Themes initializer. I know that for two reasons: a) that's exactly what the error message says; b) the initializer can't know what context to use because you haven't created the context at that point. The designated initializer for NSManagedObjectContext is:
-initWithEntity:insertIntoManagedObjectContext:
However, it's common practice to use NSEntityDescription's + insertNewObjectForEntityForName:inManagedObjectContext: convenience method to create and add new objects to a context instead. Either way, you need to use one of these.
The second problem is that you don't have a managed object context when you create your Themes object, and it looks like you're not setting up the context correctly when you do create it. You should be setting a persistent store coordinator for the context after you create it.
Update: A third problem is that when you write:
themesObjects = (Themes *)[NSEntityDescription insertNewObjectForEntityForName:themesObjects.themeName" inManagedObjectContext:managedObjectContext];
you need to make sure that the model has an entity that matches the value of themeObjects.themeName. It'd be unusual to use data that you get from an XML file to determine the theme name, because a mistake in the XML file would cause an error, and also because it strongly ties the structure of the XML to your Core Data model. Be sure that you're not confusing the concept of XML entity with Core Data entity -- those are two different things. Core Data entities are the different types of objects in your model; you probably have an entity for Themes, for example.

I Can't Insert an Object in a NSMutableArray when I parse a XML

The Code:
...
else if ([elementName isEqualToString:#"photo"]) {
NSLog(#"Trying to add photo");
NSLog(#"Prev: %d",[currentItem.photoList count]);
NSLog(#"Author: %#",[currentPhotoItem author ]);
[currentItem.photoList addObject:currentPhotoItem];
NSLog(#"Next: %d",[currentItem.photoList count]);
}
The Log:
2011-10-11 09:49:13.553 ECG[4862:b303] Trying to add photo
2011-10-11 09:49:13.553 ECG[4862:b303] Prev: 0
2011-10-11 09:49:13.554 ECG[4862:b303] Author: Fernando Blanco
2011-10-11 09:49:13.573 ECG[4862:b303] Next: 0
The method addObject doesn't add objects to the NSMutableArray...
"photoList" is a NSMutableString defined in the class:
#interface GalleryRSSItem : NSObject {
NSString *title;
NSString *imgtn;
NSString *category;
NSString *url;
NSString *date;
NSMutableArray *photoList;
}
#property (nonatomic, retain) NSString *title;
#property (nonatomic, retain) NSString *imgtn;
#property (nonatomic, retain) NSString *category;
#property (nonatomic, retain) NSString *url;
#property (nonatomic, retain) NSString *date;
#property (nonatomic, retain) NSMutableArray *photoList;
#end
And the objects are initialized in the parser didStartElemnt method
- (void) parser:(NSXMLParser *) Parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"gallery"]) {
currentItem = [[GalleryRSSItem alloc] init];
currentNodeContent = [[NSMutableArray alloc] init];
}
if ([elementName isEqualToString:#"photo"]) {
currentPhotoItem = [[PhotoRSSItem alloc] init];
currentNodeContent = [[NSMutableArray alloc] init];
}
}
Check if you have properly initialized currentItem.photoList array.
I guess, either currentItem or currentItem.photoList is NIL. Obj-C allows to call methods on nil objects and the count call will return 0 in such case.

NSXMLParser: Parsing XML file shows two identical arrays

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.

NSXMLParser multiple call - BAD ACCESS

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 :)