Ios – Sending POST request with NSURLConnection

iosiphonejsonobjective cweb services

I am sending a post Request with the some parameter in the request body.

Here is the iOS code:

 NSURL *url = [NSURL URLWithString:purchaseURL];

 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
 NSString *requestString = [NSString stringWithString:@"userid=1&couponid=1&Ccnum=7b6cd9a44365752cf39c1edf97890b72&Cctype=Visa&Cvv=434&Billingfirstname=Ankit&Billinglastname=Ankit&Street=some&getCity=mycity&State=mystate&getZip=54355&Ccexpmonth=5&Ccexpyear=2012&Phone=43423342"];
NSMutableData *postData=[NSMutableData data];
[postData appendData:[requestString dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", [postData length]] forHTTPHeaderField:@"Content-Length"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];

NSLog(@"content length %d",[postData length]);
[request setValue:@"text/html" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];


NSLog(@"purchage url string %@",postData);

connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];


  NSAssert(self.connection != nil, @"Failure to create URL connection.");

This is the php file that will handle the post request. It handles the input and the response is in JSON format.

 public function restpurchaseAction(Request $request)
 {

    $userid = $_POST['userid'];
    $couponid = $POST['couponid'];



    //Check that email was verified
//Get the user object to compare id to the listed deals id
if(!$user->getEmailVerified())
{
    return "Error:  Must verify email before making a purchase.";
}


// Initialize error varible
$error = "";


//get the currently logged in user
$repository = $this->getDoctrine()
        ->getRepository('FrontendUserBundle:User');
        $user = $repository->findOneByUsername($userid);
//get the coupon that is being purchased
$repository = $this->getDoctrine()
    ->getRepository('FrontendUserBundle:Coupon');
    $coupon = $repository->findOneById($couponid);        

//get the number of times the user has purchased and compare to maxper
$repository = $this->getDoctrine()
->getRepository('FrontendUserBundle:Purchase');     
//if they have already purchased max, redirect to error page
$purchases = $repository->findByCouponAndUser($coupon->getId(), $user->getId());
if(count($purchases) >= $coupon->getMaxper() && $coupon->getMaxper() != 0){
    "Error: Coupon purchased maximum number of times.";
}

//get the users profile
$profile = $user->getProfile();

//get the users address
$address = $profile->getAddress();

//initialize the new purchase
$purchase = new Purchase();

//generate the coupon verification code
$currentdate = new \DateTime();
$currentdate->setTimestamp(time());
$interval = new \DateInterval('P'.$coupon->getExpirationdate().'D');
$currentdate->add($interval);
$validationnumber1 = mt_rand(1000000, 9999999);
$validationnumber2 = mt_rand(1000000, 9999999);
$validationnumber = $validationnumber1 . $validationnumber2;

//set up all the values for the purchase object
$purchase->setValidationnumber($validationnumber);
$purchase->setUser($user);
$purchase->setCoupon($coupon);
$purchase->setValid(true);
$purchase->setValidationattempts(1);
$purchase->setExpirationDate($currentdate);
$card = $purchase->getCard();
$card->setCcnum($_POST['Ccnum']);
$card->setCctype($_POST['Cctype']);
$card->setCvv($_POST['Cvv']);
$card->setUserid($user->getId());

//If the form has already been submitted then check if it is a valid CC.  
//If so, then finish the purchase,else return to the start.
if($request->getMethod() == 'POST'){
    //Get post variables for credit card.

        //Live Mode Credentials
        define("AUTHORIZENET_API_LOGIN_ID", "**********");
        define("AUTHORIZENET_TRANSACTION_KEY", "***************");
        //Test Mode Credentials
        //define("AUTHORIZENET_API_LOGIN_ID", "*************");
        //define("AUTHORIZENET_TRANSACTION_KEY", "*****************");
        define("AUTHORIZENET_SANDBOX", false);
        $response="declined";

        //Make sure maxlimit hasn't been reached before processing.
        if($coupon->getMaxLimit() == 0 || $coupon->getNumPurchased()<=$coupon-                                                                                                                                     >getMaxLimit())
        {

        $sale = new AuthorizeNetAIM;

        /*Input coupon information. */
        $item_id = $coupon->getID();
        $item_name = substr($coupon->getCouponname(), 0, 31);
        $item_description = substr($coupon->getDescription(), 0,255);
        $item_quantity = 1;
        $item_unit_price = $coupon->getPrice();
        $item_taxable = FALSE;
        $billingaddress = $purchase->getBillingaddress();
        $card = $purchase->getCard();

        /*Input customer information. */
        $sale->setField('first_name', $_POST['Billingfirstname']);
        $sale->setField('last_name', $_POST['Billinglastname']);
        $sale->setField('email', $user->getEmail);
        $sale->setField('address', $_POST['Street']);
        $sale->setField('city', $_POST['getCity']);
        $sale->setField('state', $_POST['State']);
        $sale->setField('zip', $_POST['getZip']);
        $sale->setField('phone', $_POST['Phone']);


        /*Add information to the sale */
        $sale->addLineItem($item_id, $item_name, $item_description, $item_quantity, $item_unit_price, $item_taxable);
        $sale->amount = $coupon->getPrice();
        $sale->card_num = $_POST['Ccnum'];
        $sale->exp_date = $_POST['Ccexpmonth'] . '/' . $_POST['Ccexpyear'];
        $sale->setField('card_code', $_POST['Cvv']);

        $response = $sale->authorizeAndCapture();
        if ($response->approved) {
            //Prepersist, make sure to remove CVV, and extra CC digits, only store last 4
            $card->setCvv("");
            $lastfour = substr($card->getCcnum(), -4);
            $card->setCcnum($lastfour);
            $transaction_id = $response->transaction_id;
            $purchase->setId = $transaction_id;
            $coupon->incrementNumPurchased();
            $em = $this->get('doctrine')->getEntityManager();
            $em->persist($purchase);
            $em->persist($coupon);
            $em->flush();
            return "Coupon Purchase Successful!";

    }else{

        $error = $response->error_message;
     }
    }
    else{

        $error = "Maximum number of coupons already purchased!";

    }

 }

return $error;


}

I am unable to find the error or any issue in the code. I have also tried ASIHttpRequest/ASIFormDataRequest but was unable to get that to work. Is there a problem in the way i am calling the web service?

Best Answer

The easiest way to debug this, is to actually check what kind of error or response you are getting when starting the connection. To do this, I suggest you let your class implement the following delegate methods:

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    NSLog(@"Did fail with error %@" , [error localizedDescription]);
}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    NSHTTPURLResponse *httpResponse;
    httpResponse = (NSHTTPURLResponse *)response;
    int statusCode = [httpResponse statusCode];
    NSLog(@"Status code was %d", statusCode);
}

This will hopefully give you a better idea of what happens. Hope it helps :)