Getting a json file from a website into UITableview with Objective C - ios

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];

Related

Obj-C UITable not populating with MutableArray

I have an array that loads when the app starts and it gets the correct data and fills the array but once I go to the tableviewcontroller it says the array is null.
This is where I get the data
AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
NSMutableArray *tableDicsArrayTickets;
NSMutableArray *dictionaryStack;
NSMutableString *textInProgress;
NSError *errorPointer;
}
#property (strong, nonatomic) NSMutableArray *tableDicsArrayTickets;
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) NSString *photo_URL;
+(NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)errorPointer;
+(NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)errorPointer;
+(AppDelegate *) getInstance;
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.tableDicsArrayTickets = [[NSMutableArray alloc] init];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
NSURL *url = [NSURL URLWithString:#"http://MYURLexample.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *deviceCode = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSString *post = [[NSString alloc] initWithFormat:#"parameter=%#", deviceCode];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[post dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Response:%# %#\n", response, error);
if(error == nil)
{
NSString *text =[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"Data = %#",text);
NSDictionary *dics = [[NSDictionary alloc]initWithDictionary:[AppDelegate dictionaryForXMLString:text error:nil]];
NSLog(#"dics is %#", dics);
[self.tableDicsArrayTickets addObject:[[dics valueForKey:#"response"] valueForKey:#"text"]];
NSLog(#"Array2 is %#", self.tableDicsArrayTickets);
}
}];
[dataTask resume];
ViewController.h
#interface HistoryViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
{
AppDelegate *mainDelegate;
}
#property (strong, nonatomic) AppDelegate *mainDelegate;
ViewController.m
#pragma
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [mainDelegate.tableDicsArrayTickets count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *array = mainDelegate.tableDicsArrayTickets;
NSString *cellIdentifier = #"Cell";
PhotoTableViewCell *cell = (PhotoTableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
cell = [[PhotoTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
NSLog(#"Array is %#", [[array objectAtIndex:indexPath.row] objectForKey:#"text"]);
cell.ticketNumber.text = [[array objectAtIndex:indexPath.row] objectForKey:#"text"];
return cell;
}
Im not having a problem getting the data for the array its just once I finally go to the view controller with the table on it the array becomes null.
I think you're doing a number of things wrong...
First:
// AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
// this should NOT be here
NSMutableArray *tableDicsArrayTickets;
NSMutableArray *dictionaryStack;
NSMutableString *textInProgress;
NSError *errorPointer;
}
#property (strong, nonatomic) NSMutableArray *tableDicsArrayTickets;
// ...
That should give you a compile warning:
autosynthesized property 'tableDicsArrayTickets' will use synthesized instance
variable '_tableDicsArrayTickets', not existing instance variable 'tableDicsArrayTickets'
Same with:
//HistoryViewController.h
#interface HistoryViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
{
// this should NOT be here
AppDelegate *mainDelegate;
}
#property (strong, nonatomic) AppDelegate *mainDelegate;
Which should give you:
autosynthesized property 'mainDelegate' will use synthesized instance
variable '_mainDelegate', not existing instance variable 'mainDelegate'
Then, you're not showing where you have this in HistoryViewController.m (should probably be in viewDidLoad()):
_mainDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

Passing JSON data on uiviewTable ios (objective c)

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.]

Objective-c TableView Refresh With dispatch_sync error

Hello I have working simple tableview json parsing codes. But i want to do reload tableview in background everytime i added dispatch_sync codes but don't working my codes under.
NSArray * jsonArray;
NSMutableArray * array1;
- (void)viewDidLoad {
[super viewDidLoad];
NSURL * url = [NSURL URLWithString:#"http://bla.com/test2.json"];
NSURLRequest * urlReq = [NSURLRequest requestWithURL:url];
NSError * error;
NSData * data = [NSURLConnection sendSynchronousRequest:urlReq returningResponse:nil error:&error];
NSDictionary * jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSLog(#"%#",jsonDict);
jsonArray = [jsonDict objectForKey:#"worldpopulation"];
NSLog(#"%#",jsonArray);
array1 =[[NSMutableArray alloc]init];
}
- (void)main
{
dispatch_sync(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return jsonArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellid=#"CustomCell";
CustomTableViewCell *cell=(CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellid];;
if(cell==nil)
{
cell=[[CustomTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellid];
}
for ( NSDictionary * dict in jsonArray) {
NSString * country = [dict objectForKey:#"country"];
[array1 addObject:country];
}
cell.nameLabel.text= [array1 objectAtIndex:indexPath.row];
return cell;
}
Main.m
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
I added only needed codes . I need to fix it .
Thanks for your help !
First, performing synchronous network operations on the main thread is a bad idea - it will make your app UI 'freeze' until the operation completes, which in the case of a slow (or no) network could be a long time.
Secondly, you should move the loading code into its own function that you call from viewDidLoad - this way you can easily call it again if you want to reload the data.
Thirdly, your cellForRowAtIndexPath is iterating your entire jsonArray for each cell to no purpose.
Finally, NSURLConnection is deprecated in iOS 9 so you should migrate to NSURLSession if you are targeting iOS7 and later (if you want to run on iOS prior to iOS 7 then you will need to keep using NSURLConnection)
I would suggest the following:
#interface MyViewController () <UITableViewDelegate,UITableViewDataSource>
#property (strong,nonatomic) NSArray *jsonArray;
#end
#implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.jsonArray=[NSArray new];
[self loadJSON];
}
-(void)loadJSON {
NSURL * url = [NSURL URLWithString:#"http://bla.com/test2.json"];
NSURLSession *session=[NSURLSession sharedSession];
[session dataTaskWithRequest:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error!=nil) {
NSLog(#"Something went wrong:%#",error);
} else {
NSError *jsonError;
NSDictionary * jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonEerror];
if (jsonError != nil) {
NSLog(#"JSON isn't right:%#",jsonError);
} else {
self.jsonArray = jsonDict[#"worldpopulation"];
dispatch_async(dispatch_get_main_queue(),^{
[self.tableview reloadData];
});
}
}];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.jsonArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellid=#"CustomCell";
CustomTableViewCell *cell=(CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellid forIndexPath:indexPath];;
NSDictionary *entryDict=self.jsonArray[indexPath.row];
NSString *countryName=entryDict[#"country"];
cell.nameLabel.text= countryName;
return cell;
}

Making Profile Photos show up using Twitter API 1.1

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.

iOS [__NSCFString > objectForKeyedSubscript:]:

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!

Resources