Issue about appStoreReceiptURL - ios

I am trying to convert my paid app to free version with IAP , so basically I need to check if users bought previous version then unlock IAP item , I am not sure I am doing right here or not ! even is it possible to check and track 'appStoreReceiptURL' in development process ? here is my code :
NSURL* url = [[NSBundle mainBundle] appStoreReceiptURL];
NSLog(#"receiptUrl %#",[url path]);
NSError* err = nil;
if (![url checkResourceIsReachableAndReturnError:&err]){
SKReceiptRefreshRequest* request = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
request.delegate = self;
[request start];
}
-(void)requestDidFinish:(SKRequest*)request{
if([request isKindOfClass:[SKReceiptRefreshRequest class]]){
NSLog(#"YES, You purchased this app");
}
}
-(void)request:(SKRequest*)request didFailWithError:(NSError *)error{
NSLog(#"NO, you need to buy it ");
}
Now I am able to login with my Apple ID,and after I signed in it tells me YES, You purchased this app", and yes I really bought my app ! , I am going to make sure everything is alright .
Does this process should happen in every update ?

Here is a simple solution
#import <StoreKit/StoreKit.h>
Don't forget to add its delegates
<SKPaymentTransactionObserver, SKProductsRequestDelegate>
Payment Validation
- (IBAction)boughtIt:(id)sender {
NSURL* url = [[NSBundle mainBundle] appStoreReceiptURL];
NSLog(#"receiptUrl %#",[url path]);
NSError* err = nil;
if (![url checkResourceIsReachableAndReturnError:&err]){
SKReceiptRefreshRequest* request = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
request.delegate = self;
[request start];
_activity.hidden = NO;
}
}
-(void)requestDidFinish:(SKRequest*)request{
if([request isKindOfClass:[SKReceiptRefreshRequest class]]){
NSLog(#"YES, You purchased this app");
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Congrats !" message:#"Welcome To The World Of Dinosaurs" delegate:self
cancelButtonTitle:#"Cancel" otherButtonTitles:nil, nil];
[alert show];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"isPurchased"];
[[NSUserDefaults standardUserDefaults] synchronize];
_activity.hidden = YES;
[self dismissViewControllerAnimated:YES completion:nil];
}
}
- (void)request:(SKRequest*)request didFailWithError:(NSError *)error{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Sorry !" message:#"It seems you did not purchase this app before, if you like to unlock all content and features please purchase Paleontologist Pack" delegate:self
cancelButtonTitle:#"Cancel" otherButtonTitles:nil, nil];
[alert show];
_activity.hidden = YES;
// [self dismissViewControllerAnimated:YES completion:nil];
NSLog(#"NO, you need to buy it ");
}
This works only if a user PURCHASED the application , it doesn't work for redeem codes

Related

How do I check if Touch ID is enrolled but disabled on iPhone?

I'm using the following logic to check if touchID is available on iPhone and based on the returned value, I direct the user to enroll in touchID or navigate them to setup a PIN. It works fine in the happy path, but if I have even one fingerprint enrolled but have disabled touchID option from iPhone system settings, then it still returns true and navigates user to setup touchID. If I remove all fingerprints, then it works as expected by returning false and navigating to PIN screen.
- (BOOL) isTouchIDAvailable {
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
if (![myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
NSLog(#"Touch ID checking error: %#", [authError localizedDescription]);
return NO;
}
return YES;
}
I've referred to some questions on stack and apple dev docs
Not sure what I'm missing? Appreciate any help. Thanks in advance :)
let context = LAContext()
var error: NSError?
if #available(iOS 9.0, *) {
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
//this is for success
}else{
//error.description for type error LAError.biometryLockout, .biometryNotEnrolled and other errors
}
}
it's not possible. if you have TouchID, you have touchID. But if you want, you can disabled with programaticly. Look at the below code snippet to check touchID is aviable or not.
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = [NSString stringWithFormat:#"Login With your fingerprint with : %#",username];
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError *error) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
// [self performSegueWithIdentifier:#"Success" sender:nil];
[self loginWithFingerprint];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
/*
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:error.description
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alertView show];
*/
// Rather than show a UIAlert here, use the error to determine if you should push to a keypad for PIN entry.
});
}
}];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
/*
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:authError.description
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alertView show];
*/
// Rather than show a UIAlert here, use the error to determine if you should push to a keypad for PIN entry.
});
}

