Delayed Response when NSURLConnection is used with sendAsynchronousRequest - ios

Correct me if I am wrong. please easy go on me. I am not expert in iOS.
I tried sending HTTP Request with two approaches.
1)
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
The response is so quick, the time delay to get response is constant. One additional effort is to handle the response data with delegate mechanism.
Hence I approached with (2)
2).
[NSURLConnection sendAsynchronousRequest:theRequest
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
NSString *strData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog (#" THE RESPONSE DATA IS %#", strData);
UIAlertView *alView = [[UIAlertView alloc] initWithTitle:#"Process Done" message:#"MY Message" delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK", nil];
[alView show];
NSMutableData *mData = [NSMutableData dataWithData:data];
[self parseXML:mData]; // XML Parsing.
}];
With the (2) approach, I could see inconsistent delay of getting response.
My Understanding
Since I queue the block in NSOperationQueue, it is not guaranteed to be executed immediately.
If my understanding is correct, then what is the correct approach so, that the queued operation is handled immediately.

Related

Best way to handle multiple NSURL connections

I am trying to create an xls sheet programmatically. To fill the sheet, I am making the multiple NSURLConnection around 100. Right now, my approach is :
Make a connection and store the data into an array . This array has 100 objects.
Now take the first object and call the connection . Store the data. And make the second connection with 2nd object in the array. This continues till the last object in the array.
It takes on average 14 seconds to finish the 100 connections. Is there any way to implement the NSURLConnection to get the response in a faster way?
Till yesterday I followed the basic approach like:
Declaring the properties:
#property (nonatomic,strong) NSURLConnection *getReportConnection;
#property (retain, nonatomic) NSMutableData *receivedData;
#property (nonatomic,strong) NSMutableArray *reportArray;
Initializing the array in viewDidLoad:
reportArray=[[NSMutableArray alloc]init];
Initializing the NSURLConnection in a button action :
/initialize url that is going to be fetched.
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"****/%#/crash_reasons",ID]];
//initialize a request from url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request addValue:tokenReceived forHTTPHeaderField:#"**Token"];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
//initialize a connection from request
self.getReportConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
Processing the received data:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data{
if (connection==_getVersionConnection) {
[self.receivedData_ver appendData:data];
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *e = nil;
NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingMutableContainers error: &e];
[JSON[#"app_versions"] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (![obj[#"id"] isEqual:[NSNull null]] && ![reportArray_ver containsObject:obj[#"id"]]) {
[reportArray_ver addObject:obj[#"id"]];
}
NSLog(#"index = %lu, Object For title Key = %#", (unsigned long)idx, obj[#"id"]);
}];
if (JSON!=nil) {
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Version Reports succesfully retrieved" message:#"" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
}
}
Calling the another connection after one finishes:
// This method is used to process the data after connection has made successfully.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
if (connection==getReportConnection) {
//check and call the connection again
}
}
And today, I tried the NSURLConnection with sendAsync to fire all the connections one after other using loop,and it worked pretty well.
self.receivedData_ver=[[NSMutableData alloc]init];
__block NSInteger outstandingRequests = [reqArray count];
for (NSString *URL in reqArray) {
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:URL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
[self.receivedData appendData:data]; //What is the use of appending NSdata into Nsmutable data?
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *e = nil;
NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingMutableContainers error: &e];
NSLog(#"login json is %#",JSON);
[JSON[#"app_versions"] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (![obj[#"id"] isEqual:[NSNull null]] && ![reportArray_ver containsObject:obj[#"id"]]) {
[reportArray_ver addObject:obj[#"id"]];
}
NSLog(#"index = %lu, Object For title Key = %#", (unsigned long)idx, obj[#"id"]);
}];
outstandingRequests--;
if (outstandingRequests == 0) {
//all req are finished
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Version Reports succesfully retrieved" message:#"" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
}];
}
This time it took half the time to complete the 100 requests than the old procedure, Is there any faster way exists other than the asynReq?.What is the best scenario to use NSURLconnection and NSURLConnection with asyncReq?
A couple of observations:
Use NSURLSession rather than NSURLConnection (if you are supporting iOS versions of 7.0 and greater):
for (NSString *URL in URLArray) {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
// configure the request here
// now issue the request
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// check error and/or handle response here
}];
[task resume];
}
If you absolutely have to issue 100 requests, then issue them concurrently like your sendAsynchronousRequest implementation (or my dataTaskWithRequest), not sequentially. That's what achieves the huge performance benefit.
Note, though, that you have no assurances that they'll completely in the order that you issued them, so you will want to use some structure that supports that (e.g. use NSMutableDictionary or pre-populate the NSMutableArray with placeholders so you can simply update the entry at a particular index rather than adding an item to the array).
Bottom line, be aware that they may not finish in the same order as requested, so make sure you handle that appropriately.
If you keep 100 separate requests, I'd suggest that you test this on a really slow network connection (e.g. use the Network Link Conditioner to simulate really bad network connection; see NSHipster discussion). There are problems (timeouts, UI hiccups, etc.) that only appear when doing this on slow connection.
Rather than decrementing a counter of number of pending requests, I'd suggest using dispatch groups or operation queue dependencies.
dispatch_group_t group = dispatch_group_create();
for (NSString *URL in URLArray) {
dispatch_group_enter(group);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
// configure the request here
// now issue the request
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// check error and/or handle response here
// when all done, leave group
dispatch_group_leave(group);
}];
[task resume];
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// do whatever you want when all of the requests are done
});
If possible, see if you can refactor the web service so you are issuing one request that returns all of the data. If you're looking for further performance improvement, that's probably the way to do it (and it avoids a lot of complexities involved when issuing 100 separate requests).
BTW, if you use delegate based connection, like you did in your original question, you should not be parsing data in didReceiveData. That should only be appending data to a NSMutableData. Do all of the parsing in connectionDidFinishLoading delegate method.
If you go to block-based implementation, this issue goes away, but just an observation on your code snippets.
Using sendAsynchronous is a great way to improve code organization. I'm sure with some careful scrutiny, we could improve the speed at the margin, but the way to noticeably improve speed is to not make 100 requests.
If the response bodies are small, create an endpoint that answers a conjunction of the results.
If the response bodies are large, then you're requesting more data than the user needs at the moment. Hold up the UI only on what user needs to see, and get the rest silently (... or, maybe better than silently, lazily).
If you don't control the server, and the response bodies are small, and the user needs all or most of to carry on with the app, then you can start working on performance at the margins and UI tricks to amuse user while the app works, but usually one of those constraints -- usually the latter -- can be relaxed.

