Undeclared identifier that is declared? - iphone

I am making an app where if the webpage doesnt load, it gives an error and returns to the previous screen. However, in doing this, after all the code, get an undeclared identifier
#pragma mark - View lifecycle
- (void)viewDidLoad
{
UIAlertView *cats = [[UIAlertView alloc] initWithTitle:#"**Read this first!**"
message:#"Thank you for ..."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[cats show];
[catscroll setScrollEnabled:YES];
[catscroll setContentSize:CGSizeMake(320,4800)];
[catscroll setPagingEnabled:NO];
[catform loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://m.petfinder.com/s/showPage.do?siteId=76333&pageId=7133416&shelterId=MA84&navigateToPage=Adopt%20Pets"]]];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)doPop
{
[cats dissmissWithClickedButtonIndex:-1 animated:YES];
[self.navigationController popViewControllerAnimated:YES];
UIAlertView *noconnectcatform = [[UIAlertView alloc] initWithTitle:#"Check your connection!"
message:#"Cannot connect to FPP Servers.\nPlease check your Internet Connection\nYou may not proceed until you are connected via a cellular network."
delegate:nil cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[noconnectcatform show];
}
as you can see in this image. If the webpage doesnt load it activates doPop, which returns the view and displays a message. However, this is throwing an EXC_BAD_ACCESS because, as you can see, under the viewDidLoad method, there is another message that plays. The app is getting confused and crashing. I tried to fix this by dismissing the alert in the doPop method, however it is strangely giving me this error. I may be misunderstanding, but isn't the alertview defined where it says "UIAlertView *cats"? why does it say that it is not defined in the doPop method? Please help!

The object cats is defined locally to viewDidLoad. The scope of the variable does not extend beyond the method, thus doPop has no idea what cats is.
Move cats to be defined in the .h file as a member/class variable.
This means you'll need to remove the UIAlertView * from within viewDidLoad and just reference cats (as is, you are defining another variable scoped to viewDidLoad).
You have a typo in the method called in doPop The method is dismissWithClickedButtonIndex:1 animated:YES]; You have dissmissWithClickedButtonIndex:1 animated:YES];
Also, you only need IBOutlet defined with the #property

Okay, so if i were you i would simply show the error message on the view that failed to load, then use the default cancel action to pop this view (This is the most common practice)
Alternatively, if you really wanna show the message in the other view you have to make that view display the error message. there are several ways to do this but id still go with the first option. (I could tell you how if you really wanna take this approach)
Edit: If you just want that error to go away, add before "Implementation" in your .m file
#interface CatForm ()
{
UIAlertView *cats;
}
#end
and change
UIAlertView *cats = [[UIAlertView alloc] initWithTitle:#"**Read this first!**"
message:#"Thank you for considering to adopt a cat from our shelter. PLEASE READ THIS FORM CAREFULLY.\n\nThis on-line form is intended to assist you in selecting a cat that is suitable for you, your family, and your lifestyle.\n\nThe Friends of the Plymouth Pound have established guidelines and policies that must be met in order for your pre-screening application to be approved.\n\nThe information you provide is essential to facilitate the application review process.\n\nIn order to be considered for adoption by the Friends of the Plymouth Pound, you must:\n\n\n*Be at least 18 years old.\n\n*Provide all the applicable information requested below.\n\n**Note, any data field marked with an asterisk character (*) must be filled in. Incomplete application forms will not be considered for review and will be denied automatically.**\n\n*Understand that this is a pre-screening form.\n\n\nThe Friends of the Plymouth Pound will contact you and approve you if, and only if, all requirements have been met.\n\nUpon review of your pre-screening application, you will be contacted by the Friends of the Plymouth Pound to notify you if your application has been accepted and if further information is needed. \n\n\n**Please note that we do contact all personal references and veterinarians, and we must speak with them personally. In addition, in some cases, a pre-adoption home visit may also be required.**\n\nIn the event that your pre-screening application has been not been approved, we will notify you of same.\n\n\nTHE BOARD OF DIRECTORS OF THE FRIENDS OF THE PLYMOUTH POUND RESERVES THE RIGHT TO DENY ANY PRE-APPLICATION BASED ON THE ORGANIZATION'S ESTABLISHED STANDARDS AND POLICIES, INCLUDING, BUT NOT LIMITED TO, INCOMPLETE INFORMATION, NON-DISCLOSURE OR OMISSION OF PERTINENT FACTS, AND NON-COMPLIANCE WITH ACCEPTED STANDARDS.\n\n\nUpon approval of your application and transfer of the animal, you will be charged a $150.00 adoption fee per cat.\n\n\nWe are an all-volunteer organization. Due to the high volume of applications, we ask that you be patient in waiting for a reply. Please do not submit duplicate applications or separate requests for response. Doing this will not accelerate the review process in any way."
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
for
cats = [[UIAlertView alloc] initWithTitle:#"**Read this first!**"
message:#"Thank you for considering to adopt a cat from our shelter. PLEASE READ THIS FORM CAREFULLY.\n\nThis on-line form is intended to assist you in selecting a cat that is suitable for you, your family, and your lifestyle.\n\nThe Friends of the Plymouth Pound have established guidelines and policies that must be met in order for your pre-screening application to be approved.\n\nThe information you provide is essential to facilitate the application review process.\n\nIn order to be considered for adoption by the Friends of the Plymouth Pound, you must:\n\n\n*Be at least 18 years old.\n\n*Provide all the applicable information requested below.\n\n**Note, any data field marked with an asterisk character (*) must be filled in. Incomplete application forms will not be considered for review and will be denied automatically.**\n\n*Understand that this is a pre-screening form.\n\n\nThe Friends of the Plymouth Pound will contact you and approve you if, and only if, all requirements have been met.\n\nUpon review of your pre-screening application, you will be contacted by the Friends of the Plymouth Pound to notify you if your application has been accepted and if further information is needed. \n\n\n**Please note that we do contact all personal references and veterinarians, and we must speak with them personally. In addition, in some cases, a pre-adoption home visit may also be required.**\n\nIn the event that your pre-screening application has been not been approved, we will notify you of same.\n\n\nTHE BOARD OF DIRECTORS OF THE FRIENDS OF THE PLYMOUTH POUND RESERVES THE RIGHT TO DENY ANY PRE-APPLICATION BASED ON THE ORGANIZATION'S ESTABLISHED STANDARDS AND POLICIES, INCLUDING, BUT NOT LIMITED TO, INCOMPLETE INFORMATION, NON-DISCLOSURE OR OMISSION OF PERTINENT FACTS, AND NON-COMPLIANCE WITH ACCEPTED STANDARDS.\n\n\nUpon approval of your application and transfer of the animal, you will be charged a $150.00 adoption fee per cat.\n\n\nWe are an all-volunteer organization. Due to the high volume of applications, we ask that you be patient in waiting for a reply. Please do not submit duplicate applications or separate requests for response. Doing this will not accelerate the review process in any way."
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
In the View Did Load

Related

Adding Flurry in the alertView

I have added a Flurry logevent when the ok button of the alertView is clicked.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
{
if (buttonIndex == 1)
{
NSString *start = #"Start";
NSString* myLogEvent = [start stringByAppendingString:title.text];
NSLog(#"%#",myLogEvent);
[Flurry logEvent:myLogEvent];
}
}
I have logged the event like 2 hours ago. It is still not appearing in my Flurry Login Page. Did i do something wrong?
I know the analytics takes time to appear but the event name should appear in the login page after 45 minutes or so. Am i right? Worried I did something wrong..
Usage data from Flurry may take up to 7 hours to get reflected on the developer portal. First time Events may take slightly longer.
Edit: If you're using the simulator, please ensure that you press the home button before closing the app. This is required in order to complete the Flurry reporting lifecycle.
(Full disclosure: I work in the Support team at Flurry)
Flurry proved to work for me including events, so it should work for you, too. I'd check with the debugger that the Flurry session was started ([Flurry startSession:#"YOUR_API_KEY"]) and your event code got really executed. And that you have internet connection, otherwise all events will get saved locally and transfered to Flurry on the next occasion.
Than wait some more, it takes time at times for the analytics results to show...

How do I design and implement password authentication for IOS?

I have what seems to be a simple issue but I can't find a solution. I have spent hours trying to find an example that shows how to build a view, allow a user to enter a password, authenticate the password and return the view to a designated view. I have found a lot a great resources on bits and pieces, but they all are somewhat vague on how to authenticate the password and then send the user to a designated view.
This seems to be the best solution to my problem, which is: I have several pdfs that I need to password protect in my iPad app.
Issue1: Prompt for userName and Password
Present a view modally. if username/password combination is correct, dismiss the modal view. alternatively, you can use an alert with textfields.
Issue2: Store username/password in a secure way
Use key chain as suggested in the other answer. USage of key chain is as simple as using NSUserDefaults with Carlbrown's PDKeychainBindingsController. You can find it at the below link
https://github.com/carlbrown/PDKeychainBindingsController
EDITED to add info requested in comment:
Assuming you are using a custom view controller for login prompt, you have to do something like this when you want to prompt for password. it can be in your application didFinishLaunchingWithOptions.
LoginViewController *controller = [LoginViewController alloc];
[self presentModalViewController:controller animated:YES];
[controller release];
Then in your LoginViewController, you have to do something like this.
PDKeychainBindings *keyChain =[PDKeychainBindings sharedKeychainBindings];
if ([[keyChain objectForKey:#"User Name"] isEqualToString:userName] && [[keyChain objectForKey:#"Password"] isEqualToString:passWord] ) {
[self dismissModalViewControllerAnimated:YES];
}else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"ERROR" message:#"Wrong User Name and/or Password\nEnter Login Information Again"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
Please note that the strings userName and PassWord are captured from your textfields in login view controller.
In anticipation of your answer to my comment--
If you want the password to be stored locally, I would store it (hashed or otherwise) in the Keychain, to compare against the user-entered password. More in the Apple docs here.
I'd recommend downloading the Apple sample project for an example of storing/retrieving data from the keychain.
Oliver over at Cocoanetics.com has a very nice implementation of the security login screen apple uses. Look at the PinLockController class in MyAppSales.
https://github.com/Cocoanetics/MyAppSales
For keychain storage I use SFHFKeychainUtils. Its a simple method call to store and retrieve secure passwords. But I think standard NSUserDefaults would be sufficient for your needs.
(handy site http://gorgando.com/blog/tag/sfhfkeychainutils)
However, if you want to sell that app, keep in mind, that apple says
The user can set a four-digit personal identification number (PIN) to
prevent unauthorized use of the device, so there is no need for the
user to be authenticated and there are no authentication or
authorization APIs in iPhone OS.
This can be found in the Security Coding How-To's

FBLoginDialog auto ask for Basic Permission before didLogin

I am using the old facebook iphone sdk to develop a iphone app: https://github.com/megastep/facebook-iphone-sdk
I am currently encountering a problem: The FBLoginDialog auto ask for Basic Permission before the didLogin callback.
I want to skip this part as I want to ask Exteneded permission.
And idea why facebook is asking the basic permission before the callback didLogin?
Thanks.
FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:session] autorelease];
// dialog.delegate = self;
[dialog show];
You need to move to the new SDK. The SDK you are using is known to be buggy in several ways, it leaks memory and has problems on the 4.2 OS when the user is editing text and the keyboard is on screen.
Note also that the new SDK makes it extremely easy to ask for whatever permissions you need, you can just do it in the authorize:delegate method (see the sample project included in the sdk for an example).
Edit/Update:
Facebook asks for basic auth before didLogin because the user has to at least authorize your application.

In App Purchase - can get product info but can't connect to itunes for purchase

I'm trying to make "In App Purchase " works in my iphone app.
I created some products and a few test accounts in itunes connect.
I have no problem to retreive the products data (prices etc..) but when I try to make a payment
- I am asked to log in
- I use a test account
-> the transaction always fail with the following error :
failedTransaction with error : Error Domain=SKErrorDomain Code=2 "Connexion à l’iTunes Store impossible" UserInfo=0x65d02a0 {NSLocalizedDescription=Connexion à l’iTunes Store impossible}
I tried with several products and test account (even in other stores like us) but I still get the same error...
NB : I think it worked fine the first time I tried but never still
Any idea will be welcome !
Thanks
For me, I just scoured my code until I found my mistake. I was so certain everything was fine, but it was not. When I requested product information from the store, I used the correct Product Identifier:
self.productRequest= [[[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject: #"com.popculturesoft.RC_vCar.fullVersion"]] autorelease];
However, when I went to create the payment, I used the incorrect Product Identifier:
SKPayment *payment = [SKPayment paymentWithProductIdentifier:#"com.popculturesoft.RC_vCar_Lite.fullVerson"];
Using the product Identifier for the payment is not the correct way to do it, although it allows you to do it. It is better to use an SKProduct object. (I had set the fullProduct property earlier in the code:
SKPayment *payment = [SKPayment paymentWithProduct:self.fullProduct];
I was absolutely certain that the store was down, and that was the problem. But the next day I decided to start from the beginning of the process, as described in http://developer.apple.com/library/ios/#technotes/tn2259/_index.html. This is when I found that my incorrect Product Identifier was the problem.
Check out this thread. It seems to be a problem with the Sandbox. Lot's of people having this issue-
iPhone storekit sandbox stopped working
I had the same symptoms and in my case the problem was that I had a test user account with the same name as a real Apple ID account. I resolved the problem by creating a different test user account.

iPhone In App Purchase - response.products are still empty?

Basically, I've tried to set up in app purchases on a test app before I implement them into a proper app that my company is working on. I've read the Store kit pdf and other snippets about a 1000 times, but the products are still being returned as empty. Here's exactly what I've done so far:
Setup test app and In App Purchase test items
I created a new app id for 'Test App One' on my company's developer portal in the iPhone Dev Centre. I made sure that the prefix was com.mycompany.testappone to ensure that in app purchases could be configured. Staying in the App IDs section, I configured in app purchases by ticking the 'Enable In App Purchase' option.
I created 'Test App One' in iTunes Connect and completed the usual procedure but selected 'upload binary later' and didn't submit for review as the app does nothing. Surely we don't have to submit the app to review for this to work?! I then clicked on manage in app purchases and created a new one with product id 'test1' and approved it so that it is cleared for sale.
Code
I set up a new project in XCode called TestAppOne and here are the only 2 classes I am using for now:
TestAppOneAppDelegate.h:
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
#interface TestAppOneAppDelegate : NSObject <UIApplicationDelegate, SKRequestDelegate, SKProductsRequestDelegate> {
UIWindow *window;
}
TestAppOneDelegate.m:
#import "TestAppOneAppDelegate.h"
static NSString *kMyFeatureIdentifier1 = #"com.mycompany.testappone.test1";
#implementation TestAppOneAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
if([SKPaymentQueue canMakePayments]) {
NSLog(#"IN-APP:can make payments");
}
else {
NSLog(#"IN-APP:can't make payments");
}
[self requestProductData];
[window makeKeyAndVisible];
}
- (void)requestProductData {
NSLog(#"IN-APP:requestProductData");
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject:kMyFeatureIdentifier1]];
request.delegate = self;
[request start];
NSLog(#"IN-APP:requestProductData END");
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(#"IN-APP:productsRequest");
NSArray *myProduct = response.products;
NSLog(#"IN-APP:array count: %i", [myProduct count]);
[request autorelease];
NSLog(#"IN-APP:productsRequest END");
}
- (void)dealloc {
[window release];
[super dealloc];
}
#end
Testing on the device
I created a sandbox test account and logged out of my iTunes account on the iPhone, but didn't log in with the test account as the documentation tells us to not do this until we are prompted at the purchasing stage. I then build the app and here is the log I'm getting:
IN-APP:can make payments
IN-APP:requestProductData
IN-APP:requestProductData END
IN-APP:productsRequest
IN-APP:array count: 0
IN-APP:productsRequest END
Can anyone please tell me if I have left any stages out or if there is anything that I'm doing wrong. Unfortunately there doesn't seem to be any example apps made by Apple.
Another important step that is often overlooked is you need to make sure you have an iOS Paid Applications Contract setup which is located under the "Contracts, Tax, and Banking" section of iTunes connect. First you have to click on the request button, then you have to click on the 3 Set Up buttons (Contact Info, Bank Info, Tax Info)
Actually I do think you have to submit the binary for this to work.
You can set the release date to the distant future.
Check whether there are invalid product id's.
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
for (NSString *invalidProductId in response.invalidProductIdentifiers)
{
NSLog(#"Invalid product id: %#" , invalidProductId);
}
}
If there are invalid product ids visit http://troybrant.net/blog/2010/01/invalid-product-ids/
It is a very comprehensive check-list for this problem.
Edit: (13/11/20)
Site seems to be down. I'm not sure whether it is a permanent problem but you can see the page from archive.org:
https://web.archive.org/web/20200212001158/http://troybrant.net/blog/2010/01/invalid-product-ids/
Check if your Bundle Identifier (e.g. com.company.appname) in XCode matches the one in iTunes Connect.
You do not have to submit the binary for it to work.
Just delete the application on your device, and start it again from XCode.
It fixed the problem for me.
No need to upload the binary, or wait for hours after creating the in-app purchase in iTunes Connect.
Thanks to alpere's answer I found out that I used the wrong product ID. It was not as I thought de.company.appname.PROFESSIONAL_LICENSE. Just using PROFESSIONAL_LICENSE in my case (without leading bundle id stuff) works :)
No need to upload binary for Sandbox testing of InAppPurchase. You just have to add InAppPurchase item in iTunesConnect and put it in "Ready to submit"(must) state only. If you submit it for review it will always give ou response.product empty.
Try to add a Free Subscription product. If it appears on the response then there is nothing wrong in your code. Since Free Subscription is the only type that doesn't require Agreements, Tax, and Banking and if it appears and the other types don't then it is a issue related to your contract.
In my case the reason was hosting of content by Apple turned on by mistake. The product was available only when I turned it off
In my case (MacOS) I was creating a test application (with the same bundle ID of main application). SKFetchRequest started returning product Ids for test application only after I set Bundle Name (Binary name) the same as in original application.