How to set up anonymous login with XMPPFramework - iOS Objective-C

I'm trying to set up an anonymous login so my users don't have to create an account an account on the eJabberd server to use the chat room. The configuration for the server in the ejabberd.cfg is:
{host_config, "bubble", [{auth_method, anonymous},
{anonymous_protocol, login_anon}]}.
My method to connect the client to the XMPPStream:
- (BOOL)connect {
[self setupStream];
if (![self.xmppStream isDisconnected]) {
return YES;
}
if (![PFUser currentUser]) {
return NO;
}
NSString *currentUserId = [NSString stringWithFormat:#"%##bubble",[PFUser currentUser].objectId];
[self.xmppStream setMyJID:[XMPPJID jidWithString:currentUserId]];
self.xmppStream.hostName = kJABBER_HOSTNAME;
NSError *error = nil;
if (![self.xmppStream connectWithTimeout:10 error:&error]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:[NSString stringWithFormat:#"Can't connect to server %#", [error localizedDescription]]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
return NO;
}
return YES;
}
As well as the xmppStreamDidConnect method:
- (void)xmppStreamDidConnect:(XMPPStream *)sender {
self.isOpen = YES;
NSError *error = nil;
if(![self.xmppStream authenticateAnonymously:&error]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:[NSString stringWithFormat:#"Can't connect to server %#", [error localizedDescription]]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}
}
When I try to login into the server, it keep on getting "The server does no support anonymous authentication".
Not sure what I'm doing wrong here, please let me know your thoughts.
From the XMPPFramework documentation:
If you wish to use anonymous authentication, you should still set myJID prior to calling connect. You can simply set it to something like "anonymous#domain", where "domain" is the proper domain. After the authentication process, you can query the myJID property to see what your assigned JID is.
Make sure that the settings on the server allow anonymous login as well.
If you don't have access to the serve configuration you can still check if the server allows anonymous login using something like:
- (void)xmppStreamDidConnect:(XMPPStream*)sender
{
self.isXmppConnected = YES;
if ([self.xmppStream supportsAnonymousAuthentication]) {
NSError* error = nil;
//the server does support anonymous auth
[self.xmppStream authenticateAnonymously:&error];
}
else {
NSLog(#"The server does not support anonymous authentication");
}
}
Be sure to place it in the didConnect delegate method, as it needs to be connected first.

xcode display data from json web service

I am using a web service used to display details about person and profile but I don't know how to display the data from web service to labels. I have worked with login validation using web service the code is as below
-(IBAction)login:(id)sender
{
NSString *username=userName.text;
NSString *password=passWord.text;
if ([username length]!=0&&[password length]!=0)
{
NSString *link=[NSStringstringWithFormat:#"http://www.abcd.com/XXX/YYY/Login.ashx/?Username=%#&Password=%#",username,password];
NSURL *URLGet= [NSURL URLWithString:link];
NSData* data = [NSData dataWithContentsOfURL:URLGet];
NSError* error;
XYZ Return array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if ([jasonReturnArray isEqual: #"UserId 4"])
{
Connections *view2=[[Connections alloc]initWithNibName:nil bundle:nil];
view2.modalTransitionStyle= UIModalTransitionStyleFlipHorizontal;
[self presentViewController:view2 animated:NO completion:nil];
NSLog(#"%#",jasonReturnArray);
}
else
{
UIAlertView* alert=[[UIAlertView alloc] initWithTitle:#"ERROR !!!!!!"message:#"Wrong Details" delegate:self cancelButtonTitle:#"Ok"otherButtonTitles: nil];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(#"%#",jasonReturnArray);
[alert show];
}
}
else
{
UIAlertView* alert=[[UIAlertView alloc] initWithTitle:#"ERROR !!!!!!"
message:#"Wrong Details" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(#"%#",jasonReturnArray);
[alert show];
}
}
It works fine but my doubt is
how to display the data from json web service to my designed labels
Create IBOutlet of your UILabel then set text value of your label as following
for (NSString * singleStringObject in jasonReturnArray)
{
yourLabel.text=[yourLabel.text stringByAppendingString:singleStringObject];
}
in case of single string you just set text of yourLabel without any loop.

how to use Gmail smtp in iOS app

I am new to Xcode I need an app to send a email. Background: the destination email Id is typed in a text and by clicking the send button the message body Sample should go to the destination Email ID I tried this code in the function button clicked but it is not working when ever i try this code I get error in function can any one guide me with a step by step tutorial
mailTransfer[673:207] delegate - error(-5): timeout sending message
2014-07-05 10:54:05.393 mailTransfer[673:207] * stopping watchdog * I had added the SMTP files from google documents ... any other way to correct this code
- (IBAction)sendMessageInBack:(id)anObject
{
SKPSMTPMessage *testMsg = [[SKPSMTPMessage alloc] init];
testMsg.fromEmail = #"Yours mail ids";
testMsg.toEmail = emailField.text;
testMsg.relayHost = #"smtp.gmail.com";
testMsg.requiresAuth = YES;
testMsg.login = #"Your mail ids";
testMsg.pass = #"id password";
testMsg.subject = #"Test application ";
testMsg.wantsSecure = YES;
testMsg.delegate = self;
NSDictionary *plainPart = [NSDictionarydictionaryWithObjectsAndKeys:#"text/plain",kSKPSMTPPartContentTypeKey,#"Sample",kSKPSMTPPartMessageKey,#"8bit",kSKPSMTPPartContentTransferEncodingKey,nil];
testMsg.parts = [NSArray arrayWithObjects:plainPart,nil];
[testMsg send];
}
-(void)messageSent:(SKPSMTPMessage *)message{
[message release];
NSLog(#"delegate - message sent");
}
-(void)messageFailed:(SKPSMTPMessage *)message error:(NSError *)error{
[message release];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Unable to send email" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
NSLog(#"delegate - error(%d): %#", [error code], [error localizedDescription]);
}
in SKPSMTPMessage.m
update the following line
CFDictionarySetValue(sslOptions,kCFStreamSSLLevel,kCFStreamSocketSecurityLevelTLSv1);
with
CFDictionarySetValue(sslOptions, kCFStreamSSLLevel, kCFStreamSocketSecurityLevelSSLv3);
Download SMTP framework and import SKPSMTPMessage class..
#import "SKPSMTPMessage.h"
-(void)sendEmailVideo:(NSString*)_toEmailAddress andCC:(NSString*)ccEmail
{
#try
{
// Message =[data getContentOfPanic];
NSData *webData = [NSData dataWithContentsOfURL:videoURL];
SKPSMTPMessage *emailMessage = [[SKPSMTPMessage alloc] init];
emailMessage.fromEmail=#"nikki.varsha#gmail.com";//sender email address
emailMessage.toEmail=_toEmailAddress;
//receiver email address
emailMessage.relayHost=#"smtp.gmail.com";
//emailMessage.ccEmail =ccEmail;
emailMessage.requiresAuth = YES;
emailMessage.login = #"nikki.varsha#gmail.com"; //sender email address
emailMessage.pass = #"123";
//sender email password
emailMessage.subject =#"Panic Video Message";
emailMessage.wantsSecure = YES;
emailMessage.delegate = self;
NSDictionary *plainPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/plain",kSKPSMTPPartContentTypeKey,
Message,kSKPSMTPPartMessageKey,#"8bit", kSKPSMTPPartContentTransferEncodingKey,nil];
NSDictionary *vcfPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/directory;\r\n\tx-unix-mode=0644;\r\n\tname=\"Video.mov\"",kSKPSMTPPartContentTypeKey,
#"attachment;\r\n\tfilename=\"Video.mov\"",kSKPSMTPPartContentDispositionKey,[webData encodeBase64ForData],kSKPSMTPPartMessageKey,#"base64",kSKPSMTPPartContentTransferEncodingKey,nil];
emailMessage.parts=[NSArray arrayWithObjects:plainPart,vcfPart,nil];
dispatch_queue_t backgroundVideoQueue = dispatch_queue_create("com.VideoQue", 0);
dispatch_sync(backgroundVideoQueue, ^{
[emailMessage send];
});
}
#catch (NSException *exception)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Host" message:#"No Reciever Email Ids Available! " delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
}
}
pragma mark - sendEmail delegate (SKPSMTPMessage)
-(void)messageSent:(SKPSMTPMessage *)message
{
NSLog(#"delegate - Email sent");
NSLog(#"Mesg %#",message);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Email sent." message:nil delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
-(void)messageFailed:(SKPSMTPMessage *)message error:(NSError *)error
{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"err=%#" ,message);
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"Unable to send email Please Check EmailId & Password"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
});
}
in SKPSMTPMessage.m file do change the following line
Remove this line
//CFDictionarySetValue(sslOptions,kCFStreamSSLLevel,kCFStreamSocketSecurityLevelTLSv1);
Add this line
CFDictionarySetValue(sslOptions, kCFStreamSSLLevel, kCFStreamSocketSecurityLevelSSLv3);
Thanks

How can I share the contents of my page in iPhone app on facebook?

I'm providing a facebook share option on my iPhone app screen and need to share some images and URL on the user's facebook profile . I know there are several third party frameworks like ShareKit and other features like facebook sdk for iOS, but which is the best way I could so the same and i need to get the share button with the number of shares until now as shown in the image below
and on clicking should redirect to authentication.
And should be compatible with iOS5 and above, hope my question is clear.
Thanks in advance
Solved the question myself through research
I used Facebook Graph API since my application needs support from iOS4+, would have been simple if it was for iOS6 as iOS6 has Facebook integration and needs just a few lines of code to implement it.
Imported Graph APi files and added the following code:
#synthesize facebook;
//login with facebook
- (IBAction) facebookButtonPressed {
if (!facebook || ![facebook isSessionValid]) {
self.facebook = [[[Facebook alloc] init] autorelease];
NSArray *perms = [NSArray arrayWithObjects: #"read_stream", #"create_note", nil];
[facebook authorize:FACEBOOK_API_KEY permissions:perms delegate:self];
}
else {
[self fbDidLogin];
}
}
//upload image once you're logged in
-(void) fbDidLogin {
[self fbUploadImage];
}
- (void) fbUploadImage
{
NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
resultImage, #"picture",
nil];
[facebook requestWithMethodName: #"photos.upload"
andParams: params
andHttpMethod: #"POST"
andDelegate: self];
self.currentAlertView = [[[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"Facebook", #"")
message:NSLocalizedString(#"Uploading to Facebook.", #"")
delegate:self
cancelButtonTitle:nil
otherButtonTitles: nil] autorelease];
[self.currentAlertView show];
}
//facebook error
- (void)request:(FBRequest*)request didFailWithError:(NSError*)error
{
[self.currentAlertView dismissWithClickedButtonIndex:0 animated:YES];
self.currentAlertView = nil;
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"Error", #"")
message:NSLocalizedString(#"Facebook error message", #"")
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[myAlert show];
[myAlert release];
}
//facebook success
- (void)request:(FBRequest*)request didLoad:(id)result
{
[self.currentAlertView dismissWithClickedButtonIndex:0 animated:YES];
self.currentAlertView = nil;
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"Facebook", #"")
message:NSLocalizedString(#"Uploaded to Facebook message", #"")
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[myAlert show];
[myAlert release];
}
And to get the share count of a particular URL in facebook,
use
http://graph.facebook.com/?id=url
But this returns the count of all likes,shares and posts altogether, so better find some alternatives to do so.
Hope this helps
Thanks

Resources