How to make a registration page in an iPhone app? - iphone

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];
}

Related

How to navigate from app delegate class in window based iPhone application. How to write pushViewcontroller method in app delegate class

In my window base application I need to navigate to informationview from my appdelegate when i click on alert view button.
alert view works with NSlog.
But i need to push to the other view for this purpose i used
[self.navigationController pushViewController:info animated:YES];
but it doesn't pushes. just nslog only prints
- (void)applicationDidBecomeActive:(UIApplication *)application
{
//To count the number of launches
NSInteger i = [[NSUserDefaults standardUserDefaults] integerForKey:#"numOfCalls"];
[[NSUserDefaults standardUserDefaults] setInteger:i+1 forKey:#"numOfCalls"];
NSLog(#"the number of active calls are %d",i%3);
if(i%3==0 && i!=0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"you might prefer MedChart+" message:#"Get it now for more options" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok",nil];
[alert show];
[alert release];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
NSLog(#"canceled");
}
else if (buttonIndex == 1)
{
NSLog(#"Pushed to the information view ");
InformationViewCotroller *info = [[InformationViewCotroller alloc]initWithNibName:#"InformationViewCotroller" bundle:nil];
[self.navigationController pushViewController:info animated:YES];
}
}
(dont consider 'i' values it is part of my logic).
Thanks in advance
Before Navigate to any viewController , set the RootController for your navigationController of appDelegate.
Add navigationController.View as subview of window.Then your root controller will be the first ViewController.from there you can push to any viewController.

reloadData after Login on iPhone app

I have a Login that is initiated on the viewDidLoad of the mainApp. This means numberOfRowsInSection in the mainApp runs before the Login and results my tableview not being populated.
I have my JsonArray in the viewWillAppear in the mainApp the reloadData function to make numberOfRowsInSection run after the Login as well. So I put:
[self.tableView reloadData];
...in the viewWillAppear. But this doesn't make it run after Login.
Any suggestions?
Thanks in advance.
CODE UPDATE
Login Page
if (serverOutput != nil) {
//UIAlertView *alertSuccess = [[UIAlertView alloc] initWithTitle:#"Congrats" message:#"You are authorised" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
//[alertSuccess show];
//[alertSuccess release];
LucentaAppDelegate *appDelegate = (LucentaAppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.userProducts = serverOutput;
loginButton.enabled = FALSE;
[self dismissModalViewControllerAnimated:YES];
Main View
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
LucentaAppDelegate *appDelegate = (LucentaAppDelegate *)[[UIApplication sharedApplication] delegate];
self.jsonArray = [appDelegate.userProducts JSONValue];
//[self.tableView reloadData];
[self performSelector:(#selector(refreshDisplay:)) withObject:(tableView) afterDelay:0.5];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Test Alert" message:#"View Will Appear." delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles: nil];
[alert show];
[alert release]; }
-(void)refreshDisplay:(UITableView *)tableView {
[self.tableView reloadData];}
When your login (started in viewWillLoad) is completed, you should get some delegate callback call that tells you that your request as completed. You usually specify the delegate when creating the request.
If you are using NSURLRequest and NSURLConnection, the delegate is specified in one of:
+ connectionWithRequest:delegate:
– initWithRequest:delegate:
– initWithRequest:delegate:startImmediately:
depending on how your create the request, and the delegate callback to override is connectionDidFinishLoading: (or connection:didFailWithError: in case of communication errors).
connectionDidFinishLoading: is the right place where you should issue your [self.tableView reloadData];, after having updated your table data source.
If you are not using NSURLRequest, then the delegate callback will be different.
EDIT:
if your mainView receive the JSon data it needs, what you should do there is update your table data source and call reloadData on the table.
Indeed, calling reloadData will force calling numberOfRowsInSection again, but this information is provided by your data source, so if it is not updated to reflect the new data you have received, it will always reflect the old value.
Could you provide more information about your data source?
That depends on the actual code of your app. I suggest just to put a method like
- (void)loginSucceeded {
[self.tableView reloadData];
}
to your view controller and call it after the login was successful. It is also convenient as you might need to do some more complicated actions in this situation when your app grows.

App Store Review Button

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!

alertView didDismissWithButtomIndex is not called after a click on the alertView's buttom

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.

Show UIAlertView on splash screen

I used to show a splash screen which in background load some data from web, I also check that if the location of the user is changed from one city to another city I want to show in alert to the user with the message that you are now in "CityName" would you like to see data from this city?
I have tabbed application and I have presented the splash screen as follow in the app delegate class.
SplashViewController *controller = [[SplashViewController alloc] initWithNibName:nil bundle:nil];
tabBarController.view.frame = [[UIScreen mainScreen] bounds];
controller.tabBarController = self.tabBarController;
[application setStatusBarStyle:UIStatusBarStyleBlackOpaque];
[window addSubview:controller.view ];
//[window addSubview:tabBarController.view ];
[self.tabBarController presentModalViewController:controller animated:YES];
[window makeKeyAndVisible];
[controller release];
Now when I show the alert screen it crash the application with "EXC_BAD_ACCESS" message and the stack trace show that _buttonClick is released in UIAlertView class.
Please advise what should I do, I also tried with UIActionSheet but the same problem with this thing too.
I think there is some problem with the model thing with the current view (SplashView).
Thanks in advance.
Are you trying to display your UIAlertView inside of your SplashViewController viewDidAppear? If not, I would try that first. I would also make sure you have your UIAlertView clickedButtonAtIndex method setup properly to try and trap what is going on.
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Your Location Has Changed"
message:#"Your location has changed since you last opened opened THEAPP. Would you like to refresh your data?" delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
alert.tag = 1;
[alert show];
[alert autorelease];
Then for the clickedButtonAtIndex method:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
//--NSLog(#"You clicked button #%i",buttonIndex);
if (alertView.tag == 1){
if (buttonIndex == 0) {
//--NSLog(#"CANCEL");
} else if (buttonIndex == 1) {
//--NSLog(#"OK");
}
}
}
Doing all of this on a splash screen should be fine as long as you take into account the HIG's requirements for using the users location. Hope this helps!
I resolve this issue, the problem was that my Splash View was a modeled view and invoked by
[self.tabBarController presentModalViewController:controller animated:YES];
what I did that I shifted the data downloading to another view controller and there I can show alerts, and can handle that