Load youtube channel to uitableview - iphone

i had search in the whole internet for my question: "How to load youtube channel into an uitableview"
I can't find a good example or tutorial.
Please someone can help me?
Thank you very much!

It looks like youtube already provides an API where you can retrieve your information have a look at this link:
http://apiblog.youtube.com/2009/02/youtube-apis-iphone-cool-mobile-apps.html
Otherwise you should search for youtube projects on github. I already found 2 projects. The first one provides already a preview page and plays the video after you selected one:
YoutubeBrowserDemo
HCYoutubeParser
Of course you would neet to look how to get the specific channels you are looking for but I think this should help you for the beginning.

add your youtube channel ID
class.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *urlForPlaylist=#"http://gdata.youtube.com/feeds/api/playlists/URchannelID";
GDataServiceGoogleYouTube *service = [self youTubeService];
[service fetchFeedWithURL:urlForPlaylist
delegate:self
didFinishSelector:#selector(request:finishedWithFeed:error:)];
}
//youtube
- (GDataServiceGoogleYouTube *)youTubeService {
static GDataServiceGoogleYouTube* _service = nil;
if (!_service) {
_service = [[GDataServiceGoogleYouTube alloc] init];
[_service setUserAgent:#"AppWhirl-UserApp-1.0"];
[_service setServiceShouldFollowNextLinks:NO];
}
// fetch unauthenticated
[_service setUserCredentialsWithUsername:nil
password:nil];
return _service;
}
- (void)request:(GDataServiceTicket *)ticket
finishedWithFeed:(GDataFeedBase *)aFeed
error:(NSError *)error {
self.feed = (GDataFeedYouTubeVideo *)aFeed;
NSLog(#"feed..////%#",_feed);
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return[[self.feed entries] count];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"CellR";
UITableViewCell *cell = nil;
cell = [self.VideoTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
GDataEntryBase *entry = [[self.feed entries] objectAtIndex:indexPath.row];
NSString *title = [[entry title] stringValue];
NSArray *thumbnails = [[(GDataEntryYouTubeVideo *)entry mediaGroup] mediaThumbnails];
NSLog(#"thumbnails:%#",thumbnails);
GDataEntryYouTubeVideo *video = (GDataEntryYouTubeVideo *)entry ;
NSString *videoURL = [[[video links] objectAtIndex: 0] href];
}
/////////////
in class.h
#import "GData.h"
#import "GDataYouTube.h"
#import "GDataServiceGoogleYouTube.h"
#property (nonatomic, retain) GDataFeedYouTubeVideo *feed;

Related

Populating UITableView with NSArray in iOS 7

A lot of the methods have deprecated in iOS 7 in order to set font, textLabel, and color for UITableView cells. I'm also just having a difficult time populating the view with these values. Here's a snippet of my code:
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSArray* jobs = [json objectForKey:#"results"];
for(NSDictionary *jobsInfo in jobs) {
JobInfo *jobby = [[JobInfo alloc] init];
jobby.city = jobsInfo[#"city"];
jobby.company = jobsInfo[#"company"];
jobby.url = jobsInfo[#"url"];
jobby.title = jobsInfo[#"jobtitle"];
jobby.snippet = jobsInfo[#"snippet"];
jobby.state = jobsInfo[#"state"];
jobby.time = jobsInfo[#"date"];
jobsArray = [jobsInfo objectForKey:#"results"];
}
}
I am looping through an array of dictionaries from a GET request and parsed. I am now attempting to fill my UITableView with the following code:
-
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [jobsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *jobsDic = [jobsArray objectAtIndex:indexPath.row];
[cell.textLabel setText:[jobsDic objectForKey:#"jobtitle"]];
return cell;
}
Also, I have declared this is in my .h file:
NSArray *jobsDic;
Any ideas on what I'm doing wrong? Is this an iOS 7 problem?
It seems that you reinitialize jobsarray at the end of the forin loop.
You didn't mean ?
NSArray* jobs = [json objectForKey:#"results"];
NSMutableArray *jobsTemp = [[NSMutableArray alloc] initWithCapacity:jobs.count];
for(NSDictionary *jobsInfo in jobs) {
JobInfo *jobby = [[JobInfo alloc] init];
jobby.city = jobsInfo[#"city"];
jobby.company = jobsInfo[#"company"];
jobby.url = jobsInfo[#"url"];
jobby.title = jobsInfo[#"jobtitle"];
jobby.snippet = jobsInfo[#"snippet"];
jobby.state = jobsInfo[#"state"];
jobby.time = jobsInfo[#"date"];
[jobsTemp addObject:jobby];
}
self.jobsArray = jobsTemp; //set #property (nonatomic, copy) NSArray *jobsArray; in the .h
[self.tableView reloadData]; //optional only if the data is loaded after the view
In the cell for row method :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
JobInfo *job = self.jobsArray[indexPath.row];
cell.textLabel.text = job.title;
return cell;
}
And don't forget :
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.jobsArray.count;
}
Update - an user suggested an edit :
It's true that count isn't a NSArray property. But as Objective-C lets us use a shortcut notation for calling method with a dot, this code works. You have to know limitation of this : if you use a NSArray subclass with a count property with a custom getter this could have side effects #property (nonatomic, strong, getter=myCustomCount) NSUInteger count. As I think code readability is to me one of most important things I prefer to use dot notation. I think Apple SHOULD implement count as readonly property so I use it this way (but it's my point of view). So for those which don't agree with me just read return [self.jobsArray count]; in the tableView:numberOfRowsInSection: method.
Change the declaration of jobsArray from NSArray to NSMutableArray.
Add an initialization at the beginning point of fetchedData method like follows.
if(!jobsArray) {
jobsArray = [NSMutableArray array];
}
else {
[jobsArray removeAllObjects];
}
Remove the following line.
jobsArray = [jobsInfo objectForKey:#"results"];
Instead of that, add the initialized object to the array at the end of for loop.
[jobsArray addObject:jobby];
Add a [tableView reloadData]; at the end of your *-(void)fetchedData:(NSData )responseData; method implementation.
Initially when you are loading the view, tableView will get populated. After you received the data, tableView will not be known that it is received.
Everything else seems good. Hope rest will work fine.

UITableView application crashes when scrolling

Firstly, please forgive my English.
I am learning about iPhone SDK, Obj-C and trying to make UITableView app. But my app crashes when scrolling the table. I've searched but can't solve my problem, so I post my question here and look for your help.
TMTMemberListTableViewController.h
#interface TMTMemberListTableViewController : UITableViewController
{
NSMutableArray *familyMembers;
sqlite3 *database;
}
#property (nonatomic, retain) NSMutableArray *familyMembers;
- (void) configureCell:(TMTFamilyMemberCell *)cell withFamilyMember:(TMTFamily *)member;
#end
TMTMemberListTableViewController.m
#interface TMTMemberListTableViewController (Private)
- (void) loadMemberListFromDatabase;
#end
#implementation TMTMemberListTableViewController
#synthesize familyMembers;
- (void) loadMemberListFromDatabase
{
familyMembers = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"easycook.sqlite"];
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK)
{
const char *sql = "SELECT member_id from family";
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *memberID = [NSString stringWithUTF8String:(char *) sqlite3_column_text(statement, 0)];
TMTFamily *member = [[TMTFamily alloc] initWithMemberID:memberID database:database];
[familyMembers addObject:member];
[member release];
}
}
sqlite3_finalize(statement);
}
else
{
sqlite3_close(database);
NSAssert1(0, #"Failed to open database with message '%s'.", sqlite3_errmsg(database));
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
self.navigationItem.rightBarButtonItem = self.editButtonItem;
[self loadMemberListFromDatabase];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (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 [familyMembers count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//static NSString *MyIdentifier = #"MyIdentifier";
TMTFamilyMemberCell *cell = (TMTFamilyMemberCell *)[tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil)
{
cell = [[[TMTFamilyMemberCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
TMTFamily *member = [familyMembers objectAtIndex:indexPath.row];
// Set up the cell
[self configureCell:cell withFamilyMember:member];
[member release];
return cell;
}
- (void) configureCell:(TMTFamilyMemberCell *)cell withFamilyMember:(TMTFamily *)member
{
cell.familyMember = member;
cell.memberNameLabel.text = member.description;
}
- (void)dealloc
{
NSLog(#"Dealloc");
[familyMembers release];
[super dealloc];
}
When scrolling table, my app crashes with EXC_BAD_ACCESS at
[self configureCell:cell withFamilyMember:member];
and
cell.memberNameLabel.text = member.description;
This line is not incrementing retain counter:
TMTFamily *member = [familyMembers objectAtIndex:indexPath.row]
So the following line is your problem
[member release];
You cannot release object if you down't own it. Either retain it like that:
TMTFamily *member = [[familyMembers objectAtIndex:indexPath.row] retain];
or
TMTFamily *member = [[familyMembers objectAtIndex:indexPath.row] copy];
or remove mentioned release completelly.
First off, welcome to Stack Overflow and welcome to the world of iOS Development.
There are a bunch of problems with your code and if you have an Apple developer account, I highly suggest you head over to the 2012 WWDC Session Videos and look at the talk about Modern Objective C session. https://developer.apple.com/videos/wwdc/2012/
Looking at the code, your bad access could either be an already released object or an empty cell. To determine the cause, you need to enable NSZombies. To do so, click on your project name in the tool bar as shown here:
In this example, it's called PartialTransparentcy (spelling be damned). When you click that button, click the edit scheme button and you'lll see a list of options. You'll want to click enable Zombie objects. If you don't see it, press the Diagnostics tab.
Then run your code and it'll log the object that is giving your grief. Just remember that zombie objects are very expensive. If you submit an app with them enabled, you'll be automatically rejected.
The first thing I notice when I look at your cell initialization code is this:
TMTFamilyMemberCell *cell = (TMTFamilyMemberCell *)[tableView dequeueReusableCellWithIdentifier:nil];
You are sending in a nil identifier which negates that whole entire point of reusing cells. Instead, you are creating a new cell for each row instead of reusing older cells.
So uncomment this line:
static NSString *MyIdentifier = #"MyIdentifier";
and change the dequeue method to read like this:
TMTFamilyMemberCell *cell = (TMTFamilyMemberCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
If you are building your cell in interface builder, you'll need to also give the cell an identifier. This may be the cause of the crash.
Next ... your sqllite code should be encapsulated in another object. There's no reason for the view controller to know about it. Also, you should really investigate core data. It defaults to sqllite backing store. It's also a pretty awesome technology.
And finally, take a look at ARC. Let the compiler handle the grunt work of memory management so that you can focus on the user experience of your application.
Hope that helps and good luck!

tableview will not update on phone

If this is a repost, I apologize, but I have been scouring the net and cant seem to find anything that works. I have a list of workouts that I display in a tableview that are gathered in plists in the bundle. There is a also a separate tab that I have that allows a user to build their own workouts and save them in the documents folder plist file. Once they are saved, they are added to the table view. In the simulator, everyuhting works fine. But on the actual device, it is not updated unless I close the program for an extended period of time, reload the program from xcode, or turn the phone off. I have tried adding [[self tableview] reload] to "viewDidLoad", "viewWillappear", and "viewDidAppear" and none of them work. Once again, the file is saved, the updating does work in the simulator, and it doesn't update in the phone right away. Any suggestions? Thanks.
Edit: i know it is a long piece of code, but should be straight forward (hopefully lol)
#import "BIDWODList.h"
#import "BIDWODDetails.h"
#define kFileName #"SavedDFWorkouts.plist"
#interface BIDWODList ()
#end
#implementation BIDWODList
#synthesize names;
#synthesize savedNames;
#synthesize keys;
#synthesize details;
#synthesize wodType;
#synthesize benchmarkGirls;
#synthesize theNewGirls;
#synthesize heroes;
#synthesize savedDFGWorkouts;
#synthesize chosenWOD;
#synthesize chosenDetails;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *buildBenchmarkGirls = [[NSMutableArray alloc] init];
NSMutableArray *buildTheNewGirls = [[NSMutableArray alloc] init];
NSMutableArray *buildHeroes = [[NSMutableArray alloc] init];
NSBundle *bundle = [NSBundle mainBundle];
NSURL *plistURL = [bundle URLForResource:#"CrossfitWOD" withExtension:#"plist"];
//put the contents of the plist into a NSDictionary, and then into names instance variable
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
self.names = dictionary;
//take all the keys in the dictionary and make an array out of those key names
self.keys = [self.names allKeys];
for (NSString *nameCheck in keys){
self.details = [names valueForKey:nameCheck];
if ([[self.details valueForKey:#"Type"] isEqualToString:#"The Benchmark Girls"]) {
[buildBenchmarkGirls addObject:nameCheck];
}else if ([[self.details valueForKey:#"Type"] isEqualToString:#"The New Girls"]) {
[buildTheNewGirls addObject:nameCheck];
}else {
[buildHeroes addObject:nameCheck];
}
}
NSString *filePath = [self dataFilePath];
NSMutableDictionary *savedWorkout = [[NSMutableDictionary alloc]initWithContentsOfFile:filePath];
self.savedNames = savedWorkout;
self.savedDFGWorkouts = [[savedWorkout allKeys] sortedArrayUsingSelector:#selector(compare:)];
self.benchmarkGirls = [buildBenchmarkGirls sortedArrayUsingSelector:#selector(compare:)];
self.theNewGirls = [buildTheNewGirls sortedArrayUsingSelector:#selector(compare:)];
self.heroes = [buildHeroes sortedArrayUsingSelector:#selector(compare:)];
//[[self tableView] reloadData]; //reloads the data in case a DFG workout was saved
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.names = nil;
self.keys = nil;
self.benchmarkGirls = nil;
self.theNewGirls = nil;;
self.heroes = nil;
self.details = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSString *)dataFilePath {
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kFileName];
}
-(void)viewDidAppear:(BOOL)animated{
[[self tableView] reloadData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 4;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (section == 0) {
return [benchmarkGirls count];
}else if (section == 1){
return [theNewGirls count];
}else if (section == 2){
return [heroes count];
}else{
return [savedDFGWorkouts count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SectionsTableIdentifier];
}
if (section == 0) {
cell.textLabel.text = [benchmarkGirls objectAtIndex:row];
}else if (section == 1) {
cell.textLabel.text = [theNewGirls objectAtIndex:row];
}else if (section == 2) {
cell.textLabel.text = [heroes objectAtIndex:row];
}else{
cell.textLabel.text = [savedDFGWorkouts objectAtIndex:row];
}
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
return #" The Benchmark Girls";
}else if (section == 1){
return #"The New Girls";
}else if (section ==2){
return #"The Heroes";
}else{
return #"Saved DFG Workouts";
}
}
#pragma mark - Table view delegate
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
BIDWODDetails *destination = segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
if (section == 0) {
self.chosenWOD = [self.benchmarkGirls objectAtIndex:row];
self.chosenDetails = [names objectForKey:chosenWOD];
}else if (section == 1) {
self.chosenWOD = [self.theNewGirls objectAtIndex:row];
self.chosenDetails = [names objectForKey:chosenWOD];
}else if (section ==2) {
self.chosenWOD = [self.heroes objectAtIndex:row];
self.chosenDetails = [names objectForKey:chosenWOD];
}else {
self.chosenWOD = [self.savedDFGWorkouts objectAtIndex:row];
self.chosenDetails = [savedNames objectForKey:chosenWOD];
}//end if
//self.chosenDetails = [names objectForKey:chosenWOD];
//[destination setValue:chosenWOD forKey:#"chosenWOD"];
//[destination setValue:chosenDetails forKey:#"chosenDetails"];
destination.chosenWOD = self.chosenWOD;
destination.chosenDetails = self.chosenDetails;
}
#end
Different behaviour between the simulator and the device is often related to incorrect case being used in filenames - the simulator isn't case sensitive, and the device is. Check that you have the correct case used everywhere you reference the plist file.
Alternatively, on the simulator you are able to write directly to the application bundle, but on the device this is not possible and you can only write to certain directories in your application's sandbox, typically the documents directory. You would normally copy a plist to the documents directory on first run, and use that file thereafter.
If I understand right your code you load plist file only in viewDidLoad, but most likely this function called only when you first time load your view. To make it work you should load plist
in viewDidAppear. Something like this:
- (void)viewDidAppear {
NSBundle *bundle = [NSBundle mainBundle];
NSURL *plistURL = [bundle URLForResource:#"CrossfitWOD" withExtension:#"plist"];
//put the contents of the plist into a NSDictionary, and then into names instance variable
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:plistURL];
self.names = dictionary;
//take all the keys in the dictionary and make an array out of those key names
self.keys = [self.names allKeys];
for (NSString *nameCheck in keys){
self.details = [names valueForKey:nameCheck];
if ([[self.details valueForKey:#"Type"] isEqualToString:#"The Benchmark Girls"]) {
[buildBenchmarkGirls addObject:nameCheck];
}else if ([[self.details valueForKey:#"Type"] isEqualToString:#"The New Girls"]) {
[buildTheNewGirls addObject:nameCheck];
}else {
[buildHeroes addObject:nameCheck];
}
}
NSString *filePath = [self dataFilePath];
NSMutableDictionary *savedWorkout = [[NSMutableDictionary alloc]initWithContentsOfFile:filePath];
self.savedNames = savedWorkout;
self.savedDFGWorkouts = [[savedWorkout allKeys] sortedArrayUsingSelector:#selector(compare:)];
[self.tableView reloadData];
}
If it works in the Simulator and does not on the phone, almost for sure the problem is a timing issue. Saving files on a real phone takes much longer than on the simulator.
You should do the following:
when you save a file, log it, and log the return code from the save. If the way you save does not provide a return code, use NSFileManager to verify the file is in fact where it should be and even the size of it. This takes time to do but you should do it.
when your table is asking for the number of this and that, log it, and lot what is returned. You may find that that this comes before the files are saved.
It takes time and effort, but if you start logging all relevant things, you can find it. I just spend 6 hours today tracking down a race condition I had thought could never happen, and it was only after looking at a huge trail of messages that I was able to see the problem.
Almost for sure you will see that either file is not saved, its not where you thought it was, or that the phone timing means some events happen later than they do in the Simulator.

Why am I seeing a crash when displaying this table view?

I am designing a simple navigation based application for EmployeeContactDirectory. I am displaying the list of Employee. For showing the list of employee, I am using the restfull webservice. I am getting proper response as I want. I have a utility class for Employee Data, class is EmployeeData.h and Employee.m (contains employeeId , employeeFirstName, employeeLastName). My code for parsing
// Code for parsing the response and getting desired field into the dictionary object and add the dictionaries into the array.
-(void)finishedReceivingData:(NSData *)data {
NSData *dataRes = [[restConnection stringData] dataUsingEncoding:NSUTF8StringEncoding];
////////////////Parsing with XPathQuery Start//////////////////////
if (dataRes != NULL) {
employeeData = [[EmployeeData alloc] init];
NSString *xPathQuery = [NSString stringWithFormat:#"/*",employeeData.employeeID];
NSArray *arrayWithObjectList = PerformXMLXPathQuery(dataRes, xPathQuery);
for(NSDictionary *childOfObjectList in arrayWithObjectList){
NSArray *arrayOfDataValueObj = (NSArray *)[childOfObjectList objectForKey:#"nodeChildArray"];
for(NSDictionary *childObjListDict in arrayOfDataValueObj){
NSArray *childObjListDataValue = (NSArray *)[childObjListDict objectForKey:#"nodeChildArray"];
for(NSDictionary *childDict in childObjListDataValue){
if([[childDict objectForKey:#"nodeName"] isEqualToString:#"FName" ])
{
employeeData.employeeFirstName = [childDict objectForKey:#"nodeContent"];
}
if([[childDict objectForKey:#"nodeName"] isEqualToString:#"EmpID"])
{
employeeData.employeeID = [childDict objectForKey:#"nodeContent"];
}
}
//employeeFirstNameArray = [NSArray arrayWithObjects:employeeData, nil];
employeeIDArray = [NSArray arrayWithObjects:employeeData, nil];
dictionaryEmployeeFirstName = [NSDictionary dictionaryWithObject:employeeData.employeeFirstName forKey:#"employeeData"];
dictionaryEmployeeID = [NSDictionary dictionaryWithObject:employeeData.employeeID forKey:#"employeeData"];
tempArray = [NSArray arrayWithObjects:dictionaryEmployeeFirstName, dictionaryEmployeeID, nil];
NSLog(#"size of temp %d",[tempArray count]);
}
}
//[employeeData release];
//employeeData = nil;
}
[self.tableviewEmloyeeList reloadData];
//////////////////////////////Parsing with XPathQuery end//////////
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell..
NSDictionary *dictionaryEmployee = [tempArray objectAtIndex:indexPath.row];
NSArray *firstNameArray = [dictionaryEmployee objectForKey:#"employeeData"];
NSString *cellValue = [firstNameArray objectAtIndex:indexPath.row];
NSLog(#"cellValue %#",cellValue);
cell.textLabel.text = cellValue;
return cell;
}
I am getting the message (Exc_bad_Access) when this line of code comes into the execution flow:
NSDictionary *dictionaryEmployee = [tempArray objectAtIndex:indexPath.row]
The EXC_Bad_Access is at the mail.m file at line nt retVal = UIApplicationMain(argc, argv, nil, nil);
So, Please tell me how can I set the data into the tableview when I am using NSDictionary. When, user clicks on the row of the tableview it will return the id of the selected employee.
Instead of the line
tempArray = [NSArray arrayWithObjects:dictionaryEmployeeFirstName, dictionaryEmployeeID, nil];
try the following,
if( tempArray )
{
[tempArray release];
tempArray = nil;
}
tempArray = [[NSArray arrayWithObjects:dictionaryEmployeeFirstName, dictionaryEmployeeID, nil] retain];
Since it is autoreleased, it might have been out of memory.
you need to implement a tableView delegate method called
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
here you will get the section & row clicked in the table

Memory leaks in UITableView with NSMutableArray - How to stop them?

I'm pretty new to objective-c development and I'm to the point I'm beginning to test my application for leaks and patching up anything else I may have done wrong originally. I followed the examples from a book I bought and expanded on those ideas. The Leaks instrument is telling me in my tableView cellForRowAtIndexPath method I have a leak and I'm not sure on how to fix it.
Here is the related .h contents:
#interface NewsListViewController : UITableViewController<UIActionSheetDelegate> {
NSMutableArray *newsList, *account, *playerList;}
And here is the related .m contents:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)ip {
static NSString *CellIdentifier = #"NewsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
[cell autorelease];
}
NSManagedObject *uNews = [newsList objectAtIndex:[ip row]];
NSManagedObjectContext *playerDBContext = [[AppController sharedAppController] managedObjectContext];
NSFetchRequest *playerDBRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *playerDBEntity = [NSEntityDescription entityForName:#"Players"
inManagedObjectContext:playerDBContext];
[playerDBRequest setEntity:playerDBEntity];
NSPredicate *playerDBPredicate = [NSPredicate predicateWithFormat:#"playerID=%#", [uNews valueForKey:#"playerID"]];
[playerDBRequest setPredicate:playerDBPredicate];
NSError *playerDBError;
NSArray *playerDBList = [playerDBContext executeFetchRequest:playerDBRequest error:&playerDBError];
[playerDBRequest release];
playerList = [playerDBList mutableCopy];
NSString *playerInformation;
if (![playerDBList count] == 0) {
NSManagedObject *playerInfo = [playerList objectAtIndex:0];
playerInformation = [NSString stringWithFormat:#"%#, %# (%#-%#)", [playerInfo valueForKey:#"playerLastName"],
[playerInfo valueForKey:#"playerFirstName"],
[playerInfo valueForKey:#"team"],
[playerInfo valueForKey:#"position"]];
} else {
//NSInteger playerID = (NSInteger *)[uNews valueForKey:#"playerID"];
[self addPlayer:(NSInteger *)[uNews valueForKey:#"playerID"]];
NSLog(#"%#", [uNews valueForKey:#"playerID"]);
playerInformation = [uNews valueForKey:#"playerInfo"];
}
cell.textLabel.text = playerInformation;
cell.detailTextLabel.text = [uNews valueForKey:#"news"];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;}
It's throwing the error on the playerList = [playerDBList mutableCopy]; line - Help with how to fix and an explanation would be greatly appreciated. It's probably from reallocating without releasing but when I've tried using [playerList release]; at the end of the cellForRowAtIndexPath my app crashes.
Properties would make this 'just work'.
.h:
...
#property (nonatomic, retain) NSMutableArray *playerList;
...
.m:
#implementation MyClass
#synthesize playerList;
... then in your cellForIndexPath method ...
self.playerList = [[playerDBList mutableCopy] autorelease];
...
- (void)dealloc {
[playerList release];
[super dealloc];
}
A property declared 'retain' will automatically handle memory management when the property is assigned, releasing the old value if it exists before retaining the new one.
The release you tried crashed because the first time through playerlist hasn't ever been assigned and you release a nil. But the second time through it has something and you leak it. Whenever I reuse a retaining pointer like that, I do
if( playerList )
[playerList release];
playerList = [playerDBList mutableCopy];
just to be safe.