I have what is most likely a fairly newb question, but have searched and can't seem to find/learn the answer.
I'm tinkering with the iOS Twitter framework, and attempting to create a very simple app that will return the most recent tweet from a specific user account. I'm currently triggering this off a button tap.
The problem I have is the UILabel I'm displaying the text takes forever to load! I don't think it's twitter as I've logged the request and it's pretty fast. I can't seem to figure out what I'm doing wrong here. Could this have anything to do with the autorelease? Below is the relevant code. Any help would be much appreciated!!
Code:
- (IBAction)displayTweet:(id)sender {
[activityIndicator startAnimating];
[currentTweet setHidden:YES];
[activityIndicator setHidden:NO];
[processingLabel setHidden:NO];
// First, we create a dictionary to hold our request parameters
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
[params setObject:@"donslamm" forKey:@"screen_name"];
[params setObject:@"1" forKey:@"count"];
[params setObject:@"1" forKey:@"include_entities"];
//[params setObject:@"1" forKey:@"include_rts"];
// Next, we create an URL that points to the target endpoint
NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/user_timeline.json"];
// Now, we can create our request. Note that we are performing a GET request
TWRequest *request = [[TWRequest alloc] initWithURL:url parameters:params requestMethod:TWRequestMethodGET];
// Finally, we perform our request
[request performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (responseData != nil) {
// Here we leverage the NSJSONSerialization class to parse the returned JSON
NSError *jsonError;
NSArray *timeline = [NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONReadingMutableLeaves
error:&jsonError];
if (jsonError == nil) {
// We now have an object that we can parse
NSDictionary *dict = [timeline objectAtIndex:0];
NSString *string = [[NSString alloc] initWithString:[dict objectForKey:@"text"]];
self.currentTweet.text = [[NSString alloc] initWithString:string];
} else {
// Inspect the contents of jsonError
NSLog(@"%@", jsonError);
}
}
[activityIndicator stopAnimating];
[activityIndicator setHidden:YES];
[processingLabel setHidden:YES];
[currentTweet setHidden:NO];
}];
}
Roughly 30-45 seconds on average. I did a little more digging in the Apple iOS forums and it appears the Twitter framework has some serious memory leaks. I'm kind of at a loss on how to make this thing run faster though.
Thanks for the tip, and so fast! Unfortunately it didn't solve the time it takes to load the UILabel or map.... Below is what I implemented based on your suggestion (ignore the map stuff, again just tinkering around). Interestingly enough, I put the same code in viewDidLoad and it comes up lightning fast. It seems localized to the IBAction somehow. Any thoughts, suggestions?
Code:
-(void)setTweet:(NSString *)theTweet {
self.currentTweet.text = theTweet;
}
-(IBAction)displayTweet:(id)sender {
[activityIndicator startAnimating];
[currentTweet setHidden:YES];
[mapView setHidden:YES];
[activityIndicator setHidden:NO];
[processingLabel setHidden:NO];
// First, we create a dictionary to hold our request parameters
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
[params setObject:@"donslamm" forKey:@"screen_name"];
[params setObject:@"1" forKey:@"count"];
[params setObject:@"1" forKey:@"include_entities"];
//[params setObject:@"1" forKey:@"include_rts"];
// Next, we create an URL that points to the target endpoint
NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/user_timeline.json"];
// Now, we can create our request. Note that we are performing a GET request
TWRequest *request = [[TWRequest alloc] initWithURL:url parameters:params requestMethod:TWRequestMethodGET];
// Finally, we perform our request
[request performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (responseData != nil) {
// Here we leverage the NSJSONSerialization class to parse the returned JSON
NSError *jsonError;
NSArray *timeline = [NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONReadingMutableLeaves
error:&jsonError];
if (jsonError == nil) {
// We now have an object that we can parse
NSDictionary *dict = [timeline objectAtIndex:0];
NSString *string = [[NSString alloc] initWithString:[dict objectForKey:@"text"]];
[self performSelectorOnMainThread:@selector(setTweet:) withObject:string waitUntilDone:NO];
NSArray *hashArray = [[NSArray alloc] initWithObjects:[dict objectForKey:@"entities"], nil];
NSDictionary *hashDict = [hashArray objectAtIndex:0];
NSArray *hashArray2 = [[NSArray alloc] initWithObjects:[hashDict objectForKey:@"hashtags"], nil];
NSArray *hashArray3 = [[NSArray alloc] initWithArray:[hashArray2 objectAtIndex:0]];
NSDictionary *hashDict2 = [hashArray3 objectAtIndex:0];
if ([[hashDict2 objectForKey:@"text"] isEqualToString:@"ATX"]) {
NSArray *keys = [NSArray arrayWithObjects: @"lat", @"lng", nil];
NSArray *objects = [NSArray arrayWithObjects:@"30.2669444", @"-97.7427778", nil];
NSDictionary *location = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
CLLocationCoordinate2D coord = {.latitude = [[location objectForKey:@"lat"] doubleValue], .longitude = [[location objectForKey:@"lng"] doubleValue]};
MKCoordinateSpan span = {.latitudeDelta = 0.2, .longitudeDelta = 0.2};
MKCoordinateRegion region = {coord, span};
[mapView setRegion:region];
CLLocationCoordinate2D annotationCoord;
annotationCoord.latitude = [[location objectForKey:@"lat"] doubleValue];
annotationCoord.longitude = [[location objectForKey:@"lng"] doubleValue];
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
annotationPoint.title = @"Austin";
annotationPoint.subtitle = @"Austin Texas";
[mapView addAnnotation:annotationPoint];
}
} else {
// Inspect the contents of jsonError
NSLog(@"%@", jsonError);
}
}
[activityIndicator stopAnimating];
[activityIndicator setHidden:YES];
[processingLabel setHidden:YES];
[currentTweet setHidden:NO];
[mapView setHidden:NO];
}];
}
Last edited by stephenmetts; 02-03-2012 at 05:16 PM.
Reason: clarification, it's not that MarcC's code didn't work, it's that it didn't solve the original problem.