Send Mail TableView NSArray - ios

This is my NSObject code;
Task.h
#import <Foundation/Foundation.h>
#interface Task : NSObject
#property (nonatomic,strong) NSString *name;
#property (nonatomic,assign) BOOL done;
-(id)initWithName:(NSString *)name done:(BOOL)done;
#end
Task.m
#import "Task.h"
#implementation Task
#synthesize name = _name;
#synthesize done = _done;
-(id)initWithName:(NSString *)name done:(BOOL)done {
self = [super init];
if (self) {
self.name = name;
self.done = done;
}
return self;
}
This is my send mail code
Task *task = [[Task alloc]init];
MFMailComposeViewController *sendmail = [[MFMailComposeViewController alloc]init];
[sendmail setMailComposeDelegate:self];
NSString *message = [_tasks addObject:task]; // Error is here.
[sendmail setMessageBody:message isHTML:NO];
[sendmail setSubject:#"Test"];
[self presentViewController:sendmail animated:YES completion:nil];
I don't know, How to do it. I just want to send the list with mail. Where is my mistake? And How can I fix this?
Tasklistviewcontroller.m
#synthesize tasks = _tasks;
I am transferring from the tasks table view.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *NotDoneCellIdentifier = #"NotDoneTaskCell";
static NSString *DoneCellIdentifier = #"DoneTaskCell";
Task *currentTask = [self.tasks objectAtIndex:indexPath.row];
NSString *cellIdentifier = currentTask.done ? DoneCellIdentifier : NotDoneCellIdentifier;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = currentTask.name;
return cell;
}

