0

I am getting lastest tweet and show it in my app. I put it in a NSMutableString and initialize that string like below in my xmlparser.m file:

- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

I can get the tweet but somehow it cuts some of the tweets and shows some part of it. For example tweet is

Video games in the classroom? Social media & #technology can change education http://bit.ly/KfGViF @GOVERNING #edtech

but what it shows is:

#technology can change education http://bit.ly/KfGViF @GOVERNING #edtech

Why do you think it is? I tried to initialize currentNodeContent in other ways to but I could not solve the problem.

Do you have any idea why is this happening?

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
user1244069
  • 95
  • 2
  • 12
  • 1
    Is the string variable being passed into the method exactly what you expect it to be? – sosborn Apr 27 '12 at 02:24
  • I don't know what's causing the trimming problem, but that is not the way you get a mutable string. You need to call `mutableCopy` on the trimmed string instance. You can't just cast. – warrenm Apr 27 '12 at 02:24

2 Answers2

1

Event-driven (SAX) parsers are free to return only part of the text of a node in a callback. You might only be getting part of the tweet passed in. You should probably accumulate characters in a mutable string until you get a callback indicating the end of the element. See Listing 3 and the surrounding text in this guide.

warrenm
  • 31,094
  • 6
  • 92
  • 116
  • 1
    In particular, the above code snippet is probably being called repeatedly with segments of the tweet (probably three times with: the part before the entity for the ampersand ('&'), the ampersand entity itself, and the part after the ampersand). It's overwriting the `currentNodeContent` each time and thus only remembering the last part. – Ken Thomases Apr 27 '12 at 03:55
  • I tried to do something like currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; [currentStringValue appendString:string]; but this time I get SIGBRT error saying that 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendString:' – user1244069 Apr 27 '12 at 04:09
0

You've got two problems here:

- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

Simply casting an NSString to an NSMutableString doesn't work. You have to make a mutable copy yourself or initialise a new NSMutableString using the contents of an NSString.

Furthermore, the text parser is only giving you the last part of the string because it may be interpreting the '&' simply as part of an entity reference, or it may be an entity reference itself.

What you probably want to do is:

  1. Before you begin parsing, initialise currentNodeContent so that it is an empty NSMutableString:

    currentNodeContent = [NSMutableString string];
    
  2. As you are parsing, append the characters to the currentNodeContent:

    [currentNodeContent appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    
dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • This time I get [NSMutableArray insertObject:atIndex:]: attempt to insert nil object at 0' error – user1244069 Apr 27 '12 at 04:32
  • @user1244069: Try `currentNodeContent = [[NSMutableString alloc] init];` instead. But also post the code where you are trying to insert an object into an array. – dreamlax Apr 27 '12 at 04:37
  • This is where I initialized it:-(id) loadXMLByURL:(NSString *)urlString {currentNodeContent = [[NSMutableString alloc] init];} – user1244069 Apr 27 '12 at 04:46