开发者

MGTwitterEngine and its Supported Arrays

开发者 https://www.devze.com 2023-03-09 14:25 出处:网络
This is my first time posting. I have been afraid to post anything since I am a noob with C++ but I do have to say I seem to be catching on fairly quick since I am an experienced html, css, javascript

This is my first time posting. I have been afraid to post anything since I am a noob with C++ but I do have to say I seem to be catching on fairly quick since I am an experienced html, css, javascript developer.

Ok so I am working on this project that implements twitter and Matts TwitterEngine and things are starting to come together. I have a tableview collecting the timeline of the user who signs in. You can make tweets and see the timeline but I am running into a few problems while trying to incorporate the "@"user" attribute.

I have come to conclusion that it is because it is a NSDictionary with several arrays within in it itself. For example @user consist of User, scree_name, ect so here is some code to maybe see if anybody can help me sort this out a little.

In the .h file of a NSObject I will call out a

-(NSString*)author;

In the .m file

 @implementation Tweet

 -(id)init开发者_如何学PythonWithTweetDictionary:(NSDictionary*)_contents {

if(self == [super init]) {
    
    contents = _contents;
    [contents retain];
}

return self;
}

-(NSString*)author {

return [[contents objectForKey:@"user"] objectForKey:@"screen_name"];
}

Now this is where I call it to a View and believe I have issues becuase I am still learning Arrays and Mutable Arrays and not sure what to call.

In my TwitterViewController.h I first obviously import SA_OAuth engine and controller which work fine then I use two MutableArrays like below

  MGTwitterEngine *_twitter;
  SA_OAuthTwitterEngine *_engine;
  NSMutableArray *tweets;
  NSMutableArray *authors;

in the twitterview.m I import the first .h and then call out

 //Connect to twitter API
- (void)viewDidAppear:(BOOL)animated {
    
    if(_engine) return;
    
    _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
    _engine.consumerKey = @"key here =P";
    _engine.consumerSecret = @"secret here =P";
    
    UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];
    
    if (controller) 
        [self presentModalViewController: controller animated: YES];
    else {
        tweets = [[NSMutableArray alloc] init];
        authors = [[NSMutableArray alloc] init];

Then I returns the count of that MutableArray and try to display it next to the tweets so it shows the persons screen_name of the actual tweet on the timeline

    - (UITableViewCell *)tableView:(UITableView *)tableView      cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    NSString *identifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    
    if (cell == nil) {

  //add subtitle
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle     reuseIdentifier:@"cell"];

    }
    
    [cell.textLabel setNumberOfLines:7];
    [cell.textLabel setText:[(Tweet*)[tweets objectAtIndex:indexPath.row] tweet]];
    //-------THIS IS WHERE I KEEP GETTING A SIGBRT DURING LOAD "dump saying return count 0-----------[cell.textLabel setText:[(Tweet*)[authors objectAtIndex:indexPath.row] author]];------

   //[cell.detailTextLabel setText:[(Tweet*)[retweetCount objectAtIndex:indexPath.row]      reTweetCount]];
    



#pragma mark SA_OAuthTwitterController Delegate

- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
    
    NSLog(@"Authenticated with user %@", username);
    
    tweets = [[NSMutableArray alloc] init];
    authors =[[NSMutableArray alloc] init];
    
    [self updateStream:nil];
}





- (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)connectionIdentifier {
    
    tweets = [[NSMutableArray alloc] init];
    
    for(NSDictionary *d in statuses) {
        
        NSLog(@"See dictionary: %@", d);
        
        Tweet *tweet = [[Tweet alloc] initWithTweetDictionary:d];
        [tweets addObject:tweet];
        [retweetCount addObject:tweet];
        [tweet release];
    }
    
    [self.tableView reloadData];
}


- (void)userInfoReceived:(NSArray *)userInfo forRequest:(NSString *)connectionIdentifier {
  
    
    authors = [[NSMutableArray alloc] init];
    
    for (NSDictionary *d in userInfo) {
     
    
    NSLog(@"See dictionary: %@", d);
       
        
        Tweet *tweet = [[Tweet alloc] initWithTweetDictionary:d];
        [authors addObject:tweet];
        [tweet release];
        
    }
    
    [self.tableView reloadData];

    
}

