سؤال

I searched a lot for similar questions, but couldn't figure out my problem.

I have an app in which I've embedded an RSS feed file. What I do is that in my root view controller, I load that local file and parse it, and display the data in the table view. I also save the GUID of each item in an array.

I want to I get the RSS feed link from the server and parse it, if the user has internet access, and then save the GUIDs of the items in that file to another array, and compare the two arrays, and then add the new items to the current list in my table view.

I have NIKFeedEntry as an NSObject model for my parsed data, and an NSXMLParser. I'm instantiating it with two different parser objects for the two URLs, but they're both being written in the same object. Therefore the first set of parsed data is displayed for a very short time, and then the table view reloads data with the new parsed data, and I don't know how to fix this so that after parsing the second URL, it compares the two arrays of the GUIDs, if there are any new ones, append those items (the XML data) to my local XML file, and display this combination of the old and new data.

Here's my NIKFeedEntry.m:

#import "NIKFeedEntry.h"

@implementation NIKFeedEntry

@synthesize lastBuildDate;
@synthesize radioTitle;
@synthesize podcastTitle;
@synthesize podcastDate;
@synthesize podcastURL;

@synthesize podcastAuthor;
@synthesize podcastContent;
@synthesize podcastGUID;
@synthesize podcastDownloadURL;
@synthesize podcastLinkURL;
@synthesize podcastSummary;
@synthesize categories;

- (id)initWithRadioTitle:(NSString*)radioTitle lastBuildDate:(NSDate*)lastBuildDate podcastTitle:(NSString*)podcastTitle podcastFile:(NSString*)podcastFile podcastDate:(NSDate*)podcastDate podcastDownloadURL:(NSString*)podcastDownloadURL
{
    return self;
}

@end

And my NIKFeedParser.m:

//  NIKFeedParser.m

#import "NIKFeedParser.h"
#import "NIKMasterViewController.h"

@class NIKMasterViewController;

NIKMasterViewController *masterVC;


@interface NIKFeedParser (Private)

- (NSString *)trimString:(NSString *)originalString;

@end

@implementation NIKFeedParser

@synthesize currentItem;
@synthesize currentItemValue;
@synthesize feedItems;
@synthesize delegate;
@synthesize retrieverQueue;
@synthesize parsingFeedsWithNumbers;
@synthesize queue;
@synthesize selectedCategory;
@synthesize feedURL;
@synthesize downloadURL;
@synthesize lastModified;
@synthesize RSSURL;
@synthesize updatedGUIDs;

- (id)initWithRSSURL:(NSURL *)rssURL{
    self = [super init];
    if (self) {
        feedItems = [[NSMutableArray alloc]init];
        RSSURL = rssURL;
    }
    return self;
}


- (NSOperationQueue *)retrieverQueue
{
    if (nil == retrieverQueue)
    {
        retrieverQueue = [[NSOperationQueue alloc] init];
        retrieverQueue.maxConcurrentOperationCount = 1;
    }

    return retrieverQueue;
}

- (void) startDownloading
{
//  ?? [feedItems removeAllObjects];
    NSString *file = [[NSBundle  mainBundle] pathForResource:@"Feed"
                                                      ofType:@"plist"];
    NSDictionary *item = [[NSDictionary alloc]initWithContentsOfFile:file];
    NSArray *array = [item objectForKey:@"Root"];
    NSString *theURL = [[array objectAtIndex:selectedCategory.intValue] objectForKey:@"URL"];
    NSLog(@"url:%@",theURL);
    NSURL * url = [NSURL URLWithString:theURL];
    NSURLRequest * urlRequest = [NSURLRequest requestWithURL:url];

    NSURLConnection * download = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
    [download start];
}

#pragma mark -
#pragma mark Private Methods


