How can we make the "please leave us a review in the app store" functional PopUp in an iOS app?
It's quite easy. Create an action rateGame and change the id 409954448 to your app id.
- (IBAction)rateGame {
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString:#"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=409954448"]];
}
This will launch the AppStore app and take the user directly to the page where s/he can rate and review your app. If you want this to happen after, say, 20 times the user loads your app, then you can add an alert in viewDidLoad of your main page:
- (void)viewDidLoad {
[super viewDidLoad];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSInteger launchCount = [prefs integerForKey:#"launchCount"];
if (launchCount == 20) {
launchCount++;
[prefs setInteger:launchCount forKey:#"launchCount"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"LIKE MY APP?"
message:#"Please rate it on the App Store!"
delegate:self
cancelButtonTitle:#"NO THANKS"
otherButtonTitles:#"RATE NOW", nil];
[alert show];
[alert release];
}
}
This assumes you've set up the launchCount in the AppDelegate:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSInteger launchCount = [prefs integerForKey:#"launchCount"];
launchCount++;
[prefs setInteger:launchCount forKey:#"launchCount"];
// YOUR CODE HERE
}
I personally used this one. I think it works really well. http://arashpayan.com/blog/2009/09/07/presenting-appirater/
There is code missing if you want user to review your app after 20 times. The missing part is
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
// user hit dismiss so don't do anything
}
else if (buttonIndex == 1) //review the app
{
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString:#"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=409954448"]];
}
}
Well, here's one.
These are usually done as simple UIAlertViews with three buttons (Review Now, Later, Never) with preferences stored in NSUserDefaults to indicate whether the user has already done so, whether they never wish to be asked again, etc.
iRate is also another good library to present "rate this app" dialog boxes.
Since iOS 10.3 iOS provides a feature for this.
import StoreKit
SKStoreReviewController.requestReview()
A complete class how to request Appstore Reviews can be found on my GitHubAccount.
Cheers!
Related
The below code is working but has a bug. The scenario is that, I begin by logging in to enter the app system. Once the login has succeeded, the app will set UserDefaults (UserId). After that, I can navigate the app views with stored UserId. Once I go to settings and tab logout, that will clean UserId and go to login view.
The BUG: When I login again to the app and click the home button to go to iPhone desktop and close the app, and return to open it again it still storing the UserId. So, if I go to the setting and log out that will clean UserId and will not go to login view. I don't know why.
The code:
- (IBAction)resetKeychain:(id)sender {
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:#"Are you sure you want to logout?"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Logout"
otherButtonTitles:nil];
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
[actionSheet showFromTabBar:self.tabBarController.tabBar];
[actionSheet release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex ==0) {
//logout
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
//delete user ID fro user Defaults
[defaults setObject:nil forKey:#"UserId"];
//redirect to login view
NewClassMoonAppDelegate * appsDelegate =[[UIApplication sharedApplication] delegate];
[appsDelegate.window addSubview:[appsDelegate.login view]];
}
}
From what I can interpret from you question, which needs to be formatted and made coherent by the way, I believe that:
a) your #"UserID" value is not syncing with NSUserDefaults because you are not calling the -synchronize method. NSUserDefaults will update its in-memory key-value store, but will not write it to disk meaning that it's lost at an arbitrary time.
b) The fact that it is not going to the loginView could be to do with any few reasons, most likely that it is already a subview of your UIWindow. So, instead of reusing the login property in your app delegate, create a new instance variable of the View Controller, and set that as the rootViewController instead.
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:nil forKey:#"UserId"];
[defaults synchronize];
//redirect to login view
NewClassMoonAppDelegate * appsDelegate =[[UIApplication sharedApplication] delegate];
LoginViewController *login = [[LoginViewController alloc] initWithNibName...];
[appsDelegate.window setRootViewController:nil];
[appsDelegate.window setRootViewController:login];
}
}
Swift:
From max_'s answer with some changes:
let objectsToSave: [String] = [obj1, obj2, obj3]
for key in objectsToSave {
NSUserDefaults.standardUserDefaults().removeObjectForKey(key)
}
let appsDelegate = UIApplication.sharedApplication().delegate
let storyboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
let newLoginVC: LoginViewController = storyboard.instantiateInitialViewController() as! LoginViewController
appsDelegate?.window!!.rootViewController = nil
appsDelegate?.window!!.rootViewController = newLoginVC
EDIT: The only changes I've made are just that I initialize newLoginVC through Storyboards instead of initWitName.
Make property of UINavigation controller and synthesize it, And write below code on logout button
AppDelegate * appDelegateObj =[[UIApplication sharedApplication] delegate];
login *loginObj = [[login alloc]initWithNibName:#"login" bundle:nil];
[appDelegateObj.window setRootViewController:nil];
navObj=[[UINavigationController alloc]initWithRootViewController:loginObj];
[appDelegateObj.window setRootViewController:navObj];
Well the title is self explained. I want to create an App that can manage programmed local notifications when App is in background mode. Notifications works smoothly but I want to fire a custom method when the alert is fired.
Is it possible?
Thank you.
Yes it can be done. You can do somethng like this:
- (void)applicationDidEnterBackground:(UIApplication *)application {
[NSTimer scheduledTimerWithTimeInterval:17.0 target:self selector:#selector(makeNotificationRequest:) userInfo:nil repeats:YES];
}
-(void)makeNotificationRequest:(NSTimer *)timer
{
CLLocation *location = [[AppHelper appDelegate] mLatestLocation];
NSMutableDictionary *paramDic = [[NSMutableDictionary alloc] init];
#ifdef _DEBUG
[paramDic setValue:[NSString stringWithFormat:#"77.586"] forKey:#"Lat"];
[paramDic setValue:[NSString stringWithFormat:#"12.994"] forKey:#"long"];
#else
[paramDic setValue:[NSString stringWithFormat:#"%f",location.coordinate.latitude] forKey:#"Lat"];
[paramDic setValue:[NSString stringWithFormat:#"%f",location.coordinate.longitude] forKey:#"long"];
#endif
WNetwork *mNetwork = [[WNetwork alloc] init];
[mNetwork makeRequsetWithURL:URL_Showbeeps type:JBJsonParser paramDictionary:paramDic delegate:self];
[mNetwork autorelease];
NSLog(#"URL HIT%#",paramDic);
[paramDic autorelease];
}
And to customize your action on alert you can use this:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
;
}
}
If the app were in the foreground then you would want the - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification method of UIApplicationDelegate, however the documentation suggests that this will not be called when the app is in the background.
You can get a list of local notifications by calling scheduledLocalNotifications on your UIApplication instance - you can then poll these for their times and schedule a function to call at that time in your background mode. This won't necessarily 100% match up with when the Local Notification fires though, but I think it's as close as the App Store guidelines will let you get.
You can also present your own Local Notifications when you are in background mode by calling the presentLocalNotificationNow: method:
https://developer.apple.com/library/IOS/#documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/presentLocalNotificationNow:
so you could work around this by just presenting your own notifications and not scheduling them for the OS to deliver.
If you are trying to access Local Notifications from other applications then I don't think this is allowed.
No ..no custom methods are defined while app is running in background..Once an notification is fired we can;t change the alert message also. But nice when we show the alert message then by clicking the yes button to the alert take you to the one method called app is Running in Background which is in AppDelegate.m file
I'm trying to play an intro movie when my app is getting launch, but am totally driven crazy already, I did a lot of testing in my code, along with trying to use this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
NSLog(#"App started to launch");
[self.window makeKeyAndVisible];
[self.window addSubview:_intro.view];
return YES;
}
but that's make my video run, even if I'm coming from the background.
If like pressing the middle button, then double pressing the middle button and pressing app icon, I get the movie to play again.
I forget to mention that this is my ViewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL launchedBefore = [userDefaults boolForKey:#"hasRunBefore"];
NSLog(#"value of hasRunBefore is %d",launchedBefore);
if(!launchedBefore)
{
[userDefaults setBool:1 forKey:#"hasRunBefore"];
launchedBefore = [userDefaults boolForKey:#"hasRunBefore"];
NSLog(#"value of hasRunBefore is %d",launchedBefore);
[self playvideo];
}
}
NSUserDefaults does not commit the changes to disk until you send the synchronize message.
Try adding doing this:
[userDefaults setBool:YES forKey:#"hasRunBefore"];
[userDefaults synchronize];
I need a registration page in my application which should appear only at the first launch of the application.
Look into:
NSUserDefaults (for saving and loading the registered info) - https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html
Modal view controllers (for showing the page) -- http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html
Use NSUserDefaults to save the registered info, and at startup, check if that information exists. If it doesn't, show the registration controller and save the info. That way it will only appear once.
A kind soul might do a lot of guesswork about your set up and write a clearer answer, or you could update your question telling us how you have tried to implement this yourself, and how you failed doing so because of [insert reason], and how you would love some hints on that.
Use NSUserDefaults in the viewDidLoad method of my main screen. So every time the app starts and the main screen loads, it checks if its the user's first time.
This is how I do it in my app:
- (void)viewDidLoad {
BOOL tempBOOL = [[NSUserDefaults standardUserDefaults] boolForKey:#"hasSeenOpeningAlert"];
if (!tempBOOL) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Welcome To My App" message:#"This app will ... First you need to ..." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
[super viewDidLoad];
}
and then:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
Edit *editViewController = [[[Edit alloc] initWithNibName:#"Edit" bundle:nil]retain];
[self.navigationController presentModalViewController:editViewController animated:YES];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"hasSeenOpeningAlert"];
[[NSUserDefaults standardUserDefaults] synchronize];
[editViewController release];
}
I have recently begun my studies on iOS development so forgive me if I am asking something too obvious.
When my application's view loads it checks the configurations for some keys and if there's no value for these keys the application should display an alert and quit.
First of all, I have implemented the UIAlertViewDelegate:
#interface FirstViewController : UIViewController <UIAlertViewDelegate> {
...
And then checked for the settings:
- (void)viewDidLoad {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *url = [defaults stringForKey:#"url"];
NSString *apiKey = [defaults stringForKey:#"api-key"];
if([url length] < 1 || [apiKey length] < 1){
UIAlertView *dialog = [[[UIAlertView alloc]
initWithTitle:#"Not properly configured"
message:#"This application was not properly configured. Please configure the application on your iPhone settings."
delegate:self
cancelButtonTitle:#"Close"
otherButtonTitles:nil]
autorelease];
[dialog setTag:1];
[dialog show];
}
[url release];
[apiKey release];
[super viewDidLoad];
}
I understand that the method alertView didDismissWithButtomIndex should be called after the alertView's dismiss but for some reason this method is never called in my code.
- (void)alertView:(UIAlertView *)alertView didDismissWithButtomIndex:(NSInteger)buttomIndex {
if([alertView tag] == 1){
exit(0);
}
}
Any ideas on why this is happening?
didDismissWithButtonIndex is misspelled, you snuck an ‘m’ in there instead of ’n’.
You are listening for the wrong method, you should implement :
alertView:clickedButtonAtIndex:
In the doc you can read that the didDismissWithButtomIndex is called when dismissWithClickedButtonIndex:animated: is called on the alertView.
alertView:didDismissWithButtonIndex:
Sent to the delegate after an alert view is dismissed from the screen.
So for your code to work you should implementsomething like :
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == ...) {
// do something
}
}
PS: You shouldn't call exit(0), it is a bad practice on iOS to force an application to quit. User are supposed to quit the app with the home button.