I don't know what is exactly wrong in your code since you don't supply an error and I'm not that proficient yet in Objective-C.
I suspect it is because you reference to "_tasks" which I don't see other code for creating that Class.
NSString *message = [_tasks addObject:task];
Another problem is that you're using task as input object for the array, but it probably doesn't contains something.
You probably wan't something like this:
Task *task = [[Task alloc] initWithName:#"Task 1"];
NSString *message = [[NSString alloc] initWithFormat:#"Task name is %#", task.name];
Also I'm guessing you haven't posted your complete code.
You also forgot to include the right framework for mailing in-app in your header file:
#import <MessageUI/MFMailComposeViewController.h>
Don't forget to also add the framework it to your project!
By the way, you can remove the two lines with synthesize, the compiler does this automatically these days. Nice isn't it?

Related

my method definition is not found but i'm not sure why

I have a storyboard with tabbed browsing. One of the tabs is a table view. The table is populated by a list of animal "titles". when the title is pressed, a detailed view is opened that displays the title in addition to a sound and the number of times that the animal has been clicked. I have a view controller set up. I also have item.h/m and itemstore.h/m. there is also a detailedviewcontroller. my current problem is that in the item store i have two arays set up but right off the bat xcode is telling me that method definitions aren't found. its also giving my undeclared identifier errors.
FSAnimalsViewController.h (this is my table view controller)
#import <AVFoundation/AVAudioPlayer.h>
#import <UIKit/UIKit.h>
#import "FSDetailViewController.h"
#interface FSAnimalsViewController : UITableViewController
{
}
#end
FSAnimalsViewController.m
#import "FSAnimalsViewController.h"
#import "FSItemStore.h"
#import "FSItem.h"
#implementation FSAnimalsViewController
- (id)init
{
// Call the superclass's designated initializer
self = [super initWithStyle:UITableViewStyleGrouped];
if (self)
{
UINavigationItem *n = [self navigationItem];
[n setTitle:#"FoxSays"];
// Create a new bar button item that will send
// addNewItem: to ItemsViewController
[[self navigationItem] setLeftBarButtonItem:[self editButtonItem]];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[self tableView] reloadData];
}
- (id)initWithStyle:(UITableViewStyle)style
{
return [self init];
}
- (void)tableView:(UITableView *)aTableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
FSDetailViewController *detailViewController = [[FSDetailViewController alloc] init];
NSArray *items = [[FSItemStore defaultStore] allItems];
FSItem *selectedItem = [items objectAtIndex:[indexPath row]];
// Give detail view controller a pointer to the item object in row
[detailViewController setItem:selectedItem];
// Push it onto the top of the navigation controller's stack
[[self navigationController] pushViewController:detailViewController
animated:YES];
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [[[FSItemStore defaultStore] allItems] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set the cell identifier
static NSString *CellIdentifier = #"BasicCell";
// Reuse the cell from the identifier
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell if it doesn't exist
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Log the row for debugging
NSLog(#"%d", [indexPath row]);
// Get object from store
FSItem *item = [[[FSItemStore defaultStore] allItems] objectAtIndex:[indexPath row]];
// Set label to from property in object
[[cell textLabel] setText:[item title]];
return cell;
}
#end
FSItem.h
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVAudioPlayer.h>
#interface FSItem : NSObject
#property (nonatomic, copy) NSString *title;
#property (nonatomic) SystemSoundID *sound;
#property (nonatomic) int plays;
- (NSArray *)animals;
- (NSArray *)sounds;
#end
FSItem.m
#import <AudioToolbox/AudioToolbox.h>
#import "FSItem.h"
#implementation FSItem
NSString *title;
SystemSoundID *sound;
int plays;
- (NSArray *)animals
{
NSArray *animals = [NSArray arrayWithObjects:#"Dog",#"Cat",#"Bird",#"Mouse",#"Cow",#"Frog",#"Elephant",#"Duck",#"Fish",#"Seal",#"Fox", nil];
return animals;
}
- (NSArray *)sounds
{
NSArray *sounds = [NSArray arrayWithObjects:
#"Woof.mp3",
#"Meow.mp3",
#"tweet.mp3",
#"Squeak.mp3",
#"Moo.mp3",
#"Croak.mp3",
#"Toot.mp3",
#"Quack.mp3",
#"Blub.mp3",
#"OWOwOw.mp3",
#"Fox.mp3",
nil];
return sounds;
}
#end
FSItemStore.h
#import <AVFoundation/AVAudioPlayer.h>
#import <AudioToolbox/AudioToolbox.h>
#import <Foundation/Foundation.h>
#class FSItem;
#interface FSItemStore : NSObject
{
NSMutableArray *allItems;
}
#property (nonatomic) int i;
+ (FSItemStore *)defaultStore;
- (NSArray *)allItems;
- (NSArray *)animals;
- (NSArray *)sounds;
- (FSItem *)createItem;
#end
FSItemStore.m
#import <AudioToolbox/AudioToolbox.h>
#import "FSItem.h"
#import "FSItemStore.h"
#implementation FSItemStore
int i = 0;
- (NSArray *)allItems
{
return allItems;
}
+ (FSItemStore *)defaultStore;
{
static FSItemStore *defaultStore = nil;
if(!defaultStore)
defaultStore = [[super allocWithZone:nil] init];
return defaultStore;
}
- (FSItem *)createItem
{
FSItem *item = [[FSItem alloc] init];
if (i < [animals count])
{
[item setTitle: [animals objectAtIndex: i]];
[item setSound: [sounds objectAtIndex: i]];
[item setPlays: 0];
i++;
[allItems addObject: item];
}
return item;
}
#end
FSItemStore is where my problems seem to be. Its saying that method definition for sounds and animals isn't found and both sounds and animals are undeclared identifiers. Anyone got any ideas?
Your problem is that in your H file you are declaring that your class will implement a method called animals that will return an NSArray, and a method call sounds that will return another NSArray, but in your M file you are not implementing these methods.
In your FSItemStore.m you should implement these methods:
- (NSArray *)animals{
//Do whatever this method is supposed to do, return an NSArray.
}
- (NSArray *)sounds
{
//Do whatever this method is supposed to do, return an NSArray.
}
EDIT
If what you pretend is that FSItemStore inherits the methods from FSItem, you have to declare the interface that way:
#interface FSItemStore : FSItem //FSItem instead of NSObject
{
NSMutableArray *allItems;
}
If I understood your code correctly you want to set one of the animals and sounds initialized in FSItem::sounds and FSItem::animals to the new item that you create in FSItemStore::createItem. So the animals and sounds methods should be executed ont eh correct object - the FSItem object. Change your code in FSItemStore::createItem to this -
- (FSItem *)createItem
{
FSItem *item = [[FSItem alloc] init];
if (i < [animals count])
{
[item setTitle: [[item animals] objectAtIndex: i]];
[item setSound: [[item sounds] objectAtIndex: i]];
[item setPlays: 0];
i++;
[allItems addObject: item];
}
return item;
}
This is still a bad way of doing what you want, as the NSArray will be initialized everytime you create an item. If the number of sounds and animals is fixed, better define them so that they just get initialized once e.g. static objects in FSItem or property on FSItemStore
You haven't defined any properties or variables that are called animals or items. You have only defined the getter methods.
e.g.
#property(nonatomic,strong) NSArray *animals;
#property(nonatomic,strong) NSArray *items;
Then the implementation of your getters, would return these properties.

Memory keep increasing when the UITableView scrolling

there is a strange problem I have not met ever
there is an array() including some custom object named MyClass parsed by JSONKit;
when I keep scrolling the tableview the memory will keeping increasing too.
but when replace
cell.textLabel.text = myclass.name;
with
cell.textLabel.text = #"cool";
or
cell.textLabel.text = [NSString stringWithFormate:#"a-%d", indexPath.row];
it's ok the memory with keep stable
but if I use
cell.textLabel.text = [NSString stringWithFormate:#"a-%#-i",myclass.name, indexPath.row];
it also keep increasing;
It will drive my crazy!!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Singers";
OMTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
MyClass *myclass = [self.data objectAtIndex:indexPath.row];
if (cell == nil){
cell = [[[OMTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
}
cell.textLabel.text = myclass.name;
return cell;
}
MyClass
there is two class one Base another inherit
Base:
#interface OMBase : NSObject {
NSMutableDictionary *data;
NSString *name;
NSArray *keys;
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, copy) NSMutableDictionary *data;
#implementation OMBase
#synthesize data, name;
- (void)setData:(NSMutableDictionary *)adata{
if (data){
[data release];
data = nil;
}
data = [adata mutableCopy];
}
- (void)dealloc{
if (keys){
[keys release];
}
[data release];
[super dealloc];
}
- (id)init{
if (self = [super init]){
self.data = [[[NSMutableDictionary alloc] initWithCapacity:20] autorelease];
}
return self;
}
inherit:
#import "OMBase.h"
#interface OMLyric : OMBase
- (NSString *)songid;
- (NSString *)content;
#import "OMLyric.h"
#implementation OMLyric
- (NSString *)songid{
return [data objectForKey:#"songid"];
}
- (NSString *)content{
return [data objectForKey:#"content"];
}
Seems like your myclass.name getter returns a new allocated object. We can't say more without seeing myclass.

Queue a NSMutableArray into a NString as a loop?

If one had a NSString that needed a userid to be used as a URL for a request:
And one had a NSMutableArray that he wanted to Queue into the above call one at a time? So basically make 3 calls of NSString from the NSMutableArray .
One can check multiple UITableView cells and once completed I can index which cell rows were pushed. That is what userIDArray is used for now I want to make a call with the userID's I got back from userIDArray.
for (NSDictionary* userIDDict in userIDArray)
{
userIDArray = [[NSMutableArray alloc] init]; //I put this line in my viewdidload
NSNumber* userID = [userIDDict objectForKey:#"UserID"];
}
UserIDArray is the NSMutableArray .
This would be the NSLog from the NSMutableArray The Integer would be 1, 2 and 3.
UserID: 1
UserID: 2
UserID: 3
So in other words I would like to take the results from my NSMultiTableArray 1,2 and 3 to use within the NSString :
NSString *userProfile = [NSString stringWithFormat:#"http://example.com/userid=1"];
NSString *userProfile = [NSString stringWithFormat:#"http://example.com/userid=2"];
NSString *userProfile = [NSString stringWithFormat:#"http://example.com/userid=3"];
So I would make the first call and wait for a result, and then the second and finally the third.
Can this be done? I have search this link about Queues and this one but I am unsure if those are what I need?
UserDetailViewController.h file:
#interface UserDetailViewController : UIViewController <UITableViewDelegate>{
long long expectedLength;
long long currentLength;
UITableView *userTableView;
NSIndexPath* checkedIndexPath;
}
#property (nonatomic, retain) NSArray *userIDJson;
#property (strong, nonatomic) NSDictionary *userIDDict;
#property (nonatomic, retain) NSIndexPath* checkedIndexPath;
#property (nonatomic, strong) NSMutableArray *userIDArray;
#property (nonatomic) NSInteger currentUserIndex;
#end
UserDetailViewController.m file:
#interface UserDetailViewController ()
#end
#implementation UserDetailViewController
#synthesize userIDJson;
#synthesize userIDDict;
#synthesize checkedIndexPath;
#synthesize userIDArray;
#synthesize currentUserIndex;
- (void)viewDidLoad
{
[super viewDidLoad];
userIDArray = [[NSMutableArray alloc] init];
[self.navigationController setNavigationBarHidden:NO];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//return self.loadedSearches.count;
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.userIDJson.count;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.text = self.userIDJson[indexPath.row][#"UserName"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if([self.checkedIndexPath isEqual:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *thisCell = [tableView cellForRowAtIndexPath:indexPath];
NSString *userStringIndex = [self.userIDJson objectAtIndex:indexPath.row];
if (thisCell.accessoryType == UITableViewCellAccessoryNone)
{
thisCell.accessoryType = UITableViewCellAccessoryCheckmark;
[userIDArray addObject:userStringIndex];
}
else
{
thisCell.accessoryType = UITableViewCellAccessoryNone;
[userIDArray removeObject:userStringIndex];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (self.currentUserIndex < userIDArray.count) {
NSNumber* userID = [[userIDArray objectForIndex:currentUserIndex]objectForKey:#"UserID"];
//Make the actual request here, and assign the delegate.
NSString *userProfile = [NSString stringWithFormat:#"http://example.com/userid=%#",userID];
self.currentUserIndex++;
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:userProfile]];
NSString *userResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSURL *url = [[NSURL alloc] initWithString: userProfile];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
userIDJson = [NSJSONSerialization JSONObjectWithData:dataURL
options:kNilOptions
error:&error];
}
}
for (userIDDict in userIDArray)
{
NSNumber* userID = [userIDDict objectForKey:#"UserID"];
NSLog(#"%#", userID);
NSArray* userName = [userIDDict objectForKey:#"UserName"];
}
NSURLConnection can take a delegate through the constructor initWithRequest:delegate:. So you need the object that makes the calls conform to that protocol, I'll assume it's a UIViewController. You can use one of the required methods in the delegate to fire up the next request.
For example, assume you have property to indicate the current index.
#property (nonatomic) NSInteger currentUserIndex;
Then in the place that will fire the first request, make the call for the first user. In some delegate method, say connectionDidFinishLoading:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (self.currentUserIndex < self.userIDArray.count) {
NSNumber* userID = [[self.userIDArray objectAtIndex:self.currentUserIndex] objectForKey:#"UserID"];
self.currentUserIndex++;
//Make the actual request here, and assign the delegate.
}
}
Of course, if your connection calls don't have to be synchronous, you can do it in an easier way.

Variable is disappearing when certain functions are called

I'm kind of a noob so hopefully this isn't too complex. I'm having a problem with my code that has so far stumped and confused me and some other users. I spent some time cleaning my code, and following some tutorials, but I still get past this issue. I just know it is something really simple, so here goes:
Im making an iOS app for my blog site. It goes to the site, pulls an XML document (containing the blog title, brief description, and full article url), and parses it to display in a UITableView. To manage this, there are two custom objects: "PostList", and "Post". Post is just an object that hold the individual post data (url, title, publication date, etc) and PostList has an array that holds the Post objects, as well as some getter/setter/init functions.
That all works well. The view loads and the XML is parsed and displays in the list. The problem arises when the user either taps on a link or scrolls some cells off the screen. As far as I can tell, these are both related to the same problem. In the case of the user tapping on the cell, the view controller does not pass a value to the detailed view controller (prepareForSegue), and in the case of scrolling, the cellForRowAtIndexPath does not reinitialize the cell values.
I believe that this is al due to the same problem, that once the view has been initialized, the existing values in the PostList array are somehow deleted. The debugger says the array still sees objects inside it, but they are all blank objects. I have spent forever trying to figure out why.
If you could give me some ideas why this is happening that would be AMAZING! My code is below. I posted almost all of it since Ive had issues with not posting enough before. Hope this helps. If you need more please ask!
-Thanks in advance ;)
FirstViewController.h
#import <UIKit/UIKit.h>
#import "PostList.h"
#import "Post.h"
#interface FirstViewController : UITableViewController
#property (nonatomic, strong) PostList *postController;
#property (nonatomic, strong) IBOutlet UITableView *tableView;
#property (nonatomic, strong) Post *postToSendToDetailView;
#property (nonatomic, strong) NSString *type;
#end
FirstViewController.m
#import "FirstViewController.h"
#import "DetailViewController.h"
#import "Post.h"
#import "PostList.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.type = #"blog";
self.postController = [[PostList alloc] initWithType:self.type];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.postController countOfList];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Post *postAtSighting = [self.postController objectInListAtIndex:indexPath.row];
// Configure the cell...
[[cell textLabel] setText:postAtSighting.name];
[[cell detailTextLabel] setText:postAtSighting.content];
NSLog(#"Cell Initalized");
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"pushToDetailView"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *destViewController = segue.destinationViewController;
destViewController.aPost = [self.postController objectInListAtIndex:indexPath.row];
}
}
#end
PostList.h
#import <Foundation/Foundation.h>
#import "Post.h"
#interface PostList : NSObject
-(NSMutableArray *) getPostsofType:(NSString *)type;
-(NSString *) getName: (Post *)aPost;
-(NSUInteger) countOfList;
-(Post *)objectInListAtIndex:(NSUInteger)theIndex;
-(id)initWithType:(NSString *)type;
#property (nonatomic, strong) NSMutableArray *postsArray;
#property (nonatomic) NSString *urlString;
#property (nonatomic) NSUInteger countingIndex;
#end
PostList.m
#import "PostList.h"
#import "TBXML+HTTP.h"
#implementation PostList
- (id)initWithType:(NSString *)type {
self = [super init];
if (self) {
//Creates postArray to store Post objects
self.postsArray = [[NSMutableArray alloc] init];
//Create other resources
self.urlString = [[NSString alloc] init];
self.countingIndex = 0;
[self getPostsofType:type];
}
return self;
}
-(NSString *)getName:(Post *)somePost {
//Gets the Name of the Post object and returns the value
NSString *name = somePost.name;
return name;
}
-(NSMutableArray *)getPostsofType:(NSString *)type {
//Go to the Server and get the posts that are available for the post type selected.
//Determing the post type
if ([type isEqual: #"blog"]) {
self.urlString = #"http://www.biteofanapple.com/blog/feeds/blogFeed.xml";
}
if ([type isEqual: #"bbp"]) {
self.urlString = #"http://www.biteofanapple.com/blog/feeds/blogFeed.xml";
}
//Checks for an existant xmlBlogData.xml
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents directory
NSString* blogXML = [documentsDirectory stringByAppendingPathComponent:#"xmlBlogData.xml"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:blogXML];
NSData *data = [[NSData alloc] init];
//Determines the best way to handle the xml file
if (fileExists) {
data = [NSData dataWithContentsOfFile:blogXML];
} else {
NSURL *url = [NSURL URLWithString:self.urlString];
//Goes to the Server and reads the XML file of the Posts
data = [NSData dataWithContentsOfURL:url];
if (data != nil) {
NSLog(#" NSData value is not nil");
}
//Saves the XML data to a .dat file in the document's directory
NSError *error;
BOOL succeed = [data writeToFile:[documentsDirectory stringByAppendingPathComponent:#"xmlBlogData.dat"] atomically:YES];
if (!succeed){
// Handle error here
NSLog(#"Error: File was unable to be written to the documents directory.");
[error setValue:#"-1" forKey: #"File unable to be written"];
}
}
//Parses the XML file
TBXML *tbxml = [TBXML newTBXMLWithXMLData:data error:nil];
//Prints the data Variable to NSLog
NSLog(#"%#", [NSString stringWithUTF8String:[data bytes]]);
//Make some placeholder variables
if (tbxml.rootXMLElement == nil) {
NSLog(#"XML Document does not have rootElement. Error -1");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Sorry, there was an error" message:#"Could not find root XML element. Please contact support for help with this issue." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
TBXMLElement *element = tbxml.rootXMLElement;
TBXMLElement *nextElement = element->nextSibling;
NSLog(#"URLs have been set, preparing for parse/input. [PostList.getPosts]");
//Extracts the content of the XML file and saves it to values in the Post Class
do {
/**********
* This loop goes through the XML file looking for <item> tags that hold information
* about the blog posts. It finds <item> tags and scours them for <title>, <description>,
* <pubdate>, and <link> tags to put into the class variables for the Post Class (aPost).
**********/
NSString *stringElement = [TBXML elementName:element];
NSLog(#"%#", stringElement);
//Creates Post variable to put stuff in.
Post *aPost = [[Post alloc] init];
//Sorts through the header junk to find the first <item> tag.
if (![stringElement isEqualToString:#"item"]) {
if (!(element->firstChild)) {
if (!(element->nextSibling)) {
element = nil;
}
element = element->nextSibling;
}
element = element->firstChild;
}
//Once the first <item> tag is found, this code executes.
else {
//Now we move to the first child tag and scour its contents and its siblings
nextElement = [TBXML nextSiblingNamed:#"item" searchFromElement:element];
element = element->firstChild;
do {
//Here it loops over and over until all the parts have been collected.
stringElement = [TBXML elementName:element];
if ([stringElement isEqualToString:#"title"]) {
aPost.name = [TBXML textForElement:element];
}
if ([stringElement isEqualToString:#"description"]) {
aPost.content = [TBXML textForElement:element];
}
if ([stringElement isEqualToString:#"link"]) {
aPost.postURL = [TBXML textForElement:element];
}
if ([stringElement isEqualToString:#"pubdate"]) {
aPost.publicationDate = [TBXML textForElement:element];
}
element = element->nextSibling;
} while (element->nextSibling);
NSLog(#"%#", [self getName:aPost]);
NSLog(#"name %# content %#", aPost.name, aPost.content);
[self.postsArray insertObject:aPost atIndex:self.countingIndex];
self.countingIndex++;
element = nextElement;
}
} while ((element != nil));
return self.postsArray;
}
-(Post *)objectInListAtIndex:(NSUInteger)theIndex {
return [self.postsArray objectAtIndex:theIndex];
}
-(NSUInteger)countOfList {
return [self.postsArray count];
}
#end
Post.h
#import <Foundation/Foundation.h>
#class Post;
#interface Post : NSObject
#property (nonatomic, weak) NSString *name;
#property (nonatomic, weak) NSString *author;
#property (nonatomic, weak) NSString *publicationDate;
#property (nonatomic, weak) NSString *content;
#property (nonatomic, weak) NSString *postURL;
#end
Post.m
#import "Post.h"
#implementation Post
- (id)init {
self = [super init];
if (self) {
self.name = #"";
self.author = #"";
self.content = #"";
self.publicationDate = #"";
self.postURL = #"";
}
return self;
}
#end
As I posted in the comment above, the problem is you are using weak references in your Post class. Try this code instead:
#import <Foundation/Foundation.h>
#class Post;
#interface Post : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *author;
#property (nonatomic, strong) NSString *publicationDate;
#property (nonatomic, strong) NSString *content;
#property (nonatomic, strong) NSString *postURL;
#end
If you want to learn about the differences between strong and weak references, take a look at this question:
Differences between strong and weak in Objective-C
Also note that the default reference type for objective-c properties is strong, so you can omit the strong keyword if you wish.

Xcode Data Controller Issue

I have an application that has the following parts:
StoreDataController.h
StoreDataController.m
StoreTableViewController.h
StoreTableViewController.m
I created a property & method in StoreDataController that retrieves data from a URL and converts it to JSON. I then store it in an Array. I'm trying to get the table controller to display the array in the table but it isn't displaying. What do I need to do to have the Table display the contents of the array? Here is the code I have:
StoreDataController.h
#interface StoreDataController : NSObject
#property (nonatomic, retain) NSArray *storeNames;
-(void)addStoreNamesObject:(NSArray *)storeNames;
#end
StoreDataController.m
#import "StoreDataController.h"
#import "SBJson.h"
#implementation StoreDataController
-(void)addStoreNamesObject:(NSArray *)storeNames
{
NSString *strURL = [NSString stringWithFormat:#"http://10.247.245.87/stores/dodge.php"];
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
storeNames = [strResult JSONValue];
}
#end
StoreTableViewController.h
#import <UIKit/UIKit.h>
#class StoreDataController;
#interface StoreTableViewController : UITableViewController
#property (nonatomic, retain) StoreDataController *storeNameController;
#end
StoreTableViewController.m
#import "StoreTableViewController.h"
#import "StoreDataController.h"
#interface StoreTableViewController ()
#end
#implementation StoreTableViewController
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _storeNameController.storeNames.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [_storeNameController.storeNames objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
You at least need something to set the storeNameController property inside your StoreTableViewController so that it references the StoreDataController object that is doing the work of building the array.
How you do that depends on what creates the StoreDataController object and how that's related to your view controller.
(Aside: In general, you should use self.propertyName instead of _propertyName.)

Resources