- (NSString *)trimString:(NSString *)originalString
{
    NSString * trimmedString;
    trimmedString  = [originalString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    return trimmedString;
}

#pragma mark -
#pragma mark NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    //This method is called when the download begins.
    //You can get all the response headers

    /* create the NSMutableData instance that will hold the received data */

    long long contentLength = [response expectedContentLength];
    if (contentLength == NSURLResponseUnknownLength) {
        contentLength = 500000;
    }


    if (downloadedData!=nil)
    {
        downloadedData = nil;
    }
    downloadedData = [NSMutableData dataWithCapacity:(NSUInteger)contentLength];

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    //This method is called whenever there is downloaded data available
    //It will be called multiple times and each time you will get part of downloaded data
    [downloadedData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //This method is called once the download is complete


    //The next step is parse the downloaded xml feed
    [feedItems removeAllObjects];
    NSXMLParser * xmlParser = [[NSXMLParser alloc] initWithData:downloadedData];
    [self startParsingWithParser:xmlParser];

    updatedGUIDs = [[NSMutableArray alloc] init];

    for (int i = 0; i < feedItems.count; i++) {
        [updatedGUIDs insertObject: [[feedItems objectAtIndex:i]podcastGUID]  atIndex:i];
    }

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{

    [error localizedDescription];
    NSLog(@"%@", [error localizedDescription]);
    [self.delegate parserHasError:error];

}

#pragma mark -
#pragma mark NSXMLParserDelegate
- (void) startParsingWithParser: (NSXMLParser *)parser
{

    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:YES];
    [parser setShouldReportNamespacePrefixes:YES];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
    if(nil != qualifiedName)
    {
        elementName = qualifiedName;
    }
    parseElement = NO;
    if ([elementName isEqualToString:@"lastBuildDate"])
    {
        lbd = [[NSString alloc] init];
    }

    if ([elementName isEqualToString:@"item"])
    {
        currentItem = [[NIKFeedEntry alloc] init];
    } else if([elementName isEqualToString:@"title"] ||
              [elementName isEqualToString:@"guid"] ||
              [elementName isEqualToString:@"description"] ||
              [elementName isEqualToString:@"content:encoded"] ||
              [elementName isEqualToString:@"link"] ||
              [elementName isEqualToString:@"category"] ||
              [elementName isEqualToString:@"dc:creator"] ||
              [elementName isEqualToString:@"pubDate"] ||
              [elementName isEqualToString:@"enclosure"] ||
              [elementName isEqualToString:@"lastBuildDate"])
    {
        NSString *urlValue=[attributeDict valueForKey:@"url"];
        NSString *urlType=[attributeDict valueForKey:@"type"];
        parseElement = YES;
        if ([urlType  isEqualToString:@"audio/ogg"] && ([urlValue rangeOfString:@"jadi.net"].length != 0))
        {
            downloadURL = [urlValue stringByReplacingOccurrencesOfString:@"jadi.net" withString:@"192.168.2.1"];
            downloadURL = [downloadURL stringByReplacingOccurrencesOfString:@"ogg" withString:@"mp3"];
            [currentItem setPodcastDownloadURL:downloadURL];
        }
    }

}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if(nil != qName)
    {
        elementName = qName;
    }

    NSString * parsedElementContent = nil;

    if (parsedElementData != nil) {
        parsedElementContent = [[NSString alloc] initWithData:parsedElementData encoding:NSUTF8StringEncoding];
    } else if (parsedElementString != nil) {
        parsedElementContent = [[NSString alloc] initWithString:parsedElementString];
    }
    if ([elementName isEqualToString:@"lastBuildDate"]) {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss Z"];
        NSDate *lastSavedBuildDate = [formatter dateFromString:[self trimString:parsedElementContent]];
        [[NSUserDefaults standardUserDefaults] setObject:lastSavedBuildDate forKey:@"Date"];

    }
    if([elementName isEqualToString:@"title"])
    {
        [currentItem setPodcastTitle:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"guid"])
    {
        [currentItem setPodcastGUID:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"description"])
    {
        [currentItem setPodcastSummary:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"content:encoded"])
    {
        [currentItem setPodcastContent:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"link"])
    {
        [currentItem setPodcastLinkURL:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"category"])
    {
        [currentItem addPodcastCategory:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"dc:creator"])
    {
        [currentItem setPodcastAuthor:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"pubDate"])
    {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss Z"];
        [currentItem setPodcastDate:[formatter dateFromString:[self trimString:parsedElementContent]]];
    }
    else if([elementName isEqualToString:@"item"])
    {
        [feedItems addObject:currentItem];
        currentItem = nil;
    }

    if (parsedElementContent!=nil)
    {
        parsedElementContent = nil;
    }

    if (parsedElementString!=nil)
    {
        parsedElementString = nil;
    }

    if (parsedElementData!=nil)
    {
        parsedElementData = nil;
    }

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (!parseElement)
    {
        return;
    }
    if (parsedElementString==nil)
    {
        parsedElementString = [[NSMutableString alloc] init];
    }
    [parsedElementString appendString:string];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"parseErrorOccured: %@",[parseError localizedDescription]);

}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    if (downloadedData!=nil)
    {
        downloadedData = nil;
    }
    [self.delegate parserDidCompleteParsing];
}

@end
هل كانت مفيدة؟

المحلول 2

All methods of NSXMLParserDelegate return reference to caller parser:(NSXMLParser *)parser. You can use it for separate data. Keep reference of your parser instances in the properties and use the comparison with them.

نصائح أخرى

Instead of using this Process with much Confusing use GDataXMLNode Hear i attach its .h and .m after Download this follow Bellow steps:-

  • Download and extract zip and add this two class in to you project GDataXMLNode.h and GDataXMLNode.m

  • #import "GDataXMLNode.h" in to your class that you want to callinng your xmp URL.

  • Use this Bellow Method for parsiong data:-


-(void)ActionCountAlikes
{
NSString *urlParsingStr =@"http://youryoue.php"



    NSData *xmlData = [[NSMutableData alloc] initWithContentsOfURL:[NSURL URLWithString:urlParsingStr]];

    NSError *error;
    GDataXMLDocument *xmlDocument = [[GDataXMLDocument alloc] initWithData:xmlData
                                                                   options:0 error:&error];
    NSArray *getData = [[xmlDocument rootElement]elementsForName:@"Record"];

        for(GDataXMLElement *e in getData)
        {
             NSMutableDictionary *d = [[NSMutableDictionary alloc] init];
            [d setValue:[[[e elementsForName:@"Message"]objectAtIndex:0]stringValue] forKey:@"Message"];


        }


    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top