Objective C - SLComposeViewController delayed presention - objective-c

I've been doing a program which takes care of posting a picture or words (or both) to both facebook and twitter. But I want to do them both at the same time, so I wrote my code like this:
//POST TO FACEBOOK
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
slcvc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[slcvc addImage:bim];
[slcvc setInitialText:tf.text];
[self presentViewController:slcvc animated:YES completion:NULL];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Facebook - not logged in!" message:#"You need to login (or sign up) to successfully post..." delegate:nil cancelButtonTitle:#"Too bad!" otherButtonTitles:nil];
[alert show];
}
//POST TO TWITTER
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
slcvc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[slcvc addImage:bim];
[slcvc setInitialText:tf.text];
[self presentViewController:slcvc animated:YES completion:NULL];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Twitter - not logged in!" message:#"You need to login (or sign up) to successfully post..." delegate:nil cancelButtonTitle:#"Too bad!" otherButtonTitles:nil];
[alert show];
}
This is all of course, in an IBAction function that is "file owned" already (slcvc is the SLComposeViewController, bim is an UIImage, and tf.text is the text of the UITextfield tf). And I have posted with this code before, only that it worked separately. If I try to use this to post a picture to Facebook and Twitter at the same time, I get this error:
Attempt to present <SLTwitterComposeViewController: 0xf6265e0> on <ViewController: 0x9476960> which is waiting for a delayed presention of <SLFacebookComposeViewController: 0x9432d70> to complete
(I'm still allowed to post to Facebook but not to Twitter)
I'm sure this happens because the SLComposeViewController registers itself as free to operate again once the first posting (the one for Facebook in this case) is done. So is there a way to have the second posting (the one for Twitter) to wait somehow for the user to send the first posting (to Facebook) and then to present the posting for Twitter? Thanks to anyone in advance for any help or suggestions!!

You will need to use the completion handler of the SLComposeViewController. This is called after user is done composing the post or cancelling it:
[slcvc setCompletionHandler:^(SLComposeViewControllerResult result) {
//POST TO TWITTER
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
slcvc2 = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[slcvc2 addImage:bim];
[slcvc2 setInitialText:tf.text];
[self presentViewController:slcvc animated:YES completion:NULL];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Twitter - not logged in!" message:#"You need to login (or sign up) to successfully post..." delegate:nil cancelButtonTitle:#"Too bad!" otherButtonTitles:nil];
[alert show];
}
}

Just try following thing.
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self presentViewController:fbViewController animated:YES completion:nil];
}];

Related

locking tab bar items and unlocking via login page

Hey guys having trouble with the UI tab controller,
So I have a login screen as my first controller I was wondering if there is a way to lock tab bar items and then unlocking them after login is successful?
At the moment I'm using NSDictionary to store my username and passwords and an UIAlertView for alerting whether the login is successful or not, but there really is no point of a login if tabs are accessible without the logging in.
below is my current code for logging in
- (IBAction)loginNow {
if ([[credentialsDictionary objectForKey:usernameField.text]isEqualToString:passwordField.text]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Correct" message:#"You have successfully logged in." delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
usernameField.hidden = YES;
passwordField.hidden = YES;
goButton.hidden = YES;
welcomeField.hidden = NO;
nameField.hidden = NO;
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"You have entered an incorrect Username or Password" message:#"Please try again." delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
}
}
You can use the tabBarController:shouldSelectViewController: method in UITabBarControllerDelegate protocol to return NO for tabs which should be inaccessible.
Set the relevant object (probably your main view controller) as the delegate of the tab bar, and implement the above method, returning NO when the user is not logged in and tries to access a tab which they should not have access to.

UIActionSheet pass touches through?

