Post on website works on simulator but not on device? - ios

I want to use the web service in my app and upload post on the website, at first I used ASIFormRequest API, it worked on simulator but did not work on device, I asked a question here and someone told me to change the API and use the RestKit (Here is the link for my previous question)
Right now I'm using RestKit API and I got the same problem, I cannot post on the website by device, but It works when I use simulator. Although it doesn't allow me to post but I can login both by the simulator and the device.
Here is my code for POST:
- (IBAction)addLinkPressed:(UIButton *)sender {
[RKClient clientWithBaseURLString:#"http://MyWebsite.com"];
NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:
self.linkField.text, #"url",
self.linkTitleField.text, #"title",
self.linkSummaryField.text, #"summary",
nil];
[[RKClient sharedClient] post:#"/send_link.php" params:params delegate:self];
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
NSRange range = [[error localizedDescription] rangeOfString:#"-1012"];
if (range.length > 0){
//Do whatever here to handle authentication failures
}
RKLogError(#"Hit error: %#", error);
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response
{
if ([request isGET]) {
// Handling GET /foo.xml
if ([response isOK]) {
// Success! Let's take a look at the data
NSLog(#"Retrieved XML: %#", [response bodyAsString]);
}
} else if ([request isPOST]) {
// Handling POST /other.json
if ([response isJSON]) {
NSLog(#"Got a JSON response back from our POST!");
}
} else if ([request isDELETE]) {
// Handling DELETE /missing_resource.txt
if ([response isNotFound]) {
NSLog(#"The resource path '%#' was not found.", [request resourcePath]);
}
}
NSLog(#"HTTP status code: %d", response.statusCode);
NSLog(#"HTTP status message: %#", [response localizedStatusCodeString]);
NSLog(#"Header fields: %#", response.allHeaderFields);
NSLog(#"Body: %#", response.bodyAsString);
}
Here is the error that I receive for RestKit API:
2012-09-11 22:33:01.053 (NameOfMyApp)[16271:707] I restkit.support:RKCache.m:189 Invalidating cache at path: /var/mobile/Applications/897B1DEA-1767-4F5C-AC8F-1809075C5CA9/Library/Caches/RKClientRequestCache-(Mywebsite).com/SessionStore
2012-09-11 22:33:01.057 (NameOfMyApp)[16271:707] I restkit.network.reachability:RKReachabilityObserver.m:123 Reachability observer initialized with IP address: 0.0.0.0.
2012-09-11 22:33:01.075 (NameOfMyApp)[16271:707] I restkit.network.reachability:RKReachabilityObserver.m:391 Network availability has been determined for reachability observer <RKReachabilityObserver: 0x10066330 host=0.0.0.0
2012-09-11 22:33:01.075 (NameOfMyApp)[16271:707] I restkit.network.reachability:RKReachabilityObserver.m:391 Network availability has been determined for reachability observer <RKReachabilityObserver: 0x10066330 host=0.0.0.0 isReachabilityDetermined=YES isMonitoringLocalWiFi=NO reachabilityFlags=-R -----l->
2012-09-11 22:33:01.325 (NameOfMyApp)[16271:707] I restkit.network:RKRequest.m:689 Status Code: 200
2012-09-11 22:33:01.328 (NameOfMyApp)[16271:707] HTTP status code: 200
2012-09-11 22:33:01.332 (NameOfMyApp)[16271:707] HTTP status message: no error
2012-09-11 22:33:01.338 (NameOfMyApp)[16271:707] Header fields: {
"Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
Connection = "Keep-Alive";
"Content-Encoding" = gzip;
"Content-Length" = 4679;
"Content-Type" = "text/html";
Date = "Wed, 12 Sep 2012 03:33:02 GMT";
Expires = "Thu, 19 Nov 1981 08:52:00 GMT";
"Keep-Alive" = "timeout=5, max=100";
Pragma = "no-cache";
Server = Apache;
Vary = "Accept-Encoding";
}
2012-09-11 22:33:01.345 (NameOfMyApp)[16271:707] Body: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Ater these code, it shows the HTML code of the address that I use for POST ( http://MyWebsite.com/send_link.php)
Any Idea how can would be appreciated, I really need help :(

I found the answer, In simulator it doesn't need to put http:// at the beginning of the url addresses, but on device, if I do not input http:// the website that I use their web service doesn't allow me to POST. Isn't that weird!
Thank you guys for your comments.
One more thing is, when I close the app and reopen it I have to do login, any idea how I can make the username and password persistence?

Related

NSURLSessionUploadTask response content data is null

Here's where I am so far with NSURLSessionUploadTask:
iOS application starts an NSURLSessionUploadTask using POST
server receives HTTP POST request
server reads content of the request so data is uploaded
server sends HTTP response to iOS consisting of the following:
HTTP/1.1 200 OK
Server: BaseHTTP/0.3 Python/2.7.10
Date: Fri, 30 Oct 2015 16:15:21 GMT
Content-Type: text/html
Content-Length: 96
<html><head><title>POST RESPONSE</title></head><body><p>The file was uploaded.</p></body></html>
iOS application receives response and NSLogs the response via NSURLSessionTaskDelegate -> URLSession:task:didCompleteWithError:
<NSHTTPURLResponse: 0x15d95110> { URL: http://10.157.239.129:42000/ } { status code: 200, headers {
"Content-Length" = 96;
"Content-Type" = "text/html";
Date = "Fri, 30 Oct 2015 16:15:21 GMT";
Server = "BaseHTTP/0.3 Python/2.7.10";
} }
however, when I try to NSLog the response content when the method NSURLSessionTaskDelegate: -> URLSession:dataTask:didReceiveData:
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
{
// Called when data task has received some data (not applicable for straight upload?)
if (data != NULL)
{
NSLog(#"%s: %#", __PRETTY_FUNCTION__,[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}
else
{
NSLog(#"%s: but no actual data received.", __PRETTY_FUNCTION__);
}
// If we are not in the "active" or foreground then log some background information to the console
if (UIApplication.sharedApplication.applicationState != UIApplicationStateActive)
{
[BackgroundTimeRemainingUtility NSLog];
}
}
is called I get this for output:
2015-10-30 12:15:22.648 NSURLSessionUploadTaskExample[215:7286] -[ViewController URLSession:dataTask:didReceiveData:]: (null)
what is odd about this is that the response should not have triggered the if statement block if the data is null!
I also have evidence that the response data WAS sent to the iOS application via Wireshark. Here's a packet capture of the HTTP response from the server:
Can anyone tell me why iOS appears to be losing the content in the HTTP response?
Because I was able to trace the HTTP 200 response from the server to the iOS application, I suspected the iOS application had a problem. I set a breakpoint at the line:
NSLog(#"%s: %#", __PRETTY_FUNCTION__,[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
and examined the data object with the debugger:
Each of the 96 bytes in the response content was getting to NSURLSessionTaskDelegate: -> URLSession:dataTask:didReceiveData: So the NSString decoding in the NSLog was at fault. Now things were making sense. I was sending a 96 byte ASCII response, not a 96 byte UTF8 response!
I replaced the NSString decoder with the following:
NSLog(#"%s: %#", __PRETTY_FUNCTION__,[[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding: NSASCIIStringEncoding]);
Problem solved with the following output:
2015-11-02 10:04:47.086 NSURLSessionUploadTaskExample[561:363449] -[ViewController URLSession:dataTask:didReceiveData:]:<html><head><title>POST RESPONSE</title></head><body><p>The file was uploaded.</p></body></html>
I've also put a very basic NSURLSessionUploadTask example application and webserver on github here.

Get the value of Error-Message in failure block of AFHTTPRequestOperation

I need to get the value of Error-Message in the failure block of my request.
Here's the error:
Error Domain=com.alamofire.error.serialization.response Code=-1011
"Request failed: bad request (400)" UserInfo=0x165151b0
{NSErrorFailingURLKey=http://203.125.112.203:8090/megumi01/api/zipData?lastSynced=1441161682,
com.alamofire.serialization.response.error.response= { URL:
http://203.125.112.203:8090/megumi01/api/zipData?lastSynced=1441161682
} { status code: 400, headers {
"Access-Control-Allow-Headers" = "x-requested-with, Authorization, Content-Type, Accept";
"Access-Control-Allow-Methods" = "POST, GET, OPTIONS, DELETE, PUT";
"Access-Control-Allow-Origin" = "*";
"Access-Control-Max-Age" = 3600;
"Cache-Control" = "no-cache, no-store, max-age=0, must-revalidate";
Connection = close;
"Content-Type" = "application/json;charset=UTF-8";
Date = "Wed, 02 Sep 2015 10:38:57 GMT";
"Error-Code" = 0808;
"Error-Message" = "No updates available";
Expires = 0;
Pragma = "no-cache";
Server = "Apache-Coyote/1.1";
"Transfer-Encoding" = Identity;
"X-Application-Context" = "application:9090";
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = DENY;
"X-XSS-Protection" = "1; mode=block"; } }, NSLocalizedDescription=Request failed: bad request (400)}
I have tried putting "error" into NSData so I could convert it to NSDictionary but it becomes nil.
May I know how could I get the value of the custom header "Error-Message"?
TYIA!
below code may help you. try it.
NSLog(#"status code :%ld",(long)[operation.response statusCode]);
NSLog(#"Failure Response %#, %#", error, operation.response.description);
After thinking straightly, I was able to get the proper way to get the custom header in failure block of AFHTTPRequestOperation.
NSDictionary *userInfo = [error userInfo];
NSHTTPURLResponse *alamofireResponse = [userInfo objectForKey:#"com.alamofire.serialization.response.error.response"];
NSDictionary *allHeaders = [alamofireResponse allHeaderFields];
NSString *customMessage = [allHeaders objectForKey:#"Error-Message"];

How to use PromiseKit to handle header-only response?

I'm using PromiseKit in an IOS app to communicate with a Rails RESTful backend,
and there're some calls that return only header, say by executing head 200 on the backend.
What I've tried is:
I used [NSURLConnection POST:url formURLEncodedParameters:parameters] to post data to backend, the backend did receive the data and responded with a head 200 message, but PromiseKit is reporting the following exception:
2014-07-31 11:19:39.501 HelloPOS[13223:60b] Error
Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be
completed. (Cocoa error 3840.)" (No value.) UserInfo=0xa4c5a90
{NSDebugDescription=No value., PMKURLErrorFailingDataKey={length = 1, capacity = 16, bytes = 0x20},
PMKURLErrorFailingURLResponseKey= { URL:
http://SOME_APP.SOME_HOST.com/api/v1/sales.json } { status code: 200,
headers {
"Cache-Control" = "max-age=0, private, must-revalidate";
Connection = "keep-alive";
"Content-Length" = 1;
"Content-Type" = "application/json";
Date = "Thu, 31 Jul 2014 03:19:25 GMT";
Etag = "\"7215ee9c7d9dc229d2921a40e899ec5f\"";
Server = "WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)";
Via = "1.1 vegur";
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = SAMEORIGIN;
"X-Request-Id" = "5a1c1aa1-4b42-41ea-8397-a5df8fa956bc";
"X-Runtime" = "0.013359";
"X-Xss-Protection" = "1; mode=block"; } }}
It's probably because header-only response has no body, and the error is caused
PS: I've changed the URL in the exception message
The problem is the server claims that the response has a JSON content of length 1 byte. But the response does not parse into JSON, so PromiseKit errors that promise.
PromiseKit doesn't provide a mechanism to ignore the response, but you could easily make your own promise here if you cannot fix the server to provide correct responses.
#import <OMGHTTPURLRQ.h>
- (PMKPromise *)myPromise:(id)args {
id rq = [OMGHTTPURLRQ POST:url:args];
id q = ;
return [PMKPromise new:^(PMKPromiseFulfiller fulfill, PMKPromiseRejecter reject){
[NSURLConnection sendAsynchronousRequest:rq queue:q completionHandler:^(id rsp, id data, NSError *urlError) {
if (urlError) {
reject(urlError)
} else {
fulfill(nil);
}
}];
}];
}
EDIT: PromiseKit now works around this specific situation, so you should no longer get this specific error.

NSURLConnection, NSURLAuthenticationChallenge failure response

When trying to log in to my app with iOS7 I'm getting a failure response with some description. This is NSLog of NSURLAuthenticationChallenge failureResponse:
<NSHTTPURLResponse: 0xa383570> { URL: <URL> } { status code: 401,headers {
"Content-Length" = 1385;"Content-Type" = "text/html;charset=utf-8";
Date = "Fri, 13 Jun 2014 12:14:24 GMT";
Server = "Apache-Coyote/1.1";
"Www-Authenticate" = "Basic realm=\"booo\"";
"x-errorCode" = 02;
"x-errorDescription" = "com.idealination.core.server.client.http.ServerException:
Request failed: <URL> Status: CLIENT_ERROR_UNAUTHORIZED
Error: #Unauthorized :: Invalid userid or password.";
} }
and I need that last line to know what error do I get. But when I use iOS6 and iPhone 3gs I get only:
<NSHTTPURLResponse: 0x1c507ae0>
What should I do to get a response like using iOS7? And why I'm getting a different response?
You should not be looking for the last line, you should be looking for the HTTP Status Code, in this case 401.
if(urlResponse.statusCode == 401) { }
If you need to convert that into what the status code means as a string use
NSString *status = [NSHTTPURLResponse localizedStringForStatusCode:urlResponse.statusCode];

parse json from post request ios afnetworking

I'm working on an iOS app (pretty new to iOS) and I have my registration flow working where i post data to my server... The server returns JSON, but my question is, how do I parse that into variables?
The data that it returns is:
{"token":"67f41f60-9a9a-11e3-8310-11b6baf18c40","userId":13,"stationId":1}
The code I'm using to make the post request is:
[manager POST:#"http://localhost:3000/service/register_user/" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error!!!!!: %#", error);
}];
Also, when I make the post request, this is what I get in the log in xcode
2014-02-20 20:50:39.799 FlashoverResponse[4668:70b] Error!!!!!: Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0x8a5e4f0 {NSErrorFailingURLKey=http://localhost:3000/service/register_user/, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x8a5e200> { URL: http://localhost:3000/service/register_user/ } { status code: 200, headers {
Connection = "keep-alive";
"Content-Length" = 74;
"Content-Type" = "text/html; charset=utf-8";
Date = "Fri, 21 Feb 2014 01:50:39 GMT";
"X-Powered-By" = Express;
} }, NSLocalizedDescription=Request failed: unacceptable content-type: text/html}
Is your server configured to respond in text/json application/json?
and/or have you set this?
manager.responseSerializer.acceptableContentTypes
it takes a NSSet of content types this parser will attempt to parse, if you cannot change the server to respond in json you can add text/html into that set, so the parser will parse it anyway.

Resources