NSMutableRequest not working for the second time (ARC enabled)

I am performing JSON POST request by clicking UIButton and after the submission, segue perform can be done. So, After submitting values, I cannot perform POST request anymore. It shows status code 200 and response is OK. But, data is not reflected in the Backend. Here is my code:
(IBAction)transitsurveydone:(id)sender {
if([tempArray count]!=0){
/* alert= [[UIAlertView alloc] initWithTitle:#"Survey Submission"
message:#"Please Enter your location"
delegate:self
cancelButtonTitle:#"Modify"
otherButtonTitles:#"Submit",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
alert.tag=2;
[alert show];*/
NSLog(#"Caption array is %# %#",captionArray,tempArray);
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"myURL"]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSMutableDictionary *postDict = [[NSMutableDictionary alloc]init];
NSMutableDictionary *d=[[NSMutableDictionary alloc] initWithObjectsAndKeys:#10,#"\"Bus\"", nil];
NSMutableArray *m=[[NSMutableArray alloc] init];
NSString *str1,*str2,*str3,*str4;
// Checking the format
if(tempArray.count==1){
for (int x=0; x<1; x++) {
str1=[NSString stringWithFormat:#"\"%#\"",[captionArray objectAtIndex:x]];
[d setObject:[tempArray objectAtIndex:x] forKey:str1];
}
[request setHTTPBody:[[NSString stringWithFormat: #"{\n \"instance\" : %#,\n \"response_method\": \"web\",\n \"routes\": [\n {%#:%#}\n ]\n}",randomString,str1,[d objectForKey:str1] ]dataUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"%#:%#",str1,[d objectForKey:str1]);
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
// Handle error...
return;
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSLog(#"Response HTTP Status code: %ld\n", (long)[(NSHTTPURLResponse *)response statusCode]);
NSLog(#"Response HTTP Headers:\n%#\n", [(NSHTTPURLResponse *)response allHeaderFields]);
}
NSString* body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response Body:\n%#\n", body);
}];
[task resume];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *respData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"~~~~~ Status code: %d", [response statusCode]);
if([response statusCode]==200){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Transit Survey submitted" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
alert.transform = CGAffineTransformMakeTranslation( 10, 740);
[alert show];
[self performSelector:#selector(dismissAlert:) withObject:alert afterDelay:1.0f];
submitteddonthide=NO;
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Transit Survey Submission Failed" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
alert.transform = CGAffineTransformMakeTranslation( 10, 740);
[alert show];
[self performSelector:#selector(dismissAlert:) withObject:alert afterDelay:1.0f];
}
if([prefs integerForKey:#"humandone"]==1){
[self performSegueWithIdentifier:#"transittohuman" sender:nil];
}
else{
[self performSegueWithIdentifier:#"gobackfromtransit" sender:nil];
}
}
`
The above code is in IBAction
Your code looks fine and there is no any issues.
If this issue is happens all the time, add "Advanced Rest Client" add-on to chrome browser and test your server URL passing respective input values. If this process also can't be able to update values on your backend there should be some issue on your backend.
A couple of thoughts:
You are using status code to determine whether the server inserted the data correctly or not. You should actually have your web service build an affirmative response (in JSON, would be great) that says whether data was successfully inserted or not. You should not be relying solely on the web server's request response code.
I would observe the request with something like Charles and make sure it looks OK.
You're building a JSON request manually, which is very fragile. I would suggest using Charles to observe the request, and copy and paste it into http://jsonlint.com and make sure it's OK.
Even better, use NSJSONSerialization which is more robust and easier to use.
Also, you're sending this request twice. Lose this second request (you shouldn't do synchronous requests, anyway) and put all of your confirmation logic inside the session's completion handler block.
Yes. After struggling a bit, Clearing cookies helped me a lot :-
Here is a chunk of code, which is pretty much simple
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [cookieStorage cookiesForURL:[NSURL URLWithString:urlString]];
for (NSHTTPCookie *cookie in cookies) {
NSLog(#"Deleting cookie for domain: %#", [cookie domain]);
[cookieStorage deleteCookie:cookie];
}
Thank you Mr. reddys and Rob for the suggestions

How to run a NSURLConnection in background in iOS

I am working with an app which is todo list organizer, where user adds notes. I am using coredata DB to store the notes. As I am providing sync feature, I am parsing JSON data to server, and also getting JSON data from server.
I am using NSURLConnection API and its delegate functions
- (void)pushData
{
loop through the notes array and send notes 1 by one
[[request setValue:#"application/json;charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:jsonData];
m_dataPush = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
[m_dataPush start];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
Process response from server, save to core DB
and again pushData if any modified and again process the response
}
I call this API, on appEnterBackground and appBecomeActive, because, I want the data to updated on multiple devices.
The problems, which I am facing is that
1) When the notes are more, app is getting stuck, when we exit and open the app and start adding notes.
2) I tried using GCD, but then my NSURLConnection doesnot send me any response
Regards
Ranjit
Ranjit: Based on your comments in the different responses, I suspect you are sending the 1st request from the main thread. When you receive the 1st response, you process it in the background, and then send the 2nd request also from the background. The subsequent requests should be sent from the main thread
[self performSelectorOnMainThread:#selector(myMethodToOpenConnection:)
withObject:myObject
waitUntilDone:NO];
otherwise the thread exits before the delegate is called
You can use NSOperation Queue with NSURLConnection like this
//allocate a new operation queue
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//Loads the data for a URL request and executes a handler block on an
//operation queue when the request completes or fails.
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:queue
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error) {
if ([data length] >0 && error == nil){
//process the JSON response
//use the main queue so that we can interact with the screen
NSString *myData = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(#"JSON data = %#", myData);
NSDictionary *myDict = [myData JSONValue];
}
}];
it will do all the processing in the background.
NSURLConnection provides a convenience method called sendAsynchronousRequest: completionHandler: that does the GCD work for you. You can tell it to run the completion handler on the main thread.
Using it, your code would get simpler as follows:
// place a declaration in your .h to make it public
- (void)pushDataWithCompletion:(void (^)(BOOL, NSError*))completion;
- (void)pushDataWithCompletion:(void (^)(BOOL, NSError*))completion
{
// setup your connection request...
[[request setValue:#"application/json;charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:jsonData];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// whatever you do on the connectionDidFinishLoading
// delegate can be moved here
if (!error) {
// did finish logic here, then tell the caller you are done with success
completion(YES, nil);
} else {
// otherwise, you are done with an error
completion(NO, error);
}
}];
}
Exactly what you pass back in the block depends on what the callers care about. It's common to make some aspect of the data you collected one of the block params.
EDIT - I left out the pointer notation (*) after NSError above.
Also, say you have an array of objects that needs to be processed by the server. This method is good for one call. To handle several, lets give it a parameter. Say that each note is an NSString *;
- (void)pushNote:(NSString *)note withCompletion:(void (^)(BOOL, NSError*))completion {
// Code is the same except it forms the request body using the note parameter.
}
If the real task is to do work for several notes, you need a method that calls this one repeatedly, then tells its caller that its done.
- (void)pushNotes:(NSArray *)notes withCompletion:(void (^)(BOOL, NSError*))completion {
// if there are no more notes, we are done
if (!notes.count) return completion(YES, nil);
NSString *nextNote = notes[0];
NSArray *remainingNotes = [notes subarrayWithRange:NSMakeRange(1, notes.count-1)];
[self pushNote:nextNote withCompletion:^(BOOL success, NSError*error) {
// if success, do the rest, or else stop and tell the caller
if (success) {
[self pushNotes:remainingNotes withCompletion:completion];
} else {
completion(NO, error);
}
}];
}

Displaying error messages after modal dismissal

So just like the question suggests, I'm trying not to freeze up the UI after the user sends some data to the server. In my case, they're possibly sending a lot of data and server side I have to do a foreach loop for multiple queries.
While all that is happening, I don't want the user to wait for a response so I'm dismissing the modal VC after "Send" is clicked. The data still gets inserted into the database but what if there's an error? Right now I'm showing a UIAlertView after the modal VC is dismissed but I get a bad access error. What's the best way of showing an error?
- (void)send:(id)sender{
if ([[Data sharedInstance].someData objectForKey:#"time"] != NULL) {
[self dismissViewControllerAnimated:YES completion:^(){
NSMutableDictionary *paramDic = [NSMutableDictionary new];
[paramDic setValue:[[Data sharedInstance].someData objectForKey:#"oneArray"] forKeyPath:#"oneArray"];
[paramDic setValue:[NSArray arrayWithObjects:[[[Data sharedInstance].someData objectForKey:#"two"] valueForKey:#"Name"], [[[Data sharedInstance].someData objectForKey:#"two"] valueForKey:#"State"], [[[Data sharedInstance].someData objectForKey:#"two"] valueForKey:#"Country"], nil] forKeyPath:#"twoArray"];
[paramDic setValue:[[[Data sharedInstance].someData objectForKey:#"three"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKeyPath:#"three"];
[paramDic setValue:[[NSUserDefaults standardUserDefaults] valueForKey:#"username"] forKey:#"username"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:paramDic options:NSJSONWritingPrettyPrinted error:nil];
NSURL *url = [NSURL URLWithString:#"http://localhost/myapp/handleData.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSString *length = [NSString stringWithFormat:#"%d", jsonData.length];
[request setValue:length forHTTPHeaderField:#"Content-Length"];
[request setValue:#"json" forHTTPHeaderField:#"Data-Type"];
[request setHTTPBody:jsonData];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if (![httpResponse statusCode] == 200 || ![[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding] isEqualToString:#"success"]) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Problem on the server. Please try again later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}];
}];
}
That's how I'm doing it now...what's a better way?
The above answer is valuable. But I think this is what causes the problem.
Change:
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Problem on the server. Please try again later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
To:
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Problem on the server. Please try again later." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
Hope this helps.
I'm thinking the issue has to do with your nested completion blocks. Because you place your web service call in the modal dismissal completion block, by the time it finishes and starts to execute your URL completion block, the class/controller in charge of that block has already been forgotten/destroyed/deallocated/whatever. At the very least, the view no longer exists where you're trying to present your alert view. You've listed self as the delegate of that alert view, but self doesn't exist anymore.
Try this first: instead of trying to display your alert on a no-longer-in-memory view from a background thread (big no-no even if the view still existed), try posting a notification to the main thread that you can pick up elsewhere in your app (such as your root view controller) and present the alert from there:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if (![httpResponse statusCode] == 200 || ![[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding] isEqualToString:#"success"]) {
dispatch_async(dispatch_get_main_queue(),^{
// observe this notification in root view controller or somewhere
// that you know will be in memory when it fires
[[NSNotificationCenter defaultCenter] postNotificationName:#"ErrorAlert"
object:nil
userInfo:imageDict];
});
}
}];
If that still doesn't work because the app has discarded your completion block when the view was dismissed, you will need to create a separate class that is in charge of sending this web service request instead of doing it all directly in the completion block. But still, remember to present your alert on the main thread :)

How to make charge using stripe in iOS?

I have read all detail about stripe integration in iOS app from here. And run the sample app of stripe by downloading from here.
On running this app, I am getting following error when I am testing on iPhone Simulator.
Following method is calling after token received::
- (void)hasError:(NSError *)error
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Error", #"Error")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"OK")
otherButtonTitles:nil];
[message show];
}
//--Called after sucessfully token received ::
- (void)hasToken:(STPToken *)token
{
NSLog(#"Received token %#", token.tokenId);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"https://example.com"]];
request.HTTPMethod = #"POST";
NSString *body = [NSString stringWithFormat:#"stripeToken=%#", token.tokenId];
request.HTTPBody = [body dataUsingEncoding:NSUTF8StringEncoding];
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
if (error) {
[self hasError:error];
} else {
NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"\nStr is :::%#",str);
NSLog(#"\n\nResponse is :::%#",response);
[self.navigationController popViewControllerAnimated:YES];
}
}];
}
Please tell me how to resolve this problem and make a credit card payment on iOS app because in this sample code, there is information about payment.
You are using example.com. Replace it first with your own server address.
For charging a card in Stripe you need a server module. Here is detail explanation of how to charge your card via server module. If you are using parse as backend you can always use cloudcode for this purpose.
Here is raywenderlich's explanation of making payment system with python backend.

Resources