So like I said the "tweets" are working and I can add in other objects by addObject method such as retweet count but I can not for the life of me figure out why I cant get the User screen name to display in the cell!!!

I also eventually want to Async with the avatars and add a RT button so if anyone has any suggestions on an EASY way to implement those that would be great too!

I appreciate any help I can get !!! Thanks hope to hear from some one soon to help enlighten me about NSDictionary, NSArrays and MutableArrays cause I believe thats were the problem lays. Or maybe I am just not populating the table correctly whatever it is man I am stumpped and could use some help!

Thanks sincerely

Anthony

DUMP:

2011-05-29 03:27:21.477 ThemeCatcher[10409:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x01524be9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x016795c2 objc_exception_throw + 47
    2   CoreFoundation                      0x0151a6e5 -[__NSArrayM objectAtIndex:] + 261
    3   ThemeCatcher                        0x00024498 -[TwitterVeiwController tableView:cellForRowAtIndexPath:] + 600
    4   UIKit                               0x008037fa -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 634
    5   UIKit                               0x007f977f -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
    6   UIKit                               0x0080e450 -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
    7   UIKit                               0x00806538 -[UITableView layoutSubviews] + 242
    8   QuartzCore                          0x004a8451 -[CALayer layoutSublayers] + 181
    9   QuartzCore                          0x004a817c CALayerLayoutIfNeeded + 220
    10  QuartzCore                          0x004a137c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
    11  QuartzCore                          0x004a10d0 _ZN2CA11Transaction6commitEv + 292
    12  QuartzCore                          0x004d17d5 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
    13  CoreFoundation                      0x01505fbb __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
    14  CoreFoundation                      0x0149b0e7 __CFRunLoopDoObservers + 295
    15  CoreFoundation                      0x01463bd7 __CFRunLoopRun + 1575
    16  CoreFoundation                      0x01463240 CFRunLoopRunSpecific + 208
    17  CoreFoundation                      0x01463161 CFRunLoopRunInMode + 97
    18  GraphicsServices                    0x01f42268 GSEventRunModal + 217
    19  GraphicsServices                    0x01f4232d GSEventRun + 115
    20  UIKit                               0x0079e42e UIApplicationMain + 1160
    21  ThemeCatcher                        0x00002c29 main + 121
    22  ThemeCatcher                        0x00002ba5 start + 53
    23  ???                                 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Current language:  auto; currently objective-c
(gdb)     

UPDATED!!!!!! Want to post my solution incase others read this. I hate browsing post and users find their awnser but do not share their solution to help others in the future. So I wont be that guy and tell you all how I got this to work!

Solution:

First Correctly call out your Arrays like Danny talks about below do NOT follow the method I was it can cause issue for yourself later down the road. " I still used MutableArray on both call but will attempt to change in the near future.

Now make sure all Arrays are formatted properly and "connect your dots" =P But here is the Kicker! Below is a part of MGTwitterEngine that explains my issue. At first I was calling a integer of "1" which the engine thought I was trying to get one "screen_name" for a whole array of users so obviously it would though a SIGABRT and say WTH are you trying to do here! =P

Just want to clarify what I said earlier about Integers and defining the user. In

MGTwitterRequestTypes.h towards the bottom theres this line of code:typedef enum _     



MGTwitterResponseType {
MGTwitterStatuses           = 0,    // one or more statuses
MGTwitterStatus             = 1,    // exactly one status
MGTwitterUsers              = 2,    // one or more user's information
MGTwitterUser               = 3,    // info for exactly one user
MGTwitterDirectMessages     = 4,    // one or more direct messages
MGTwitterDirectMessage      = 5,    // exactly one direct message
MGTwitterGeneric            = 6,    // a generic response not requiring parsing
MGTwitterMiscellaneous      = 8,    // a miscellaneous response of key-value      pairs
MGTwitterImage              = 7,    // an image
 #if YAJL_AVAILABLE
MGTwitterSearchResults      = 9,    // search results
#endif
 }    MGTwitterResponseType;

// This key is added to each tweet or direct message returned, // with an NSNumber value containing an MGTwitterRequestType. // This is designed to help client applications aggregate updates.

define TWITTER_SOURCE_REQUEST_TYPE @"source_api_request_type"

I hope I i have help others to accomplish adding scree_name...and basically you can use this for any "text" information within there such as ReTweet Counts ect... ect... Now I need to figure out how to load thier profile images in the tableview .... I have it loading the images with this line of code but it wont load in the table view for some odd reason. It even pushes the text over correctly like their is an image there but there is not one

Any Suggestions on this would be greatly appreciated!!!

NSString *imageurl = [avatarsURL objectAtIndex:0]; 
 NSLog(@"http://api.twitter.com/1/users/profile_image/username.json");   
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL   URLWithString:imageurl]]; 
UIImage *tableImage = [[UIImage alloc] initWithData:imageData]; 

