Mail composer didn't display under my UIWebView - uiwebview

I have a MainController and detailedcontroller. When I popover the Book selection and select a Book, the detailcontroller display an UIWebView with the book articles :
#interface IpadBooksViewController : UITableViewController {
SearchResult *searchResult;
IpadArticleViewController *detailController;
IpadMainViewController *mainController;
UIPopoverController *popover;
}
Into the UIWebView, I display an Email icon and catch the scheme :
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSURL *url = [request URL];
NSString *scheme = [url scheme];
NSString *host = [url host];
if ([[url description] hasSuffix:#"next"]) {
NSLog(#"next Show");
}
BOOL isShareLinks = [host isEqualToString:#"displayShareLinks"];
BOOL isFavoriteLinks = [host isEqualToString:#"displayFavoriteLinks"];
if ([#"myappurl" isEqualToString:scheme] && (isShareLinks || isFavoriteLinks)) {
self.selectedArticleNumber = [url.path lastPathComponent];
if (isShareLinks) {
[self sendMailArticleNumber:selectedArticleNumber];
} else if (isFavoriteLinks) {
NSLog(#"ipad favorite clicked");
[self toggleFavorite:selectedArticleNumber];
Broker *broker = [[Broker alloc] init];
[broker loadProjects:self];
[broker release];
}
}
return [super webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
}
Action is supposed to display the MFMailController under my UIWebView, but nothing is displayed without error message :
- (void) sendMailArticleNumber:(NSString *)articleNumber {
MFMailComposeViewController* composer = [[MFMailComposeViewController alloc] init];
composer.mailComposeDelegate = self;
[composer setSubject:#"Article"];
NSString *messageBody = [Article fetchBody:articleNumber bookId:bookId];
[composer setMessageBody:messageBody isHTML:YES];
[self presentModalViewController:composer animated:YES];
[composer release];
}
Any help will be welcomed. I did try creating a popover, addView atIndex without success ... Let me know if you need more code.
David

I did solve the issue by loading the controller into the delegate as following :
[((PublilexAppDelegate*)[[UIApplication sharedApplication] delegate]) sendMailArticleNumber:selectedArticleNumber bookId:self.bookId];
And then into the Delegate :
- (void) sendMailArticleNumber:(NSString *)articleNumber bookId:(NSString*)bookId {
MFMailComposeViewController* composer = [[MFMailComposeViewController alloc] init];
composer.mailComposeDelegate = self;
[composer setSubject:#"Article"];
NSString *messageBody = [Article fetchBody:articleNumber bookId:bookId];
[composer setMessageBody:messageBody isHTML:YES];
[self->navigationController presentModalViewController:composer animated:YES];
[composer release];
}
And to dismiss and comeback to the previous view :
-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self->navigationController dismissModalViewControllerAnimated:YES];
// [self dismissViewControllerAnimated:YES completion:nil];
// [((PublilexAppDelegate*)[[UIApplication sharedApplication] delegate]) navigateToIpadMain];
}

Related

CoreDataTableViewController does not reload on return from segue

I have several CoreDataTableViewControllers that utilize the helper class from Paul Hegarty's course. Everyone of them works except this one, and I cannot see a difference.
When the table first comes up, it is correctly populated and the segue executes properly when a cell is selected. However when I hit the back button, the table displays (null), (null) everywhere.
I have tried every variant of calling [self useDocument] that I can think of, still to no avail. Any thoughts? Thanks in advance.
//
// TeamTableViewController.m
//
#import "TeamTableViewController.h"
#import "iTrackAppDelegate.h"
#import "CoreDataTableViewController.h"
#import "SchoolRecords.h"
#import "ScheduleViewController.h"
#interface TeamTableViewController ()
#property NSInteger toggle;
#end
#implementation TeamTableViewController
#synthesize iTrackContext = _iTrackContext;
#synthesize schoolSelected = _schoolSelected;
-(void) setSchoolSelected:(SchoolRecords *)schoolSelected
{
_schoolSelected = schoolSelected;
}
-(void) setITrackContext:(NSManagedObjectContext *)iTrackContext
{
if(_iTrackContext != iTrackContext){
if (!iTrackContext) {
MyCoreDataHandler* cdh =
[(iTrackAppDelegate *) [[UIApplication sharedApplication] delegate] cdh];
_iTrackContext = cdh.context;
} else {
_iTrackContext = iTrackContext;
}
}
[self useDocument];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)setupFetchedResultsController // attaches an NSFetchRequest to this UITableViewController
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"SchoolRecords"];
// no predicate because we want ALL the Athletes
request.sortDescriptors = [NSArray arrayWithObjects:
[NSSortDescriptor sortDescriptorWithKey:#"schoolName" ascending:YES],
nil];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.iTrackContext
sectionNameKeyPath:nil
cacheName:nil];
__block NSInteger myCount;
int64_t delayInSeconds = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.iTrackContext performBlock:^(void){NSError* requestError = nil;
myCount = [self.iTrackContext countForFetchRequest:request error:&requestError];
NSLog(#"In %# and count of iTrackContext = %lu", NSStringFromClass([self class]),(unsigned long)myCount);
}];
if (!myCount || myCount == 0) {
[self displayAlertBoxWithTitle:#"No Teams" message:#"Have you added athletes yet? \nPlease go to Add Athletes" cancelButton:#"Okay"];
}
});
}
- (void)useDocument
{
if (self.iTrackContext) {
[self setupFetchedResultsController];
} else {
NSString* errorText = #"A problem arose opening the search results database of Athletes.";
[self displayAlertBoxWithTitle:#"File Error" message:errorText cancelButton:#"Okay"];
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (!self.iTrackContext) {
MyCoreDataHandler* cdh =
[(iTrackAppDelegate *) [[UIApplication sharedApplication] delegate] cdh];
[self setITrackContext:cdh.context];
} else {
NSLog(#"In %# of %#. Getting ready to call useDocument",NSStringFromSelector(_cmd), self.class);
[self useDocument];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// If divide into sections use line below otherwise return 1.
// return [[self.fetchedResultsController sections] count];
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Do not really need this with only one section, but makes code usable if add sections later.
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"teamInformation";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
SchoolRecords *schoolResults = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString* titleText = schoolResults.schoolName;
cell.textLabel.text = titleText;
cell.detailTextLabel.text = [NSMutableString stringWithFormat:#"%#, %#", schoolResults.schoolCity, schoolResults.schoolState];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
# pragma navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
[self setSchoolSelected:[self.fetchedResultsController objectAtIndexPath:indexPath]];
// be somewhat generic here (slightly advanced usage)
// we'll segue to ANY view controller that has a photographer #property
if ([segue.identifier isEqualToString:#"scheduleDetailSegue"]) {
// use performSelector:withObject: to send without compiler checking
// (which is acceptable here because we used introspection to be sure this is okay)
NSLog(#"Preparing to passing school with schoolID = %#", self.schoolSelected.schoolID);
[segue.destinationViewController convenienceMethodForSettingSchool:self.schoolSelected];
}
}
- (void) displayAlertBoxWithTitle:(NSString*)title message:(NSString*) myMessage cancelButton:(NSString*) cancelText
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:myMessage
delegate:nil
cancelButtonTitle:cancelText
otherButtonTitles:nil];
[alert show];
}
#end
Well, I am not certain what the problem was. I ended up deleting the "offending" TableViewControllers in StoryBoard and recreated them. That did the trick. In retrospect, I wonder if I did not specify the wrong type of segue from my tabViewController. But I deleted it before I thought of that possibility.

UITableViewController: Data Parses but `numberOfRowsInSection:` returns NULL.

I have a UITableView populated by data parsed from xml. The parsing works but the table remains blank.
The console shows that the xml form the url is parsed and shows its components. It also shows the number of objects that the rows of tableview should have when asked in a different function but the numberOfRowsInSection: is returning Null. Therefore, the tableView in the Simulator remains blank.
Here is my code. It is simple code from a tutorial:
+++++++++++++++++ RootViewController.h++++++++++++++++++++++
#import < UIKit/UIKit.h >
#interface RootViewController : UITableViewController < NSXMLParserDelegate >{
IBOutlet UITableView *newsTable;
UIActivityIndicatorView *activityIndicator;
CGSize cellSize;
NSXMLParser *rssParser;
NSMutableArray *stories;
NSMutableDictionary *item;
NSString *currentElement;
NSMutableString *currentTitle, *currentDate, *currentSummary, *currentLink;
}
#property (nonatomic, retain) NSMutableArray *stories;
#property (nonatomic, retain) IBOutlet UITableView *newsTable;
-(void)parseXMLFileAtURL:(NSString *)URL;
#end
+++++++++++++++++++++++++++ RootViewController.m ++++++++++++++++++++++++++++++++++++++
#import "RootViewController.h"
#implementation RootViewController
#synthesize newsTable, stories;
-(void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[newsTable reloadData];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if([stories count] == 0){
NSString *path = #"http://feeds.feedburner.com/TheAppleBlog";
[self parseXMLFileAtURL:path];
}
cellSize = CGSizeMake([newsTable bounds].size.width, 60);
}
// Customize the number of sections in the table view.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(void)parseXMLFileAtURL:(NSString *)URL {
stories = [[NSMutableArray alloc] init];
NSURL *xmlURL = [NSURL URLWithString:URL];
rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[rssParser setDelegate:self];
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
-(void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(#"Found file and started parsing");
}
-(void) parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
NSString *errorString = [NSString stringWithFormat:#"Unable to download story feed from the website (error code %i)", [parseError code]];
NSLog(#"error parsing XML: %#", errorString);
UIAlertView *errorAlert = [[UIAlertView alloc]:#"Error loading content" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitle:nil];
[errorAlert show];
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
NSLog(#"Found this Element %#", elementName);
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
NSLog(#"End this Element %#", elementName);
if ([elementName isEqualToString:#"item"]) {
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentLink forKey:#"link"];
[item setObject:currentSummary forKey:#"summary"];
[item setObject:currentDate forKey:#"date"];
[stories addObject:[item copy]];
NSLog(#"adding Story : %#",currentTitle);
}
}
// Customize the number of rows in the table view.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Count is = %#", [stories count]);
return [stories count];
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(#"Found characters: %#", string);
if([currentElement isEqualToString:#"title"]){
[currentTitle appendString:string];
NSLog(#"The Title is : %#", currentTitle);
}
else if([currentElement isEqualToString:#"link"]){
[currentLink appendString:string];
NSLog(#"The Link is : %#", currentLink);
}
else if([currentElement isEqualToString:#"description"]){
[currentSummary appendString:string];
NSLog(#"The summary is : %#", currentSummary);
}
else if([currentElement isEqualToString:#"pubDate"]){
[currentDate appendString:string];
NSLog(#"The Date is : %#", currentDate);
}
}
-(void)parserDidEndDocument:(NSXMLParser *)parser{
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
NSLog(#"Stories array has %d items", [stories count]);
NSLog(#"Stories are : %#",stories);
}
// Customize the appearance of table view cells.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
// Configure the cell.
cell.textLabel.text = (NSString *)[[stories objectAtIndex:indexPath.row] objectForKey:#"title"];
return cell;
}
-(void)dealloc {
[super dealloc];
[newsTable release];
[currentDate release];
[currentElement release];
[currentSummary release];
[currentLink release];
[stories release];
[item release];
[currentTitle release];
[rssParser release];
}
You have to tell the table view that there is new data by calling reloadData after you have parsed the XML.
Is the newsTable outlet properly connected to the table view in IB? And, is the table's dataSource outlet set to your view controller?
To expand on #omz's correct answer:
The method numberOfRowsInSection is not returning NULL but zero. (In Objective-C, nil==zero and Null is a singleton object.)
The only reason that it would return zero is if the [stories count] returns zero and the only reason [stories count] would return zero is if it has no elements. Since you've confirmed that the parse works and stories has elements, then the tableview must be seeking data before the parse occurs.
This method is called first and it is the only place you reload data:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[newsTable reloadData];
// You trigger the tableview to call numberOfRowsInSection before stories is populated.
}
This method is called only after the tableview has appeared on screen and it is only after the tableview appears that you populate stories.
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if([stories count] == 0){
NSString *path = #"http://feeds.feedburner.com/TheAppleBlog";
[self parseXMLFileAtURL:path];
}
cellSize = CGSizeMake([newsTable bounds].size.width, 60);
}
However, nothing triggers the tableview to call numberOfRowsInSection again so the tableview remains blank. Simply moving the populating of stories to viewWillAppear: will fix the problem.
Each time you alter the data upon which the tableview depends (regardless of reason) you must call reloadData otherwise the tableview remains unaware that it no longer displays the current data set.
As an aside, you should use the dot notation when referring to properties to ensure they are properly retained. You should use self.stories to refer to the stories property. Otherwise, it might be released at random causing an equally random crash.

Proper release of UIImagePickerController

I'm a bit confused with this as I've seen way too many different variants and not sure which one is the correct way. Currently I have:
- (IBAction)pickImageFromLibrary:(id)sender
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
// [picker release];
}
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0.0f, 10.0f, 320.0f, 264.0f)];
self.studyView = imageView;
[imageView release];
[self.tableView setTableHeaderView:studyView];
self.fitImage = [ImageHelper image:image fitInView:studyView];
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera)
{
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
studyView.image = self.fitImage;
[self dismissModalViewControllerAnimated:YES];
[picker release];
}
I'm allocating the UIImagePickerController in the first method but wouldn't it be logical to only release it in the 2nd method when I dismiss it?
No, because it's retained when presented modally, via presentModelViewController. This is the common pattern you'll find when presenting new view controllers, whether modally, custom view controllers or not. This is fine:
- (IBAction)pickImageFromLibrary:(id)sender
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
[picker release];
}

IPhone how do display Leaderboard screen in my own game .... developed in cocos2d

i want to show leaderbord in my own game ....i am using following method for that but noting happen ... i am confuse with rootview controller as my game is developed in cocos2d so there is nothing like dat :(
// Leaderboards
-(void) showLeaderboard
{
if (isGameCenterAvailable == NO)
return;
GKLeaderboardViewController* leaderboardVC = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardVC != nil)
{
leaderboardVC.leaderboardDelegate = self;
[self presentViewController:leaderboardVC];
}
}
///
-(void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController*)viewController
{
[self dismissModalViewController];
[delegate onLeaderboardViewDismissed];
}
///////
-(UIViewController*) getRootViewController
{
return [UIApplication sharedApplication].keyWindow.rootViewController;
}
///
-(void) presentViewController:(UIViewController*)vc
{
UIViewController* rootVC = [self getRootViewController];
[rootVC presentModalViewController:vc animated:YES];
}
////
-(void) dismissModalViewController
{
UIViewController* rootVC = [self getRootViewController];
[rootVC dismissModalViewControllerAnimated:YES];
}
...
regards
Haseeb
i dont know but it work for me.if anyone can describe the real reason for why this working in this way i will be very glad....i call it through appdelegate
[(myAppDelegate*)[[UIApplication sharedApplication] delegate]gameCenter];
and from appdelegate i call rootviewcontroller method like
-(void)gameCenter
{
[rootViewController gameCenterLeaderboard];
}
and in rootviewcontroller there is a method
-(void)gameCenterLeaderboard
{
GKLeaderboardViewController* leaderboardVC = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardVC != nil) {
leaderboardVC.leaderboardDelegate = self;
[self presentModalViewController: leaderboardVC animated: YES];
}
}
the following method is also override in rootviewcontroller
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)leaderboardController
{
[self dismissModalViewControllerAnimated:YES];
}
If you don't have a root UIViewController then I'd recommend creating a new UIViewController set it's view to your openGLView then use that view controller to present the leaderboard as a modal view controller.
UIViewController *leaderboardViewController = [[UIViewController alloc] init];
[leaderboardViewController setView:[[CCDirector sharedDirector] openGLView]];
[leaderboardViewController presentModalViewController:leaderboardVC animated:YES]; //leaderboardVC is your GKLeaderboardViewController

CoverFlow multiple Views

Good Morning at all,
i have a big problem in the following code and no solution, so i hope someone could
help me:
- (IBAction)goToChart {
[rootViewController switchViews];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *weiter = [UIButton buttonWithType:UIButtonTypeRoundedRect];
weiter.frame = CGRectMake(100, 400, 120, 40);
[weiter addTarget:self action:#selector(goToChart) forControlEvents:UIControlEventTouchUpInside];
NSString *ansicht = #"Weiter";
[weiter setTitle:ansicht forState:UIControlStateNormal];
[self.view addSubview:weiter];
// loading images into the queue
loadImagesOperationQueue = [[NSOperationQueue alloc] init];
NSString *imageName;
for (int i=0; i < 10; i++) {
imageName = [[NSString alloc] initWithFormat:#"cover_%d.jpg", i];
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
UIImage *aktuellesImage = imageView.image;
UIImage *scaledImage = [aktuellesImage scaleToSize:CGSizeMake(100.0f, 100.0f)];
[(AFOpenFlowView *)self.view setImage:scaledImage forIndex:i];
[imageName release];
NSLog(#"%d is the index",i);
}
[(AFOpenFlowView *)self.view setNumberOfImages:10];
}
So you can see there 10 Images in this CoverFlowView, but how could i find out the ACTUAL picture that is in front, to use this in another view??
Could someone help me, please?
Greetings Marco
-(void)openFlowView: (AFOpenFlowView *)openFlowView imageSelected:(int)index
{
AppDelegate_iPhone *appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication]delegate];
db_detail = (DB_data *)[self.GalleryArray objectAtIndex:index];
appDelegate.Id = db_detail.Id;
// NSLog(#"id: value is %d",db_detail.Id);
// NSLog(#"Name vlaue is: %#",db_detail.Name);
appDelegate.title = db_detail.Name;
DetailMovieViewController *ViewController = [[DetailMovieViewController alloc]init];
[self.navigationController pushViewController:ViewController animated:YES ];
[ViewController release];
[db_detail release];
}

Resources