trying to make disclaimer view controller in iOS - ios

I want to display a view which contains the disclaimer for my app, only once. like, after you read it and press agree , never to show up again. when the app starts next time , jump straight to the next view in the storyboard (the login or whatever view). :( please explain the solution as detailed as possible because I'm new to iOS programming. thank you very much !
PS: I'm talking about ViewController for iOS in Xcode :)

First time try to read from NSUserDefaults and check if a property is there, if not show the view controller and set a property in user defaults as,
In didFinishLaunching delegate method,
NSString *myString = [[NSUserDefaults standardUserDefaults] stringForKey:#"DidShowDisclaimer"]
if ([myString iEqualToString:#"YES"]) {
//show the view controller and once they have accepted save this key
[[NSUserDefaults standardUserDefaults] setValue:#"YES" forKey:#"DidShowDisclaimer"];
[[NSUserDefaults standardUserDefaults] synchronize]; //next time when the app is launched it will never execute this if condition
}
So next time onwards, it would have been yes, and you never have to show again

You will need to store an NSUserDefault boolean to your app to know if your user accepted the user agreement or not.
So in terms of steps
1. app opens
2. check if boolean has been previously set
3. If not show them the agreement
4. If they agree then set the boolean to signify they've accepted and your check will always fail when the app is opened so you can skip the step.

Related

Carrying NSUserdefaults information from one viewcontroller to another view controller

I'm currently working on a simple app, one to really test my skills and understanding of xcode and app development. I'm still a beginner so it's primarily a learning tool as well as skill building. Either way, I'm trying to implement a simple login/register before going on to the next view controller screen with the login and register screen being separate and information stored in the app, not to pharse or icloud.
In ViewController1.m, i call for ViewController2.h:
#import "ViewController2.h"
This is also done in ViewController2.m for ViewController1.h.
In ViewController1.m i utilize NSUserDefaults as such:
NSUserDefaults *defaults = [NSUserDefaults standarUserDefaults];
[defaults setObject:_usernameField2.text forKey:#"username"];
[defaults setObject:_passwordField2.text forKey:#"password"];
[defaults setBool:YES forKey#"registered"];
[defaults synchronize];
When running the program and i am able to register the user and through segue command i'm able to go to the next view controller:
[self performSegueWithIdentifier:#"loginScreen" sender:self];
Ideally when I access the ViewController2 screen I want to use the information from the previous viewcontroller (ViewController1). However, when i attempt to use the information stored the program doesn't acknowledge the information from the previous viewController.
-(void) checkCredintials
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![_usernameField1.text isEqualToString:[defaults objectForKey:#"username"]] && ![_passwordField1.text isEqualToString:[defaults objectForKey:#"password"]])
I've tried other methods such as using NSString however I believe i'm either missing something simple or how i'm attempting to implement the code may be off. Part of me thinks it might be due to the fact that I am running and coding on a later version of xcode (4.6.3) but that's a minuet thought. I've done research and i've tried a few ways, just not sure what i'm missing or what i might need to add or change up. Any help would be much appreciated. Thank you in advance
Set a breakpoint or NSLog the values of the textfields and what is stored for the keys in defaults in checkCredintails method. Also just check that you're actually saving values for _usernameField2 and _passwordField2.
The way you save and retrieve data from NSUserDefaults looks fine, so the user enters(saves) they username and password in ViewController1 and enter it again in ViewController2 to get it verified? You probably shouldn't use NSUserDefaults to check/store passwords, but I guess you're just doing this as an example.

How to carry on In-App Purchase throughout whole app? (Remove ads from MULTIPLE views)

I have written my code for an In-App Purchase to remove ads and it works flawlessly, except, it only works on the view controller where I removed my ads from. I want it to carry over throughout my whole app. How would I do that?
Better understanding :
I have Ads on a few view controllers in my app. I have a Information view controller where you can purchase the removal of ads. The thing is : it does't carry over to my other views, as if I go back to the menu view controller. Also, when I go back into the Information view, it still has the ad until I restore from purchases. I don't want the users to continuously restore purchases. How do get this to work?
As #user523234 mentioned in the comments, you should be using a NSUserDefault to store a value that corresponds to the purchase of your IAP.
In this example we use NSUserDefaults to check if a key, removeAds, is true or false, YES or NO. The if statement will always be true until you set your key to YES. For more information on NSUserDefaults please refer to NSUserDefaults Class Reference.
// Create this globally
NSUserDefaults *defaults;
// Setup your NSUserDefaults in your viewDidLoad for example
defaults = [NSUserDefaults standardUserDefaults];
// Check If IAP Has Been Purchased
if (! [defaults boolForKey:#"removeAds"]) {
// NOT purchased
}
// Upon the successful purchase of your IAP you set the key to YES
[defaults setBool:YES forKey:#"removeAds"];
[[NSUserDefaults standardUserDefaults] synchronize]; // Save your changes
Daniel Storm's answer is correct. Below is the Swift equivalent:
let defaults = NSUserDefaults.standardUserDefaults()
if !defaults.boolForKey("removeAds") {
// Not Purchased.
}
// Upon the successful purchase of your IAP, you set the key to true.
defaults.setBool(true, forKey: "removeAds")
// Save your changes.
NSUserDefaults.standardUserDefaults().synchronize()
I would recommend touching up on Objective-C syntax so you can translate things like this yourself in the future. It's fairly simple, Amit. Mark Daniel's answer as correct.

How can I implement a "first time user registration" workflow in my Cocoa Touch app?

I'm implementing a "new user registration" in my app
The first time the user logs in, I'd like to have them complete a 4-step registration process to create their username, set their profile photo, etc.. Each step would be a different screen.
All this needs to be done just once. I was wondering -
What is the best setup for these 4 screens? Should they be a UINavigationController so that they are implemented as a "stack"? i.e. the user can go back to the previous screens?
How do I preserve the state of the registration? I'd like to know what step the user was on in case they leave halfway, or in general know whether I should display the registration (i.e. if this is their first time). Is there a way I can store the number of steps completed, so that if numStepsCompleted == 0 then I know they haven't started and if numStepsCompleted < 4 I know they have started but not finished?
In general, if there are any code examples online that implement something like this, it would be great to look at.
Thanks!
I would present a UINavigationController modally from you root view controller. One the user has finished you can do 2 things:
Save in NSUserDefaults the fact that the user has already complete the registration process. If the user delete the app, this flag will be removed with it.
Save personal information such username and password in the keychain, they will persist event after the remove of the application, that can be useful for silent login process and they are ciphered.
For the first point to can do something like that
+ (BOOL)isFirstTime{
static BOOL flag = NO;
static BOOL result;
if(!flag){
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"hasBeenLaunchedOnce"])
{
result = NO;
}
else
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"hasBeenLaunchedOnce"];
[[NSUserDefaults standardUserDefaults] synchronize];
result = YES;
}
flag = YES;
}
return result;
}
If this is the very first launch, show registration/login process, if not go along by taking username and password from keychain.
Save a value in NSUserDefaults to know which is the last completed step done by the user. As tou said, make a UINavigation to setup the four registration steps. When the app opens read the user defaults to know if the registration is finished.
There are a couple of different ways to implements this:
1. Use a UINavigationController
2. Use a UIPageViewController (which I like better)
3. Use a UITableView to contain all the information in one screen
To keep track of the registration info you should implement a RegistraionInfo class (or struct in Swift). Since there should only be one instance of it, you can create a singleton and access it from anywhere - RegistrationInfo.sharedInstance()
You can also create an instance in the first ViewController and pass it to the next one on prepareForSegue:.
The last part is to identify if the user already completed the Sign Up process. If you're using a Username/Password model then you should keep that info in the keychain and fetch it on launch.
Otherwise you can keep a value in NSUserDefaults.

NSUserDefaults standardUserDefaults objects are being removed randomly

I am facing a very weird behavior for NSUserDefaults, the problem is that [NSUserDefaults standardUserDefaults] objects are being removed randomly!
My [NSUserDefaults standardUserDefaults] contains around 65 objects(60 small NSStrings and 3 arrays which the maximum count could be 4 and 2 other arrays with maximum count 30..notice that it has never been the maximum case when facing this problem) , one of these objects is a value checking if the user has already completed the registration phase.
When launching the application, sometimes this NSUserDefaults will contain only 5 objects from those 65 and the others are being removed from the plist without appearing again even if i relaunch the app., which lead the user to the registration phase again!!
i am pretty sure that i am using the save function correctly
[[NSUserDefaults standardUserDefaults] setObject:#"Value" forKey:#"Key"];
[[NSUserDefaults standardUserDefaults] synchronize];
i have searched google for similar behavior without finding anything that can help!
Does anyone faced such behavior and what is the solution to fix it?
Thank you for any help
I do want to help out here, since I have had exact same strange behavior with one of my projects.
So bear with me, what happened to my project is that: I had a singleton class, which encapsulates several properties, and I had overridden setters and getters for those properties. In a setter method, I get standardUserDefaults instance and set object for key, and synchronize. In a getter method, I return the object of the key. Also I have a login success indicator value to indicate if login is successful. And same as your issue, my objects disappear. After few days of struggle, it turns out that the login indicator got initialized to false when Network became unreachable. And in the indicator false clause, I was setting nil objects to user defaults.
My points are:
Double check if standardUserDefaults setObject:forKey: function calls are logically correct, make sure the objects are NOT nil when call
Check if you have logic (login, Network change etc) that invalidates the objects.
Run tests, find the minimal steps to replicate the issue. Use Debug session to examine the objects. (Give up believing in Random Disappearing)
Hope this gives a lead.

iOS: How to Create a "User Preference" Feature

I have an application that is based on a UINavigationController; I wish to add a "Setting" page where the user will have the ability to set some features like Language and some other preferences.
Currently the UIViewController where I wish to have the Setting fields in is 2 levels under the RootViewController (i.e. there is a "main view" >> you click on a button and enter another UIViewController and form there you should be able to enter the Setting UIViewController).
I'm not clear about how I'm supposed to save this data and how to call it upon application load.
I read some blogs about NSUserDefaults and about Singleton but I'm not clear how should I use them.
Where should I create the data attributs that will later on maintain the user preferences? Should I create them on the AppDelegate or on the MySettingsViewController (the UIViewController that I'm creating)?
Should I use a Singleton attribute, and if so, where should it be created?
When you say "Singleton", do you actually mean creating a Static attribute?
Is there another way to communicate between 2 controllers that are not directly connected one to the other (I can transfer data from the "bottom" ViewController to the RootViewController passing it via the UIViewController in the middle, but it seems weird and ineffective)?
Any direction / tutorial will be appreciated!
Definitely use NSUserDefaults. It's great, and Apple recommends it.
To set a setting:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"Setting 1"];
You can also store other things, such as text, numbers, etc. Much more than a simple boolean.
To check the setting:
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"Setting 1"]) {
//ok, do the thing here
}
I'd use http://inappsettingskit.com/ rather than roll my own. I've used it in almost every application I work on and it handles app settings perfectly for just this sort of scenario.

Resources