Search code examples
iosobjective-capitwittertwitterkit

Retreive tweet information (text&image) from timeline in TWTRTimelineViewController - Objective c


Good afternoon,

I have an app that asks the user to log in thanks to twitter's doc found there: Log in with twitter. Then, I can successfully load the user's timeline. This timeline loads in a NavigationController which has the interface TWTRTimelineViewController. Now, I would like that when one user holds his finger on a tweet, or just click on one tweet, rather than opening Safari to display it, it pops up a button where I'll be able to work on the tweet after clicking. I will need to get access to the text and the image of the tweet. From my understanding, I will need to delegate all the tweets to some kind of TWTRTweetView controller to work on them but I'm not so sure how, since I'm completely new to this. I did try to read the doc but couldn't really get it, and most of the example are written in Swift. I'm also not sure how I'm supposed to access the tweet's properties. I have tried STTwitter where I played with some JSON formatted texts and where I was able to get the text and the image URL but I can't figure out how to do so directly with TwitterKit. Here's my actual code of the controller that display the timeline:

#import "TwitterTimelineViewController.h"
#import <TwitterKit/TwitterKit.h>
#import "AppDelegate.h"

@interface TwitterTimelineViewController ()
@property (strong, nonatomic) IBOutlet UITableView *TwitterTableView;
@end

@implementation TwitterTimelineViewController

TWTRUserTimelineDataSource *userTimelineDataSource;

- (void)viewDidLoad {
    [super viewDidLoad];
    
    AppDelegate *delegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
    
    [[Twitter sharedInstance] startWithConsumerKey:@"myConsumerKey" consumerSecret:@"myConsumerSecretKey"];
    
    TWTRAPIClient *APIClient = [[TWTRAPIClient alloc] init];
    userTimelineDataSource = [[TWTRUserTimelineDataSource alloc] initWithScreenName:delegate.twitterUsername APIClient:APIClient];
    self.dataSource = userTimelineDataSource;
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
    return [[Twitter sharedInstance] application:app openURL:url options:options];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Any help would be awesome!

Cheers, Theo.


Solution

  • Found the answer myself. For anyone struggling with the same issue, here the code I wrote. A bit messy but it works.

    -(IBAction)ShowTweets: (id) sender{
    
    UIButton *clicked = (UIButton *) sender;
    
    NSString *tweetToDecryptIndex = [NSString stringWithFormat: @"%ld", (long)clicked.tag];
    
    //gets all tweets from current timeline
    NSArray *allTweets = self.snapshotTweets;
    
    //look the tweets, get the URL and removes it to get the text only
    NSDataDetector *detect = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:nil];
    
        //gets the single tweet from clicked button
        TWTRTweet *tweet = [allTweets objectAtIndex:(long)clicked.tag];
        NSString *content = tweet.text; //gets the text
        NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
        NSArray *matches = [linkDetector matchesInString:content options:0 range:NSMakeRange(0, [content length])]; //find the URL
    
        NSURL *url; //contains the url from the text of the tweet
        NSString *ciph; //text from tweet without the url
    
        for (NSTextCheckingResult *match in matches) {
            if ([match resultType] == NSTextCheckingTypeLink) {
                url = [match URL];
                ciph = [content substringToIndex:content.length-url.absoluteString.length];
            }
        }
    
        //Now, ask a JSON answer from twitter of the specific tweet using its ID
        TWTRAPIClient *client = [[TWTRAPIClient alloc] init];
        NSString *statusesShowEndpoint = @"https://api.twitter.com/1.1/statuses/show.json";
        NSDictionary *params = @{@"id" : tweet.tweetID};
        NSError *clientError;
    
        NSURLRequest *request = [client URLRequestWithMethod:@"GET" URL:statusesShowEndpoint parameters:params error:&clientError];
    
        if (request) {
            [client sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
                if (data) {
                    NSError *jsonError;
                    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
    
                    //NSLog(@"%@", json);
                    //looking for the media_url
                    NSString *media = [json valueForKeyPath:@"entities.media"];
                    NSArray *urlArray = [media valueForKey:@"media_url_https"];
    
                    //finally getting the url as a string
                    NSMutableString * urlOfImageString = [[NSMutableString alloc] init];
                    for (NSObject * obj in urlArray)
                    {
                        [urlOfImageString appendString:[obj description]];
                    }
    
                    //NSLog(@"%@",urlOfImageString);
    
                    //constructing name for image to write in path
                    NSString *tweetID = tweet.tweetID;
                    NSString *imgName = [tweetID stringByAppendingString:@".jpg"];
                    NSString *tmp = [@"/your/path" stringByAppendingString:imgName];
    
                    //NSLog(@"%@", tmp);
    
                    //Now writting the image
                    NSURL *urlOfImageUrl = [NSURL URLWithString:urlOfImageString];
                    NSData *imageData = [NSData dataWithContentsOfURL:urlOfImageUrl];   
                }
                else {
                    NSLog(@"Error: %@", connectionError);
                }
            }];
        }
        else {
            NSLog(@"Error: %@", clientError);
        }