[cell.imageView setImage:tableImage]; 
CGSize imageSize = CGSizeMake(45,40);   
UIGraphicsBeginImageContext(imageSize); 
CGRect imageRect = CGRectMake(0.2, 0.1, imageSize.width, imageSize.height); 
[tableImage drawInRect:imageRect]; 
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext();    

....I get no errors at all just this in the dump " I have to remove the HyperLinks because spam issues and I am a new member....FYI"

2011-05-29 17:26:02.950 ThemeCatcher[2974:207]    

http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.980 ThemeCatcher[2974:207]   

http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.981 ThemeCatcher[2974:207]   
http:api.twitter.com/1/users/profile_image/username.json

2011-05-29 17:26:02.982 ThemeCatcher[2974:207]   
http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.983 ThemeCatcher[2974:207]   
http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.984 ThemeCatcher[2974:207]     
http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.985 ThemeCatcher[2974:207]      
http://api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.987 ThemeCatcher[2974:207]   
http://api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:06.550 ThemeCatcher[2974:207] Request Suceeded: BF0E18DB-A2CC-4823-AC02-   
6E182127BBF7

I can leave 2 =P


Okay, there are a few problems (I'll save the memory-management related stuff for last):

General Problems

First of all, how does your implementation of numberOfSectionsInTableView: and tableView:numberOfRowsInSection: look like?

Next, every time your viewDidAppear: is called and you are already logged in you basically forget about all the old tweets: tweets = [[NSMutableArray alloc] init];

But what's even more problematic, is that you do so every time you receive data, as well:

- (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)connectionIdentifier {

    tweets = [[NSMutableArray alloc] init]; // <= No!
    ...
}

And then there is this problem which I don't understand because I don't know the library: What's the difference between your authors and yout tweets? (Both are arrays of tweets — frankly, I don't see the point.)

If understood your crash correctly, it happens when you try to retrieve a tweet from the authors array and you assume that your authors array has at least the same number of objects in it, as the tweets array. I don't know MGTwitterEngine well, but from what I infer from its documentation, userInfoReceived:forRequest: will only be called after you sent an explicit request for a users profile.
So it doesn't come as a surprise, that your assumption is apparently wrong.

Furthermore, you should be able to get all the info you need to display a tweet in the timeline from the tweet itself anyway (well except the actual image-data of the avatar, that is).

Memory Management

You are leaking every tweet you will ever receive:

Although you take care of correctly releasing every individual tweet after adding it to the tweets or authors array (good), you forget about those arrays whenever new data comes in. You probably shouldn't replace the entirety of said arrays in the first place and — instead — simply add the new stuff to them, but since you decided to go that route, make sure to release the old array before you assign the new one.

Personally, I'd suggest a different approach and create the tweets array only once in initWithStyle:, (and don't bother creating an authors array at all) only adding to and removing from it as needed — properly disposing of it in dealloc and calling removeAllObjects on it, when a user logs out (if you don't dispose of the view controller entirely, in this case).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号