NSUserDefaults and alertView - ios

I am creating a Disclaimer that will be shown when the user first launches the app. The disclaimer is an alertView with 2 option. If user agrees then firstViewController will display. If he doesn't he will be redirected to another viewController. But I can't get the disclaimer to disappear if the user agrees the first time. It is shown every time the app launches. Any help would be appreciated. Thank you in advance..
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![[defaults valueForKey:#"keyDisclaimer"] isEqualToString:#"accepted"]) {
UIAlertView *disclaimer = [[UIAlertView alloc] initWithTitle:#"Read Before use" message:#"By using this app you agree to its terms and conditions.\n\n\n\n\n\n\n\n\n\n\ntext heren\n\n\n\n\n\n\n\n\n\n\n\n\n" delegate:self cancelButtonTitle:#"No!" otherButtonTitles:#"Yes Let me In", nil];
[disclaimer show];
}
// Override point for customization after application launch.
return YES;
}
-(void) alertView:(UIAlertView *) alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSString *buttonString = {[alertView buttonTitleAtIndex:buttonIndex]};
if ([buttonString isEqualToString:#"Yes Let me In"]) {
NSMutableDictionary* defaultValues = [NSMutableDictionary dictionary];
[defaultValues setValue:#"accepted"forKey:#"keyDisclaimer"];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
}
else if ([buttonString isEqualToString:#"No!"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Sorry!" message:#"You are not allowed to use this app due to the fact that you did not agree to the terms and Conditions. Please exit this app!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
// [[NSUserDefaults standardUserDefaults] setValue:#"notAccepted" forKey:#"keyDisclaimer"];
}
if ([buttonString isEqualToString:#"OK"]) {
introViewController *intro = [[introViewController alloc] initWithNibName:#"introViewController" bundle:nil];
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_window.rootViewController = intro;
[_window makeKeyAndVisible];
}
}

NSMutableDictionary* defaultValues = [NSMutableDictionary dictionary];
[defaultValues setValue:...forKey:...]
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultValues];
This will register your defaults if they are not set (for the first time)
Also, seems like you're forgetting [defaults synchronize] to commit changes after setting values. If so, you don't need the registerDefaults method at all.
Like this:
if ([buttonString isEqualToString:#"Yes Let me In"]) {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:#"accepted"forKey:#"keyDisclaimer"];
[defaults synchronize];
}

You want to use something like stringForKey or objectForKey instead of valueForKey.
if([[defaults stringForKey:#"keyDisclaimer"] isEqualToString:#"accepted"]) {
I've had bad experiences with valueForKey in the past not always working the way I want. That might be what's causing you some problems.

Related

Youtube videos failed to upload after upgrading to xcode7

- (void)uploadTicket:(GDataServiceTicket *)ticket
finishedWithEntry:(GDataEntryYouTubeVideo *)videoEntry
error:(NSError *)error
{
NSLog(#"ticket");
UIButton *uploadButton = (UIButton *)[backgroundImage viewWithTag:10];
UIButton *cancleButton = (UIButton *)[backgroundImage viewWithTag:20];
if (error == nil)
{
// tell the user that the add worked
NSLog(#"Video Successfully Uploaded to Youtube");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber *uploadedToYouTube = [defaults objectForKey:#"uploadedToYouTube"];
if(nil == uploadedToYouTube)
{
[defaults setObject:[NSNumber numberWithBool:YES] forKey:#"uploadedToYouTube"];
[defaults synchronize];
}
NSNumber *userOpenedYoutubeView = [defaults objectForKey:#"userOpenedYoutubeToUnlockTheme"];
if(nil != userOpenedYoutubeView)
{
// [defaults setBool:NO forKey:#"Unlock_Theme"];
[defaults setObject:[NSNumber numberWithBool:NO] forKey:#"Unlock_Theme"];
[defaults synchronize];
UIAlertView *alrtView = [[UIAlertView alloc] initWithTitle:#"Congrats...!" message:#"Your new theme is Unlocked" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alrtView show];
[alrtView release];
[self removeFromSuperview];
}
else
{
UIAlertView *alrtView = [[UIAlertView alloc] initWithTitle:#"Success...!" message:#"Your Video is successfully uploaded to Youtube" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alrtView show];
[alrtView release];
[self removeFromSuperview];
}
}
else {
NSLog(#"Fails to upload Video to Youtube");
UIAlertView *alrtView = [[UIAlertView alloc] initWithTitle:#"Sorry" message:#"Fails to upload video to Youtube. Please try again" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alrtView show];
[alrtView release];
}
mProgressView . hidden = YES;
uploadButton . hidden = NO;
cancleButton . enabled = YES;
[mProgressView setProgress: 0.0];
[self setUploadTicket:nil];
}
Every time i try to upload it is showing alert message "failed to upload". I don't get why it is showing like that. Before upgrading to Xcode 7 it works fine. Anyone know please help me.

Saving a text from UIAlertView

I have written a UIAlertView code with a textField and I want to write a code to store whatever is typed by the user as a pushable detail list. How can I do that?
- (IBAction)NewReference:(id)sender {
UIAlertView *newreference = [[UIAlertView alloc] initWithTitle:#"New Reference" message:#"Enter Name" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles: #"Done",nil];
newreference.alertViewStyle = UIAlertViewStylePlainTextInput;
[newreference textFieldAtIndex:0].delegate = self;
[newreference show];
}
Here you go good sir. Per your comment above, if you want to store data for NSUserDefaults here is how you would do it:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString* saveData = [[newreference textFieldAtIndex:0] text];
[defaults setObject:saveData forKey:#"whatever key you want here"];
[defaults synchronize];
Then to invoke or call it:
NSString* recallData = [defaults objectForKey:#"whatever key you named above"];
Happy coding -

Displaying alert from app delegate before displaying alert from viewDidload

I am attempting to display the message contained within a push notification through the app delegate as outlined in the parse.com documentation.
The problem I am having is that in my viewdidload method for my first view controller, i am presenting an alert which the user MUST see before they use the app.
How can I call the method from my app delegate after the user sees the Alert from the viewdidload method?
EDIT:
So i have, as suggested in the comments, added a global Variable which i set to true once i have Displayed the alert from my ViewDidload method, but the Notification Alert from my appDelegate still does not appear.
here is my app delegate.m file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[Parse setApplicationId:#"xxxxxxxxxxxxxxxx"
clientKey:#"xxxxxxxxxxxx"];
// Register for Push Notitications, if running iOS 8
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
} else {
// Register for Push Notifications before iOS 8
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound)];
}
return YES;
NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if (Notification == true) {
if (![pushText isEqual: #""]) {
pushText = [[notificationPayload objectForKey:#"aps"] objectForKey:#"alert"];
UIAlertView *alert_news = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"News", "")
message:pushText
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert_news show];
}
}
}
And here is my viewdidload method:
RoadSafetyAppAppDelegate *AppDelegate;
- (void)viewDidLoad
{
AppDelegate = (RoadSafetyAppAppDelegate *)[[UIApplication sharedApplication] delegate];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
backgroundImage.alpha = 0.3;
toRecipients = [[NSArray alloc]initWithObjects:#"records#shellharbour.nsw.gov.au", nil];
static int appCounter;
if ( appCounter < 1 ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Disclaimer", "")
message:NSLocalizedString(#"Using a mobile phone whilst driving is against the law. Ensure that you are not behind the wheel when using this app.", "")
delegate:nil
cancelButtonTitle:#"I agree to not use a mobile phone while driving"
otherButtonTitles: nil];
[alert show];
appCounter = appCounter+1;
AppDelegate.NotificationAlert = #"1";
AppDelegate.Notification = true;
}
}
since you want to show the disclaimer ONE time and to be sure that the user saw it and TAPED on Agree Button before showing any notification. you can do that using a simple local notification.
in delegate (...didFinishLaunchingWithOptions:)
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//......you code here
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]==nil)
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"disclaimerShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//......you code here
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]){ //YES
if (![pushText isEqual: #""]) {
pushText = [[notificationPayload objectForKey:#"aps"] objectForKey:#"alert"];
UIAlertView *alert_news = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"News", "")
message:pushText
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert_news show];
}
}
}
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
NSString *value=[NSString stringWithFormat:#"%#",[notification.userInfo valueForKey:#"key"]];
if ([value isEqualToString:#"disclaimerShown"]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"disclaimerShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
///continue handle parse.com notification
}
}
in you ViewController:
-(void)viewDidLoad{
//...
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]==NO){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Disclaimer", "")
message:NSLocalizedString(#"Using a mobile phone whilst driving is against the law. Ensure that you are not behind the wheel when using this app.", "")
delegate:nil
cancelButtonTitle:#"I agree to not use a mobile phone while driving"
otherButtonTitles: nil];
alert.tag = 1;
[alert show];
}
//...
}
pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 1) {//the disclaimer alert
if (buttonIndex == 0) {
UILocalNotification *alarm = [[UILocalNotification alloc] init];
alarm.userInfo = #{#"key": #"disclaimerShown"};
alarm.fireDate = [NSDate date];
alarm.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:alarm];
}
}
}
Instead of AppDelegate bool flag property use NSUserDefaults;
In AppDelegate update this line from:
if (Notification == true)
to
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"Notification"] == YES)
And in ViewController -> viewDidLoad method update line from:
AppDelegate.Notification = true;
to
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"Notification"];
[[NSUserDefaults standardUserDefaults] synchronize];
Hope this helps.

Extremely Simple Saved High Score

The game that I am creating has a highScore integer variable that gets assigned when the player loses. I am using NSUsersDefaults class to save my high score. Here is my code that I am using:
-(void)saveScore {
[[NSUserDefaults standardUserDefaults] setInteger:score forKey:#"highScore"];
[defaults setInteger:score forKey:#"highScore"];
[defaults synchronize];
NSLog(#"High Score: %i ", highScore);
}
-(IBAction)buttonReleased:(id)sender {
[stopWatchTimer invalidate];
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
NSString *label0 = #"Hold to Start";
[labelText setText:label0];
if (score > 0) {
score--;
}
else {
score = 0;
NSLog(#"Changed score to 0");
}
if (score > highScore) {
[self saveScore];
NSString *scoreMessage =[[NSString alloc] initWithFormat:#"Congrats! You have a new High Score! Click Share High Score to share your score of: %i",score];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"High Score!" message:(NSString *)scoreMessage delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
score = 0;
}
else {
NSString *scoreMessage =[[NSString alloc] initWithFormat:#"Game Over! Your score was: %i",score];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"GAME OVER!" message:(NSString *)scoreMessage delegate:nil cancelButtonTitle:#"Try Again" otherButtonTitles: nil];
[alert show];
[alert release];
score = 0;
}
- (void)viewDidLoad
{
[super viewDidLoad];
int highscore = [[NSUserDefaults standardUserDefaults] integerForKey: #"highScore"];
[stopWatchTimer invalidate];
stopWatchTimer=nil;
}
I have been wrestling with this for HOURS! What am I doing wrong?! Note: Can you explain it as simply as possible.
Thanks!
-Matt
Reading it:
int highscore = [[NSUserDefaults standardUserDefaults] integerForKey: #"highScore"];
It will most likely be the default value of int (i.e. 0) when the file is blank.
Also don't forget to force a write of your defaults to "disk" with synchronize:
-(void)saveScore {
NSUSerDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:score forKey:#"highScore"];
[defaults synchronize];
}
You can load the highscore either in viewDidLoad or even in your init (or initWithNibName) method since this part isn't dependent on your view being loaded.
You could declare a property on your Scores view that you set in the viewDidLoad method. Alternatively you could expose the UILabel of that scores class (if that's what you use) as a property of your scores class.
- (void)viewDidLoad:
{
...
self.scoresView.textLabel.text = [NSString stringWithFormat:#"%d", highScore];
...
}
There is a really simple highscore management system which I have written it even has online support. You can find it https://github.com/faizanaziz/HighScore

UIActionSheet Controller crashed on iPad and Works Fine on iPhone

I've been trying to work a UIActionSheet into my App. The idea is, if you exited the app in a certain state, it would popup on launch and ask you if you'd like to continue or reset. Here's the code:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
continueYesNo = [prefs boolForKey:#"keyContinueMeeting"];
if (continueYesNo) {
NSString *message_continue = [[NSString alloc] initWithFormat:#"Do you want to Continue the Prior Meeting"];
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:message_continue
delegate:self
cancelButtonTitle:#"Reset"
destructiveButtonTitle:#"Continue"
otherButtonTitles:nil];
[actionSheet showInView:self.view];
[actionSheet release];
[message_continue release];
}
This is in viewDidLoad. And the actual Code action is:
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
Wasted_TimeAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if (buttonIndex != [actionSheet cancelButtonIndex]) {
delegate.continueMeeting = YES;
[prefs setBool:YES forKey:#"keyContinueMeeting"];
[ [NSUserDefaults standardUserDefaults] synchronize];
} else {
delegate.continueMeeting = NO;
[prefs setBool:NO forKey:#"keyContinueMeeting"];
[ [NSUserDefaults standardUserDefaults] synchronize];
}
}
It all seems pretty straight forward, but for some reason it runs on the iPhone with no problem but on the iPad the program crashes at this point.
Ok this one get's a big fat DOH! I had incorrectly implemented the iPad XIB, after redeveloping them this works as designed.

Resources