Alright, so I've been toying around with this for a couple days now and I haven't gotten this to work, looking to you for help!
Basically I want to "Unlock" a feature once an IAP is done. I've got the IAP code to work, but I want to change the button "sendMail" ('disabled' in Interface Builder) so that the user can interact with it.
//InputViewController.h
#import "IAPStore.h"
#interface InputViewController : UIViewController <MFMailComposeViewControllerDelegate, UIAlertViewDelegate>
#property(strong,nonatomic)IBOutlet UIButton *sendMail;
-(void)enableMail;
....
#end
//InputViewController.m
#import "InputViewController.h"
#import "IAPStore.h"
-(void)enableMail
{
[_sendMail setEnabled:YES];
NSLog(#"Unlocking Button");
}
//IAPStore.h
#import "InputViewController.h"
#interface IAPHelper : NSObject <UIAlertViewDelegate>
-(void)purchaseComplete;
...
#end
//IAPStore.m
#import "InputViewController.h"
-(void)purchaseComplete
{
UIAlertView *purchased = [[UIAlertView alloc]initWithTitle:#"In-App Purchase" message:#"Purchase complete! Thank you!" delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil];
GROWInputViewController *viewController = [[GROWInputViewController alloc] init];
[viewController enableMail];
[purchased show];
NSLog(#"button enabled");
}
So it prints out too the log but nothing is changed on the other view controller, but nothing is changed, any idea to what I'm doing wrong?
You could use NSNotificationCenter
In the viewDidLoad: method of InputViewController.m add this line of code:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(enableMail) name:#"purchaseCompleteNotification" object:nil];
And in the purchaseComplete method of IAPStore.m, replace this:
GROWInputViewController *viewController = [[GROWInputViewController alloc] init];
[viewController enableMail];
with this:
[[NSNotificationCenter defaultCenter] postNotificationName:#"purchaseCompleteNotification" object:nil];
This will cause a notification to be posted when the purchase is complete. Meanwhile, InputViewController has an 'observer' that is set to call your 'enableMail' method when that notification is posted.
Also, you'll want to add this method to your InputViewController.m, so that he is removed as an observer when deallocated.
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"purchaseCompleteNotification" object:nil];
}
Related
I would like to refresh a UIWebView whenever my app comes to the foreground. All I really have in my ViewController.m is a method that checks for internet access (hasInternet) and viewDidLoad.
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize webview;
-(BOOL)hasInternet{
Reachability *reach = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStats = [reach currentReachabilityStatus];
if (internetStats == NotReachable) {
UIAlertView *alertOne = [[UIAlertView alloc] initWithTitle:#"You're not connected to the internet." message:#"Please connect to the internet and restart the app." delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alertOne show];
}
return YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self hasInternet];
[webView loadRequest: [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://warm-chamber-7399.herokuapp.com/"]] ];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Any advice on how to enable this functionality? Does it go in AppDelegate or do I create another method within ViewController.m?
You should register a UIApplicationWillEnterForegroundNotification in your ViewController's viewDidLoad method and whenever app comes back from background you can do whatever you want to do in the method registered for notification. ViewController's viewWillAppear or viewDidAppear won't be called when app comes back from background to foreground.
-(void)viewDidLoad{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doYourStuff)
name:UIApplicationWillEnterForegroundNotification object:nil];
}
-(void)doYourStuff{
[webview reload];
}
Don't forget to unregister the notification you are registered for.
-(void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Note if you register your viewController for UIApplicationDidBecomeActiveNotification then your method would be called everytime your app becomes active, It would not be appropriate to register for this notification.
Register for the UIApplicationDidBecomeActiveNotification or the UIApplicationWillEnterForegroundNotification.
I like to show the latest Push Notification in a label in my main StoryBoard I use this code to display the alert message in my AppDelegate.m:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSDictionary *test =(NSDictionary *)[userInfo objectForKey:#"aps"];
NSString *alertString =(NSString *) [test objectForKey:#"alert"];
NSLog(#"String recieved: %#",alertString);
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alertmessage=[[UIAlertView alloc]initWithTitle:#"Geier"
message:alertString delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertmessage show];
AudioServicesPlaySystemSound(1002);
}
}
i tried this in my ViewController.m file latestpush.text = #"%#",alertString; but it doesn't work.
Can someone help me?
Thanks:)
You need to make the text available to the view controller.
You could do this by sending a custom NSNotification with the alert message, from inside application:didReceiveRemoteNotification:
[[NSNotificationCenter defaultCenter]
postNotificationName:#"PushAlertNotification"
object:self
userInfo:#{#"alertString":alertString}];
In your view controller's viewDidLoad method, register as an observer:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(updateStoryboard:)
name:#"PushAlertNotification"
object:nil];
and create the updateStoryboard: method in the view controller:
- (void) updateStoryboard:(NSNotification *) notification {
self.latestpush.text = notification.userInfo[#"alertString"];
}
An alternative solution is to create a property in your AppDelegate that takes in the ViewController as an observer.
AppDelegate.h (change ViewController to the actual type of your VC).
#property (nonatomic, weak) ViewController *observer;
Inside the ViewController create a method that accepts the NSString and have that method update your Storyboard.
ViewController.m
-(void)updateStoryboard(NSString *alertString) {
self.latestpush.text = alertString;
}
Also, in your ViewContoller's viewDidLoad method, register yourself with the appDelegate:
- (void)viewDidLoad {
[super viewDidLoad];
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
delegate.observer = self;
}
Call updateStoryboard inside your application:didReceiveRemoteNotification: method:
[self.observer updateStoryboard:alertString];
I have a selector to show UIAlertView asking user if want to retry upload images after NotificationCenter post a notification with observename.
[[NSNotificationCenter defaultCenter] postNotificationName:kNOTIFICATION_PHOTOS_UPLOAD_RETRY object:nil];
But because of the notification received more than one, so will show as many as notifications received. Is there a best practice to show alert view only once?
Yeah, you can do something like:
#interface MyClass
{
UIAlertView *_myAlertView;
}
#end
#implementation MyClass
...
- (void)myNotificationSelector:(NSNotification *)notification
{
if (!_myAlertView) {
_myAlertView = [[UIAlertView alloc] init ...]
_myAlertView.delegate = self;
[_myAlertView show];
}
}
...
#end
and in the UIAlertViewDelegate handlers, just release and set _myAlertView to NO.
I'm trying to present a Modal View Controller when the app enters in foreground.. These are my files:
AppDelegate.m :
#import "AppDelegate.h"
#import "MainViewController.h"
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[self.window makeKeyAndVisible];
MainViewController * vc = [[MainViewController alloc]init];
[vc myMethodHere];
}
MainViewController.h :
//[..]
-(void) myMethodHere;
MainViewController.m :
-(void)myMethodHere{
NSLog(#"myMethodHere Activated.");
TWTweetComposeViewController *tweetViewController = [[TWTweetComposeViewController alloc] init];
[self presentModalViewController:tweetViewController animated:YES];
}
NSLog(#"myMethodHere Activated.") works.. so I can't understand why "presentModalViewController" doesn't! What should I edit/add? Maybe a delay? Thanks for your help..
p.s. I know my english sucks.. Forgive me :)
I wouldn't rely on the methods in your app delegate for this (even though it seems like the obvious solution) because it creates unnecessary coupling between your application delegate and the view controller. Instead, you can have MainViewController listen for the UIApplicationDidBecomeActive notification, and present the tweet composer view controller in response to this notification.
First, register for the notification in -viewDidLoad.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMethodHere) name:UIApplicationDidBecomeActiveNotification object:nil];
}
Now, when this notification is received when your app returns from the background, myMethodHere will be invoked.
Lastly, remember to remove yourself as an observer when the view unloads.
- (void)viewDidUnload
{
[super viewDidUnload];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
I'm in a UITableView and the user has watched a video. After the video I would like the user to take a test. Just can't figure out how to call this view controller so I can start the test.
Im in the PlayListViewController and want to call the TestViewController.
The TestViewController.h is imported. At this stage all there is in the TestViewController is what comes with UIViewController and some stuff that I added in .xib. The test coding isn't done yet (that will be the next problem).
I would greatly appreciate if someone has the time to give me directions.
-(void) movieFinishedPlaying: (NSNotification *) note {
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:[player moviePlayer]];
[player release];
NSLog(#"Video has finished playing\n");
// To the test
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Info"
message:#"Now for the test!"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
[alert release];
// Call on test here
TestViewController *testVC = [[TestViewController alloc] init];
[self presentModalViewController:testVC animated:YES];
[testVC release];
}
I have this in the TestViewController.h
#import <UIKit/UIKit.h>
#interface TestViewController : UIViewController {
UIWindow *tVC;
UIViewController *testVC;
}
#property (nonatomic, retain) IBOutlet UIWindow *tVC;
#property (nonatomic, retain) IBOutlet UIViewController *testVC;
#end
And this in the m file
#import "TestViewController.h"
#implementation TestViewController
#synthesize testVC, tVC;
Register for MPMoviePlayerPlaybackDidFinishNotification notification before playing video (I guess you are using MPMoviePlayerController to play video, right?):
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playerPlaybackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:playerViewController];
and when it get's fired, present him the instance of TestViewController modally and unregister the notification:
- (void)playerPlaybackDidFinish:(NSNotification*)notification
{
TestViewController *testVC = [[TestViewController alloc] init];
[self presentModalViewController:testVC animated:YES];
[testVC release];
[[NSNotification defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:playerViewController];
}
presentModalViewController is deprecated in ios 6 so now it is
ViewController *vc = [[ViewController alloc]init];
[self presentViewController:vc animated:YES completion:NULL];