I have tested on IAP of type Consumable with Sandbox environment. I want to make sure that the item I have bought is valid or not. but the result is always return with status "21004". I do nothing with share secret. So you can look the sample code that I follow apple when I succeed to purchase item:
- (void)verifyStatus:(SKPaymentTransaction *)transaction {
NSData *receiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
NSError *receiptError;
BOOL isPresent = [[[NSBundle mainBundle] appStoreReceiptURL] checkResourceIsReachableAndReturnError:&receiptError];
if (!isPresent) {
NSLog(#"Validation failed");
}
NSString *receiptStr = [receiptData base64EncodedStringWithOptions:0];
NSDictionary *requestContents = #{#"receipt-data":receiptStr};
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
options:0
error:nil];
if (!requestData) { /* ... Handle error ... */ }
NSURL *storeURL = [NSURL URLWithString:#"https://sandbox.itunes.apple.com/verifyReceipt"];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:#"POST"];
[storeRequest setHTTPBody:requestData];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
/* ... Handle error ... */
} else {
NSError *error;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"Respond : %#",jsonResponse);
if (!jsonResponse) { /* ... Handle error ...*/ }
/* ... Send a response back to the device ... */
}
}];
}
What's the problem I got? Please share your experience. Thanks
Please try following code and steps for SECRECT KEY.
#define SHARED_SECRET #"SECRECT KEY"
-(void)checkReceipt {
// verifies receipt with Apple
NSError *jsonError = nil;
NSString *receiptBase64 = [receiptData base64EncodedStringWithOptions:0];//receiptData NSData for validate Receipt
NSLog(#"Receipt Base64: %#",receiptBase64);
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithObjectsAndKeys:
receiptBase64,#"receipt-data",
SHARED_SECRET,#"password",
nil]
options:NSJSONWritingPrettyPrinted
error:&jsonError
];
NSLog(#"%#",jsonData);
NSError * error=nil;
NSDictionary * parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
NSLog(#"%#",parsedData);
NSLog(#"JSON: %#",[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);
// URL for sandbox receipt validation; replace "sandbox" with "buy" in production or you will receive
// error codes 21006 or 21007
NSURL *requestURL = [NSURL URLWithString:#"https://sandbox.itunes.apple.com/verifyReceipt"];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:requestURL];
[req setHTTPMethod:#"POST"];
[req setHTTPBody:jsonData];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:req queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
/* ... Handle error ... */
} else {
NSError *error;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"Respond : %#",jsonResponse);
if (!jsonResponse) { /* ... Handle error ...*/ }
/* ... Send a response back to the device ... */
}
}];
}
You need to change "SECRECT KEY" with the secret key that you get from iTunes Connect.sample look like 39fkjc38jd02mg72k9cn29dfkm39fk00.
Below is the step for create/view Secreate Key.
Login into iTunes Connect -> My Apps > Select your app > In-App
Purchases > View or generate a shared secret.
Related
Firstly I have two text fields first is login and second is password and one login button. I am using a storyboard and login button connected to another view controller by push segue. This time working in my project, Put username and password in textfield and select login button and print server response in console.
I want to login successfully after move another view and login is failed don't move another view.
My php code
<?php
header('Content-type: application/json');
include('../conn.php');
if($_POST)
{
$loginid = $_POST['loginid'];
$loginpassword = $_POST['loginpassword'];
$schoolid = substr_id($loginid);
$table = tb3($schoolid);//profile
$sql=mysql_query("select * from $table where ID = '".$loginid."' AND PASSWORD = '".$loginpassword."'",$conn);
$row=mysql_fetch_assoc($sql);
if(mysql_num_rows($sql)>0)
{
echo '{"success":1}';
}
else
{
echo '{"success":0,"error_message":"UserID and/or password is invalid."}';
}
}
else
{
echo '{"success":0,"error_message":"UserID and/or password is invalid."}';
}
My viewcontroller code
- (IBAction)Login:(id)sender {
if([[self.user_id text] isEqualToString:#""] || [[self.password text] isEqualToString:#""] ) {
} else {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://sixthsenseit.com/school/project/ios/login.php"]];
//create the Method "GET" or "POST"
[request setHTTPMethod:#"POST"];
//Pass The String to server(YOU SHOULD GIVE YOUR PARAMETERS INSTEAD OF MY PARAMETERS)
NSString *userUpdate =[NSString stringWithFormat:#"loginid=%#&loginpassword=%#&",_user_id.text,_password.text, nil];
//Check The Value what we passed
NSLog(#"the data Details is =%#", userUpdate);
//Convert the String to Data
NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
//Apply the data to the body
[request setHTTPBody:data1];
//Create the response and Error
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
//This is for Response
NSLog(#"got response==%#", resSrt);
if(resSrt)
{
NSLog(#"got response");
}
else
{
NSLog(#"faield to connect");
}
}
}
This line is wrong
NSString *userUpdate =[NSString stringWithFormat:#"loginid=%#&loginpassword=%#&",_user_id.text,_password.text, nil];
you are additionally added the & in your params ,this is not in loginpassword=%#& , you need to call like loginpassword=%# remove and send the request
use like
NSString *userUpdate =[NSString stringWithFormat:#"loginid=%#&loginpassword=%#",_user_id.text,_password.text, nil];
The problem is you are not serlize your JSON
so remove this line in your NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
and I follow your Answer
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Response code: %ld", (long)[response statusCode]);
if ([response statusCode] >= 200 && [response statusCode] < 300)
{
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization
JSONObjectWithData:urlData
options:NSJSONReadingMutableContainers
error:&error];
int success = [jsonData[#"success"] integerValue];
if(success == 1)
{
NSLog(#"Login SUCCESS");
[self performSegueWithIdentifier:#"login_success" sender:self];
} else {
NSString *error_msg = (NSString *) jsonData[#"error_message"];
[self alertStatus:error_msg :#"Sign in Failed!" :0];
}
}
Ankur kumawat I tried your coding and Brother #Anbu.karthik answer in iOS 9.I got few warnings.First I post Anbu.Karthik brother answer.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://sixthsenseit.com/school/project/ios/login.php"]];
//create the Method "GET" or "POST"
[request setHTTPMethod:#"POST"];
//Pass The String to server(YOU SHOULD GIVE YOUR PARAMETERS INSTEAD OF MY PARAMETERS)
NSString *strUserId = #"1000710017";
NSString *strPassword = #"XM0MB";
NSString *userUpdate =[NSString stringWithFormat:#"loginid=%#&loginpassword=%#",strUserId,strPassword, nil];
//Check The Value what we passed
NSLog(#"the data Details is =%#", userUpdate);
//Convert the String to Data
NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
//Apply the data to the body
[request setHTTPBody:data1];
//Create the response and Error
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingMutableContainers
error:&error];
int success = [jsonData[#"success"] integerValue];
if(success == 1)
{
NSLog(#"Login SUCCESS");
[self performSegueWithIdentifier:#"login_success" sender:self];
} else {
NSString *error_msg = (NSString *) jsonData[#"error_message"];
[self alertStatus:error_msg :#"Sign in Failed!" :0];
}
Above is brother Anbu.Karthik answer.I tried that and it shows me the warnings.
Warnings are
'sendSynchronousRequest:returningResponse:error:' is deprecated: first
deprecated in iOS 9.0 - Use [NSURLSession
dataTaskWithRequest:completionHandler:] (see NSURLSession.h
Then
Implicit conversion loses integer precision: 'long _Nullable' to 'int'
As I get warning I want to remove warning and
I must use
NSURLSession with dataTask because sendSynchronousRequest:returningResponse:error:' is deprecated in iOS 9.0
Then I modified the code.
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://sixthsenseit.com/school/project/ios/login.php"]];
NSString *strUserId = #"1000710017";
NSString *strPassword = #"XM0MB";
NSString *userUpdate =[NSString stringWithFormat:#"loginid=%#&loginpassword=%#",strUserId,strPassword, nil];
//create the Method "GET" or "POST"
[urlRequest setHTTPMethod:#"POST"];
//Convert the String to Data
NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
//Apply the data to the body
[urlRequest setHTTPBody:data1];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if(httpResponse.statusCode == 200)
{
NSError *parseError = nil;
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
NSLog(#"The response is - %#",responseDictionary);
NSInteger success = [[responseDictionary objectForKey:#"success"] integerValue];
if(success == 1)
{
NSLog(#"Login SUCCESS");
}
else
{
NSLog(#"Login FAILURE");
}
}
else
{
NSLog(#"Error");
}
}];
[dataTask resume];
The printed result is
The response is - {
success = 1;
}
And
Login SUCCESS
Now above my code works perfectly:-)
Try this code in view Controller file:
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSLog(#"%#",dict);
if (dict)
{
NSString *status = [NSString stringWithFormat:#"%#",[dict valueForKey:#"success"]];
}
output: 1 // successfully
or
0 // Unsccssfully
NSString *msg = [NSString stringWithFormat:#"%#",[dict valueForKey:#"error_message"]];
Replace your code with this :
- (IBAction)Login:(id)sender {
if([[self.user_id text] isEqualToString:#""] || [[self.password text] isEqualToString:#""] ) {
} else {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://sixthsenseit.com/school/project/ios/login.php"]];
//create the Method "GET" or "POST"
[request setHTTPMethod:#"POST"];
//Pass The String to server(YOU SHOULD GIVE YOUR PARAMETERS INSTEAD OF MY PARAMETERS)
NSString *userUpdate =[NSString stringWithFormat:#"loginid=%#&loginpassword=%#&",_user_id.text,_password.text, nil];
//Check The Value what we passed
NSLog(#"the data Details is =%#", userUpdate);
//Convert the String to Data
NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
//Apply the data to the body
[request setHTTPBody:data1];
//Create the response and Error
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
Dictionary *dictResponce = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
if (dictResponce)
{
NSString *status = [NSString stringWithFormat:#"%#",[dict valueForKey:#"success"]];
if (status == "1"){
//Push to home view controller
[self performSegueWithIdentifier:#"Home_page" sender:self];
}
else{
NSLog([NSString stringWithFormat:#"%#",[dict valueForKey:#"error_message"]]);
}
}
else{
NSLog(#"faield to connect");
}
}
}
Currently i am using .net Api's for getting response
Here is my iOS source code:
-(void)getUserNameFromFacebbok: (NSString*)newUserName withFacebookId: (NSString*)newFbId withFacebookLoginEmailId: (NSString*)newEmailId withProfilePicUrl: (NSString*)newProfilePicUrl{
NSString * fbApiURLStr =[NSString stringWithFormat:#"http://example.com/api/v1/FacebookUserLogin?UserName=%#&id=%#&emailid=%#&facebookurl=%#",
newUserName,
newFbId,
newEmailId,
newProfilePicUrl];
NSMutableURLRequest *dataRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:fbApiURLStr]];
NSHTTPURLResponse *response =[[NSHTTPURLResponse alloc] init];
NSError* error;
NSData *responseData = [NSURLConnection sendSynchronousRequest:dataRequest returningResponse:&response error:&error];
facebookLoginResponseDict = [NSJSONSerialization JSONObjectWithData:responseData
options:0
error:&error];
}
I am not getting any response dataRequest parameter ====> currently i am getting { URL: (null) }
Can you please help me out how can i solve this issue
Sorry, I found the proper solution like
NSURL *url = [NSURL URLWithString:#"http://example.com/api/v1/FacebookUserLogin?UserName=Brahmam&id=4654566&emailid=ghjnghjnhgh#gmail.com&facebookurl=https://fbjghjghjghjghmkjhgmhjkmhjmh"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response;
NSError *error;
//send it synchronous
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
// check for an error. If there is a network error, you should handle it here.
if(!error)
{
//log response
NSLog(#"Response from server = %#", responseString);
}
I have recently switched from sendSynchronousRequest to dataTaskWithRequest
with sendSynchronousRequest my method was working perfectly but when I switch to dataTaskWithRequest I get the following error:
error NSURLError * domain: #"NSURLErrorDomain" - code: 4294966096 0x15ee96c0
and
myError NSError * domain: nil - code: 1684370017 0x26cce125
I don't understand why.
Here is the old code (commented out) and the new code:
/*-(NSDictionary *)GetProductionScheduleData:(NSString *)areaDescription
{
NSString *areaDescriptionWSpaceCharacters = [areaDescription stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSString *requestString = [NSString stringWithFormat:#"%#?areaDescription=%#",kIP,areaDescriptionWSpaceCharacters];
NSURL *JSONURL = [NSURL URLWithString:requestString];
NSURLResponse* response = nil;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
if(data == nil)
return nil;
NSError *myError;
NSDictionary *productionSchedule = [[NSDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
return productionSchedule;
}*/
-(void)GetProductionScheduleData:(NSString *)areaDescription Completetion:(void (^) (NSMutableDictionary * result,NSError * error))completion{
NSString *areaDescriptionWSpaceCharacters = [areaDescription stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSString *requestString = [NSString stringWithFormat:#"%#?areaDescription=%#",kIP,areaDescriptionWSpaceCharacters];
NSURL *JSONURL = [NSURL URLWithString:requestString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:JSONURL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSError *myError;
NSMutableDictionary *productionSchedule = [[NSMutableDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
completion(productionSchedule,myError);
}];
[dataTask resume];
}
Please Help! This was working with sendSynchronousRequest I am starting to dislike dataTaskWithRequest.
The NSURLSession code you have is correct, I confirmed with a valid URL.
You stopped checking to see if data is nil before attempting to JSON parse it. If you add that check back I bet you'll find that there is an error and data is in fact nil.
Change to:
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// handle request error
if (error) {
completion(nil, error);
return;
}
NSError *myError;
NSMutableDictionary *productionSchedule = [[NSMutableDictionary alloc]initWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&myError]];
completion(productionSchedule,myError);
}];
I would recommend also checking myError before attempting to set it to productionSchedule (which could also cause a crash).
I need to get place_id from facebook for facebook checkin section.For that i am using following code.While requesting place id with access token sometines i get message as malformed access token,sometimes expired.
NSString *fbToken = [FBSession activeSession].accessTokenData.accessToken;
NSString *fbURL = [NSString stringWithFormat:#"https://graph.facebook.com/search?q=ritual&type=place¢er=9.952786,76.339828&distance=1000&access_token=%#",fbToken];
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#",fbURL, fbToken]];
NSLog(#"URL:%#",URL);
NSURLRequest *placeRequest = [NSURLRequest requestWithURL:URL];
//Send the request
[NSURLConnection sendAsynchronousRequest:placeRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if (!connectionError) {
NSDictionary *Data = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSLog(#"data = %#"Data);
}
}];
Here's the method that's giving me an error when I compile (see the requestMainPage method)
- (void)loginToMistarWithPin:(NSString *)pin password:(NSString *)password success:(void (^)(void))successHandler failure:(void (^)(void))failureHandler {
NSURL *url = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
//Create and send request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *postString = [NSString stringWithFormat:#"Pin=%#&Password=%#",
[self percentEscapeString:pin],
[self percentEscapeString:password]];
NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postBody];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse
*response, NSData *data, NSError *error)
{
// do whatever with the data...and errors
if ([data length] > 0 && error == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
// assuming you validated that everything was successful, call the success block
if (successHandler)
successHandler();
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from login), it was = %#", loggedInPage);
if (failureHandler)
failureHandler();
}
}
else {
NSLog(#"error: %#", error);
if (failureHandler)
failureHandler();
}
}]; }
- (NSData *)requestMainPage {
NSData *returner;
//Now redirect to assignments page
NSURL *homeURL = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/PortalMainPage"];
NSMutableURLRequest *requestHome = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[requestHome setHTTPMethod:#"GET"]; // this looks like GET request, not POST
[NSURLConnection sendAsynchronousRequest:requestHome queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *homeResponse, NSData *homeData, NSError *homeError) //Error is in this line.
{
// do whatever with the data...and errors
if ([homeData length] > 0 && homeError == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:homeData options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *homePage = [[NSString alloc] initWithData:homeData encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from home), it was = %#", homePage);
return homePage;
}
}
else {
NSLog(#"error: %#", homeError);
}
return [NSString stringWithFormat:#"%#", homeData];
}]; }
The error came up when I decided I wanted my method (requestMainPage) to have a return type of NSData * rather then just returning void.
So I'm not sure exactly where the problem is.
I figured out my mistake, you can't return values from inside a block.
So if I remove the return homeError and return [NSString stringWithFormat:#"%#", homeData];, the problems go away and I can compile