I'm looking to use a UIActionSheet kind of like a contextual message box (with no action buttons at all and just a label in the bubble with an arrow pointing at something). Since there are no actions the user can take, I would like it to not require a tap to dismiss, but I can't see any way (such as a passthroughViews property) to allow this.
It's probably not designed for this, but it does happen to be handy for it.
This is some example code of how to show an UIAlertView and dismiss it automatically.
Show it:
- (void)show
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"title"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
alert.tag = tag;
[alert show];
}
Dismiss it:
- (void)dismiss
{
for (UIWindow* w in [UIApplication sharedApplication].windows)
for (NSObject* o in w.subviews)
if ([o isKindOfClass:[UIAlertView class]]) {
UIAlertView *alert = (UIAlertView*) o;
if (alert.tag == tag)
[alert dismissWithClickedButtonIndex:[(UIAlertView*)o cancelButtonIndex] animated:YES];
}
}
Yo can call the dismiss method after a couple of seconds:
[self performSelector:#selector(dismiss) withObject:nil afterDelay:1.0 inModes:nil];

MFMailComposeViewController won't dismiss on iOS 6

In iOS 6 the presented MFMailComposeViewController will not dismiss if user attempts to send second email...
Everything works perfectly the first go around and email is sent. However, if email option is selected again the MFMailComposeViewController will not dismiss on cancel.
Here is how I implemented it:
- (IBAction)buttonEmailClick:(id)sender {
if (![MFMailComposeViewController canSendMail]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Can't send" message:#"This device is unable to send emails." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return;
}
NSDictionary *contactsInfo = [self contactsInfoFromPlistNamed:kConfigPlistName];
[mailComposeViewController setToRecipients:[NSArray arrayWithObject:[contactsInfo objectForKey:#"email"]]];
//[mailComposeViewController setSubject:kEmailDefaultSubject];
//[mailComposeViewController setMessageBody:text isHTML:NO];
[self presentModalViewController:mailComposeViewController animated:YES];
}
and then this:
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
UIAlertView *alert = nil;
if (result == MFMailComposeResultSent) {
alert = [[UIAlertView alloc] initWithTitle:#"Sent" message:#"Your email was sent." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
}
else if (result == MFMailComposeResultFailed) {
alert = [[UIAlertView alloc] initWithTitle:#"Failed" message:#"An error occured and your email was not sent." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
}
[alert show];
[self dismissModalViewControllerAnimated:YES];
}
It works fine in iOS 5 but not in iOS 6. I have tried replacing with non deprecated methods for iOS 6, but it doesn't work.
Have you tried creating a fresh MFMailComposeViewController each time they go to send an email? I'm not sure if you should be reusing it.
You can try this:
MFMailComposeViewController * composer = [[MFMailComposeViewController alloc] init];
composer.delegate = self;
-(void)mailComposeController:didFinishWithResult:error: should be called if you assign that class to the delegate

UIAlertView without any buttons

I wanted to know whether the following code is okay or not. I am trying to dismiss the alertView automatically after 2 seconds (and without any buttons in the alertView) from the "timedAlert" method.
//this is in another method
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Login successful." delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
[alert show];
[alert release];
[self timedAlert];
}
-(void)timedAlert
{
[self performSelector:#selector(dismissAlert:) withObject:alert afterDelay:2];
}
-(void)dismissAlert:(UIAlertView *) alertView
{
[alertView dismissWithClickedButtonIndex:nil animated:YES];
}
If the cancelButton of the alertView is set to "nil", how will the "[alertView dismissWithClickedButtonIndex:0 animated:YES];" thing work??? I tried making the cancelButton "nil" and it worked, but cant figure out how....
P.S: I call the timedAlert method from another
Any help is appreciated! Thank you!
First let me say it would be better if you handle this with a custom view, but with that said the problem looks to be with
[alert release];
You are releasing the object before you are done with it (I am surprise it does not crash).
Do something like this
// other code
alert = [[UIAlertView alloc] initWithTitle:nil message:#"Login successful." delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
[alert show];
[self performSelector:#selector(dismissAlert:) withObject:alert afterDelay:3.0f];
}
-(void)dismissAlert:(UIAlertView *) alertView
{
[alertView dismissWithClickedButtonIndex:nil animated:YES];
[alertView release];
}
Your code should work, and you should have no problems. I have done this in one of my previous apps. The button is not displayed because the title is nil but I think the instance of the button still exists. Put a breakpoint before closing your alert and take a look at the alert variable, and check to see if there is a buttons array or something, that should tell you how that works.

Trying to Integrate Mail Into my app, getting 2 warnings

I'm trying to integrate sending mail into my app, but I end up with 2 warnings. I am using Obj-C, the Cocos2d Framework. This is my code.
-(void) mailTapped: (id) sender {
MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];
composer.mailComposeDelegate = self;
if ([MFMailComposeViewController canSendMail]) {
[composer setToRecipients:[NSArray arrayWithObjects:#"", nil]];
[composer setSubject:#"Check Out This Awesome App!"];
[composer setMessageBody:#"I found this great game on the App Store! It's called Mole Attack. It's a side scroller with an epic story. You can check out some screenshots of the gameplay and download it here. Download link - " isHTML:NO]; //Include link and pics
[self presentModalViewController:composer animated:YES]; // <--- warning - GameOver (name of class) may not respond to '-presentModalViewController:animated:'
}
}
-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissModalViewControllerAnimated:YES]; // <--- warning - GameOver may not respond to '-dismissModalViewControllerAnimated:YES'
if (result == MFMailComposeResultFailed) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Failed" message:#"The email was not sent. You must be in wifi or 3G range. Try again later." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
Thanks in advance!
Are you sure your GameOver class is inheriting from UIViewController? That's the class that defines the two methods that you're getting warnings about.