I am trying to implement a tableview with a twitter feed into my iOS app. I have followed tutorials and am able to get the users twitter feed. I found the url for a hash tag but when implemented get an error:
'NSInvalidArgumentException', reason: '-[__NSCFString
objectForKeyedSubscript:]: unrecognized selector sent to instance
0xa0b7e20'
I have tried to do some research but all attempts failed. Any advice would be great. Thank you.
.h
#import <UIKit/UIKit.h>
#import <Social/Social.h>
#import <Accounts/Accounts.h>
#interface ViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tweetTableView;
#property (nonatomic, copy) NSArray *dataSource;
-(IBAction)refresh:(id)sender;
#end
.m
#implementation ViewController
- (void)getTimeLine {
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType
options:nil completion:^(BOOL granted, NSError *error)
{
if (granted == YES)
{
NSArray *arrayOfAccounts = [account
accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0)
{
ACAccount *twitterAccount = [arrayOfAccounts lastObject];
/* NSString * kTwitterHashtag = #"#nasa";
NSString * kTwitterUsername = #"";
// Looking for #kTwitterHashtag or #kTwitterUsername
NSString *urlString = [[[#"http://search.twitter.com/search.json?q=%23" stringByAppendingString:(NSString *)kTwitterHashtag]
stringByAppendingString:#"+OR+%40"] stringByAppendingString:(NSString *)kTwitterUsername];
NSURL *requestURL = [NSURL URLWithString:urlString];
*/
NSURL *requestURL = [NSURL URLWithString:#"http://api.twitter.com/1/statuses/home_timeline.json"];
NSMutableDictionary *parameters =
[[NSMutableDictionary alloc] init];
[parameters setObject:#"20" forKey:#"count"];
[parameters setObject:#"1" forKey:#"include_entities"];
SLRequest *postRequest = [SLRequest
requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodGET
URL:requestURL parameters:parameters];
postRequest.account = twitterAccount;
[postRequest performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse
*urlResponse, NSError *error)
{
self.dataSource = [NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingMutableLeaves
error:&error];
if (self.dataSource.count != 0) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.tweetTableView reloadData];
NSLog(#"_dataSource.count %d",_dataSource.count);
for(NSDictionary * tweet in _dataSource){
NSLog(#"tweet : %#",tweet[#"text"]);
}
});
}
}];
}
} else {
// Handle failure to get account access
}
}];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_tweetTableView = [[UITableView alloc] init];
_dataSource = [[NSArray alloc] init];
[self getTimeLine];
}
-(IBAction)refresh:(id)sender{
[self getTimeLine];
[self.tweetTableView reloadData];
}
#pragma mark -
#pragma mark UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _dataSource.count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tweetTableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *tweet = _dataSource[[indexPath row]];
NSLog(#"tweet : %#",tweet);
cell.textLabel.text = tweet[#"text"];
return cell;
}
#end
self.dataSource = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
This is returning a string... but you are assigning it to an NSArray!
Related
I'm attempting to get a json file from a website into UITableview with Objective C.
As I'm not an advanced coder please excuse my crude coding tecniques.
I have a .json file uploaded to my webspace. The File is formatted as so:
"JSONDATA":[
{
"name": "ABC",
"details": "DEF"
},
{
"name": "UVW",
"details": "XYZ"
}
]
my .h looks like:
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
IBOutlet UITableView *myTableView;
}
#property (strong, nonatomic) IBOutlet UITableView *myTableView;
#end
the .m code
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arrName;
NSMutableArray *arrDetails;
NSString *responseString;
}
#end
#implementation ViewController
#synthesize myTableView;
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"ViewDidLoad");
[self fetchData];
[myTableView reloadData];
}
-(void)fetchData
{
NSLog(#"GetJsonResponse Fired");
NSURL *URL = [NSURL URLWithString:#"http://myWebsite.com/json/myJsonFile.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSLog(#"URLRequest = %#",request);
/////////////////////////////////////////////////////////////////// Nothing Below Here Fires/////////////////////////////////////////////////
// [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:ourBlock];
[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data,NSURLResponse *response,NSError *error)
{
// Block Body
NSLog(#"response = %#",response);
NSLog(#"block Body");
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"GetJsonDict%#",jsonDict);
NSArray *arr = jsonDict[#"JSONFILE"];
NSLog(#"jasoDict = %#",arr);
self->arrName = [[NSMutableArray alloc]init];
self->arrDetails = [[NSMutableArray alloc]init];
//arrValue = [[NSMutableArray alloc]init];
for(int i=0;i<[arr count];i++)
{
NSString *strName = [arr[i]objectForKey:#"NAME"];
NSString *strCode = [arr[i]objectForKey:#"CODE"];
// NSString *strValue = [arr[i]objectForKey:#"VALUE"];
NSLog(#"The strName is - %#",strName);
NSLog(#"The strCode is - %#", strCode);
// NSLog(#"The strValue is - %#", strValue);
[self->arrName addObject:strName];
[self->arrDetails addObject:strCode];
// [arrValue addObject:strValue];
NSLog(#"The arrName is - %#",self->arrName);
NSLog(#"The arrDetails is - %#", self->arrDetails);
// NSLog(#"The arrValue is - %#", arrValue);
}
}];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrName.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strCell = #"Cell";
// UITableViewCell *cell = [UITableView dequeueReusableCellWithIdentifier:strCell];
UITableViewCell *cell = [myTableView dequeueReusableCellWithIdentifier:strCell forIndexPath:indexPath];
if(cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strCell];
}
cell.textLabel.text = arrName[indexPath.row];
cell.detailTextLabel.text = arrDetails[indexPath.row];
return cell;
}
#end
I can't seem to put all the pieces together and get any data through to parse.
The NSLog is telling me:
2020-03-09 14:13:42.605558-0500 jsonFromWeb[27389:1317924] ViewDidLoad
2020-03-09 14:13:42.605802-0500 jsonFromWeb[27389:1317924] GetJsonResponse Fired
2020-03-09 14:13:42.606118-0500 jsonFromWeb[27389:1317924] URLRequest = <NSURLRequest: 0x6000001f8cc0> { URL: http://mywebsite.com/json/myJsonFile.json }
Where is this thing derailing? I can't get any data out of the URLResponse.
Thanks so much.
You have to resume the data task and you have to reload the table view inside the completion block on the main thread
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data,NSURLResponse *response,NSError *error) {
...
}
dispatch_async(dispatch_get_main_queue(), ^{
[myTableView reloadData];
});
}] resume];
There are similar questions but i could not find any solution which fits for me.
I have got all the data from the link as JSON but i am unable to understand that how can i show that data on uitableview. It is to be shown on homepage. it has title, info. for now i only need title and info to be shown on homepage.
NSURL *url = [NSURL URLWithString:#"http://mantis.vu.edu.pk/fundme/public/api/v1/ideas"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *jsonOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:urlRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
NSDictionary *responseDict = (NSDictionary *)JSON;
ideasArrayList = [[NSMutableArray alloc] init];
for (NSDictionary *innerObject in [responseDict objectForKey:#"data"])
{
[ideasArrayList addObject:innerObject];
if (ideasArrayList.count > 0) {
NSDictionary *userObject = [ideasArrayList objectAtIndex:0];
NSLog(#"Object and first index of array is %#",userObject);
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Oops something went wrong."
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
[jsonOperation start];
i am using AFNetworking library.
if you call your code in ViewController, at first you need add a dispatch_async block for move your data to main thread and reload tableview
-(void)getDataFromApi {
NSURL *url = [NSURL URLWithString:#"http://mantis.vu.edu.pk/fundme/public/api/v1/ideas"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *jsonOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:urlRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
NSDictionary *responseDict = (NSDictionary *)JSON;
ideasArrayList = [[NSMutableArray alloc] init];
for (NSDictionary *innerObject in [responseDict objectForKey:#"data"])
{
[ideasArrayList addObject:innerObject];
if (ideasArrayList.count > 0) {
NSDictionary *userObject = [ideasArrayList objectAtIndex:0];
NSLog(#"Object and first index of array is %#",userObject);
dispatch_async(dispatch_get_main_queue(), ^{
self.ideasArrayList = ideasArrayList;
[self.tableView reloadData];
});
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Oops something went wrong."
message:[error localizedDescription] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alertView show];
});
}];
[jsonOperation start];
}
In viewDidLoad method
- (void)viewDidLoad{
self.tableView.dataSource = self;
}
And implement UITableViewDatasource protocol methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.ideasArrayList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//configure the cell here or create custom subclass
}
NSDictionary *innerObject = self.ideasArrayList[indexPath.row];
cell.textLabel.text = innerObject[#"title"];
return cell;
}
You need to store the values you need to display in tableview in an array. So retrieve those values from your output JSON and store them in an array. Then in the data source methods of table view follow the usual.For e.g.- In the numberOfRowsInSection return yourArray.count. I hope you get the point.
I hope you get the point. Store values in array and then make the table fetch from that array.
I think it's help for you.
First you want to add the .m file.
#import "ViewController.h"
#import "tblcellTableViewCell.h"
#interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray *arrJSONDATA;
}
#property (weak, nonatomic) IBOutlet UITableView *tbl;
#end
and add the below code the viewDidLoad.
arrJSONDATA = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://mantis.vu.edu.pk/fundme/public/api/v1/ideas"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&err];
NSDictionary *dicData = [dic valueForKey:#"data"];
for (NSDictionary *dic1 in dicData) {
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:[dic1 objectForKey:#"idea_title"]];
[arr addObject:[dic1 objectForKey:#"idea_info"]];
[arrJSONDATA addObject:arr];
}
NSLog(#"%#",[arrJSONDATA description]);
[_tbl reloadData];
Label Outlet Create for title and info.
#import <UIKit/UIKit.h>
#interface tblcellTableViewCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *lblTitle;
#property (weak, nonatomic) IBOutlet UILabel *lblInfo;
#end
Then Create the tableView Delegate Method.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrJSONDATA count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
tblcellTableViewCell *cells = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
NSMutableArray *arr = [[NSMutableArray alloc] init];
arr = [arrJSONDATA objectAtIndex:indexPath.section];
cells.lblTitle.text = [arr objectAtIndex:0];
cells.lblInfo.text = [arr objectAtIndex:1];
return cells;
}
[Check the Screenshot.]
As you can see I have two methods tuula and wendyslookbook. Then I call them both in my mostPopular method. I have requested the photos from the Instagram API but now I want to put these two user photos together. How can I do that?
//
// PhotosViewController.m
// Photo Bombers
//
// Created by Alex Macleod on 20/8/14.
// Copyright (c) 2014 Alex Macleod. All rights reserved.
//
#import "PhotosViewController.h"
#import "PhotoCell.h"
#import "DetailViewController.h"
#import "PresentDetailTransition.h"
#import "DismissDetailTransition.h"
#import <SimpleAuth/SimpleAuth.h>
#interface PhotosViewController () <UIViewControllerTransitioningDelegate>
#property (nonatomic) NSString *accessToken;
#property (nonatomic) NSArray *photos;
#end
#implementation PhotosViewController
- (instancetype) init {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
layout.itemSize = CGSizeMake(106.0, 106.0);
layout.minimumInteritemSpacing = 1.0;
layout.minimumLineSpacing = 1.0;
return (self = [super initWithCollectionViewLayout:layout]);
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Fashun";
[self.collectionView registerClass:[PhotoCell class] forCellWithReuseIdentifier:#"photo"];
self.collectionView.backgroundColor = [UIColor whiteColor];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
self.accessToken = [userDefaults objectForKey:#"accessToken"];
if (self.accessToken == nil) {
[SimpleAuth authorize:#"instagram" options:#{#"scope": #[#"likes"]} completion:^(NSDictionary *responseObject, NSError *error) {
self.accessToken = responseObject[#"credentials"][#"token"];
[userDefaults setObject:self.accessToken forKey:#"accessToken"];
[userDefaults synchronize];
[self mostPopular];
}];
} else {
[self mostPopular];
}
}
- (void)tuula {
NSURLSession *session = [NSURLSession sharedSession];
NSString *urlString = [[NSString alloc]initWithFormat:#"https://api.instagram.com/v1/users/7522782/media/recent/?access_token=%#", self.accessToken];
NSURL *url = [[NSURL alloc] initWithString:urlString];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
NSLog(#"links: %#", location);
NSData *data = [[NSData alloc]initWithContentsOfURL:location];
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
self.photos = [responseDictionary valueForKeyPath:#"data"];
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
});
}];
[task resume];
}
- (void)wendyslookbook {
NSURLSession *session = [NSURLSession sharedSession];
NSString *urlString = [[NSString alloc]initWithFormat:#"https://api.instagram.com/v1/users/14454619/media/recent/?access_token=%#", self.accessToken];
NSURL *url = [[NSURL alloc] initWithString:urlString];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
NSLog(#"links: %#", location);
NSData *data = [[NSData alloc]initWithContentsOfURL:location];
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
self.photos = [responseDictionary valueForKeyPath:#"data"];
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
});
}];
[task resume];
}
- (void)mostPopular {
[self tuula];
[self wendyslookbook];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self.photos count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
PhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"photo" forIndexPath:indexPath];
cell.backgroundColor = [UIColor lightGrayColor];
cell.photo = self.photos[indexPath.row];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *photo = self.photos[indexPath.row];
DetailViewController *viewController = [[DetailViewController alloc]init];
viewController.modalPresentationStyle = UIModalPresentationCustom;
viewController.transitioningDelegate = self;
viewController.photo = photo;
[self presentViewController:viewController animated:YES completion:nil];
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented
presentingController:(UIViewController *)presenting
sourceController:(UIViewController *)source {
return [[PresentDetailTransition alloc]init];
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
return [[DismissDetailTransition alloc]init];
}
#end
I'm currently doing a practice for twitter API. Currently, i had a problem to populate a search hashtag results to tableview cellForRowAtIndexPath method. Below is my code.
My Header Code :
#interface TableViewController : UITableViewController<UITableViewDataSource,UITableViewDelegate> #property (nonatomic,strong) NSArray *array; #end
My Implementation Code :
#import "TableViewController.h"
#import <Social/Social.h>
#import <Accounts/Accounts.h>
#interface TableViewController ()
#end
#implementation TableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self getDataFromTwitter];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.array.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSDictionary *dataDictionary = [self.array objectAtIndex:indexPath.row];
// NSLog(#"data result: %#", self.array);
cell.textLabel.text = dataDictionary[#"text"];
return cell;
}
- (void)getDataFromTwitter {
// 1. set an URL
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/search/tweets.json"];
// 2. set NSMutableArray For Parameter
NSMutableDictionary *parameter = [[NSMutableDictionary alloc] init];
[parameter setObject:#"%23MH370" forKey:#"q"];
[parameter setObject:#"10" forKey:#"text"];
[parameter setObject:#"popular" forKey:#"result_type"];
//3. set ACAccountStore & ACAccountType
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if (granted == YES) {
NSArray *accountArray = [accountStore accountsWithAccountType:accountType];
if ([accountArray count] > 0) {
ACAccount *twitterAccount = [accountArray lastObject];
// guna slrequest to get data from twitter
SLRequest *getRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:parameter];
// set twitter account
[getRequest setAccount:twitterAccount];
[getRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *output = [NSString stringWithFormat:#"HTTP response status : %i", [urlResponse statusCode]];
NSLog(#"Output : %#", output);
self.array = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
if (self.array.count != 0) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
NSLog(#"search result: %#", self.array);
});
}
}];
}
}
}];
}
#end
I got a problem now when i always got a crash when i'm running the app and here is result from my console.
2014-03-12 19:57:11.990 twitterSearch[3069:a0b] -[__NSCFDictionary objectAtIndexedSubscript:]: unrecognized selector sent to instance 0xa45fd00
2014-03-12 19:57:11.992 twitterSearch[3069:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndexedSubscript:]: unrecognized selector sent to instance 0xa45fd00'
This error means that you are dealing with a NSArray as NSDictionary, most likely you are getting dictionary here not array:
self.array = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
We're working on an iOS 7 Twitter client. I haven't worked with the the Twitter API much and what I did was before 1.1.
Could somebody please help us get the profile photos loading on our application's Timeline?
Our code is below.
Here is our .h file:
#import <UIKit/UIKit.h>
#import <Accounts/Accounts.h>
#import <Social/Social.h>
#import <Twitter/Twitter.h>
#interface FirstViewController : UIViewController <UITableViewDataSource , UITableViewDelegate> {
UIRefreshControl *myRefreshControl;
}
#property (nonatomic) IBOutlet UITableView *timelineTableView;
#property (nonatomic) NSArray *timelineArray;
#end
and here is our .m for the application's timeline.
#interface FirstViewController ()
#end
#implementation FirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self getTimeline];
myRefreshControl = [[UIRefreshControl alloc]init];
myRefreshControl.tintColor = [UIColor blackColor];
[myRefreshControl setAttributedTitle:[[NSAttributedString alloc]initWithString:#"Pull to Refresh"]];
[myRefreshControl addTarget:self action:#selector(refreshTimeline) forControlEvents: UIControlEventValueChanged];
[self.timelineTableView addSubview:myRefreshControl];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)getTimeline
{
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType
options:nil completion:^(BOOL granted, NSError *error)
{
if (granted == YES)
{
NSArray *arrayOfAccounts = [account
accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0)
{
ACAccount *twitterAccount = [arrayOfAccounts lastObject];
NSURL *requestURL = [NSURL URLWithString:#"http://api.twitter.com/1/statuses/home_timeline.json"];
NSMutableDictionary *parameters =
[[NSMutableDictionary alloc] init];
[parameters setObject:#"200" forKey:#"count"];
[parameters setObject:#"1" forKey:#"include_entities"];
SLRequest *postRequest = [SLRequest
requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodGET
URL:requestURL parameters:parameters];
postRequest.account = twitterAccount;
[postRequest performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse
*urlResponse, NSError *error)
{
self.timelineArray = [NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingMutableLeaves
error:&error];
if (self.timelineArray.count != 0) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.timelineTableView reloadData];
});
}
}];
}
} else {
}
}];
}
-(void)refreshTimeline
{
[self getTimeline];
[self.timelineTableView reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.timelineArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSDictionary *tweet = self.timelineArray[[indexPath row]];
cell.textLabel.text = [[tweet objectForKey:#"user"]objectForKey:#"name"];
cell.detailTextLabel.text = [tweet objectForKey:#"text"];
cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL: [[tweet objectForKey:#"user"]objectForKey:#"profile_image_url"]]];
return cell;
}
#end
The response of :
http://api.twitter.com/1/statuses/home_timeline.json
will return home feeds. It contains a user key in it , you have to access that and get the profile image by profile_image_url.
Handling response in array of dictionaries will solve your problem and each dictionary will have the user key which contains profile_image_url.
Your call to the api is referencing version 1. I would suggest reviewing the info at https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline and examining the response format.
You can drill down the response to arrive at the 'user' object and get the profile image from there.