I am trying to get Alamofire on Swift 3 to send a post request to my Codeigniter based RESTful server (using: https://github.com/philsturgeon/codeigniter-restclient)
I have got the request working but am struggling to get Alamofire to handle any error messages that is being sent back from my REST server
Swift 3 code
Alamofire.request("http://192.168.0.26/index.php/register/user", method: .post, parameters: parameters, headers: headers).responseJSON { response in
print(response.result)
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
In codeigniter im sending an array of errors based on the form validation rules and passing it back like
$this->response($error, 404);
$error is basically a multiarray like this
$error = ["error" => ['field_name' => 'must contain unique value']];
But in my debug section on xcode im getting success and struggling to then handle the json result
SUCCESS
JSON: (
{
error = {
"field_email" = "The Email field must contain a unique value.";
};
},
{
error = {
"field_username" = "The Username field must contain a unique value.";
};
}
)
Could anybody point me in the right direction to basically determine wether the actual result was a success (if it was perform this action) and if not handle the error messages?
Thank you
Try returning a response code 200.
Related
I am building a LARAVEL PHP API in order to be consumed by Delphi 2007.
Basically, in Delphi I am performing a POST and in PHP I am validating the fields. If it fails validation, I need to return code 422 along with the validation errors (array).
In Delphi, I'm using Indy10. In it I have a Client of type TIdHTTP.
To do the POST, I do:
Client.Post(sFullEndPoint, Request, Response);
To get code 422:
Client.ResponseCode;
To get the content of the response:
Response.DataString;
In PHP, if I return only one array of errors, as return $ errors I can handle it in Delphi with Response.DataString, the problem is that I won't know the response code, because it will come 200.
If I return response ($ errors, 422) in PHP, Delphi does not find the value of $errors in response.
I need to get the HTTP code and the response body. Can someone help me?
you can set http response code in php like (refrence : https://www.php.net/manual/en/function.http-response-code.php) :
http_response_code(422);
also in laravel you can do it like :
return response('Your output string', 200)->header('Content-Type', 'text/plain');
but i suggest you to pass response as json and add some information about what is wrong or ... :
$errors = [
[
'error_code'=>1312,
'error_message'=>'name is empty'
]
];
return Response::json($errors, 201); // Status code here
I am making an Alamofire request but getting an odd response. (Swift 3)
Alamofire.request(url, parameters: params).validate(statusCode: 200..<300).responseJSON { response in
if let result = response.result.value {
let JSON = result as! NSDictionary
print("JSON: \(JSON)")
}
This prints the following:
JSON: {
message = "Payment has been charged";
status = Success;
}
Looks solid, but I'm having trouble with two pieces of this response. First off, what is the type of this response. Array? Any? Dictionary? Second, how would I access an element in it. For instance, I want to check to see if the status equals Success.
The last piece of information I have is that my backend (in PHP) produces this with:
$response = array("status"=>"Success","message"=>"Payment has been charged");
Thank you for any insight!
I am using ionic 2 Http.post method with php API. My problem is i am getting Disallowed Key Characters. error on client side. While i figured out in postman that this error arrives when i select form-data option from postman it says "Disallowed Key Characters." in response.
As well as when i select x-www-form-urlencoded option i get the response and my info updated successfully in mySQL server.
Here is my .ts file code:
let headers = new Headers();
headers.append('Access-Control-Allow-Origin:','*');
headers.append('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
let postData = {
FirstName:"testname",
LastName:"testlastname",
PhoneNumber:"12345",
EmailAddress:"test#gmail.com",
InsertedBy:"21"
};
this.http.post('http://localhost:889/api/user/users.json', JSON.stringify(postData),options)
.subscribe((data) => {
//var data = res.json();
console.log(data);
}
I think there is a problem while passing header. Somebody guide me where i am doing wrong?
Here is a screenshot of error:
This api works fine when selecting x-www-form-urlencoded with postman:
I am trying to send a PUT request method from my Android app to my PHP endpoint but in my endpoint the PUT request is not recognized as a PUT request so I return Request method is wrong! message from my endpoint.
Android interface and request execution
Interface for activation
#PUT("device/activate.php")
Call<DeviceRegistry> registryDevice();
Executing the request
DeviceRegistryAPI registryAPI =
RetrofitController.getRetrofit().create(DeviceRegistryAPI.class);
Call<DeviceRegistry> registryCallback = registryAPI.registryDevice();
response = registryCallback.execute();
With this I am expecting a response but I am getting my endpoint error message.
My PHP endpoint
if($_SERVER['REQUEST_METHOD'] == "PUT"){
//doing something with the data
} else {
$data = array("result" => 0, "message" => "Request method is wrong!");
}
I don't know why the $_SERVER['REQUEST_METHOD'] == "PUT" is false but I wonder if I am missing something on Retrofit 2.
More Info.
I am using Retrofit2.
Update 1: Sending json into the body
I am trying to send a json using the body.
It is my json:
{
"number": 1,
"infoList": [
{
"id": 1,
"info": "something"
},
{
"id": 2,
"info": "something"
}
]
}
There are my classes:
class DataInfo{
public int number;
public List<Info> infoList;
public DataInfo(int number, List<Info> list){
this.number = number;
this.infoList = list;
}
}
class Info{
public int id;
public String info;
}
I changed the PUT interface to this:
#PUT("device/activate.php")
Call<DeviceRegistry> registryDevice(#Body DataInfo info);
But I am getting the same problem.
Update 2: Do I need Header
I have this header in my REstfull client:
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Do I need to put this on my request configuration? How do I do that if I need it?
Update 3: checking the request type of my sending post.
Now I am checking the type of the request. Because I am having the same problem with the PUT/POST requests. So If can solved the problem with the put maybe all the problems will be solved.
When I execute the request and asking and inspect the request it is sending the the type (PUT/POST) but in the server php only detect or GET?? (the below example is using POST and the behavior is the same)
Call<UpdateResponse> requestCall = client.updateMedia(downloadItemList);
Log.i("CCC", requestCall .request().toString());
And the output is a POST:
Request{method=POST, url=http://myserver/api/v1/media/updateMedia.php, tag=null}
so I am sending a POST (no matter if I send a PUT) request to the sever but why in the server I am receiving a GET. I am locked!!! I don't know where is the problem.
Update 4: godaddy hosting.
I have my php server hosting on godaddy. Is there any problem with that? I create a local host and everything works pretty good but the same code is not working on godaddy. I did some research but I didn't find any good answer to this problem so Is possible that godaddy hosting is the problem?
PHP doesn't recognize anything other than GET and POST. the server should throw at you some kind of error like empty request.
To access PUT and other requests use
$putfp = fopen('php://input', 'r'); //will be a JSON string (provided everything got sent)
$putdata = '';
while($data = fread($putfp, filesize('php://input')))
$putdata .= $data;
fclose($putfp);
//php-like variable, if you want
$_PUT = json_decode($putdata);
did not tested, but should work.
I guess the problem is that you don't pass any data along with PUT request, that's why PHP recognizes the request as a GET. So I think you just need to try to pass some data using #FormUrlEncoded, #Multipart or probably #Body annotations
To add header in your retrofit2 you should create an interceptor:
Interceptor interceptor = new Interceptor() {
#Override
public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException
{
okhttp3.Request.Builder ongoing = chain.request().newBuilder();
ongoing.addHeader("Content-Type", "application/x-www-form-urlencoded");
ongoing.addHeader("Accept", "application/json");
return chain.proceed(ongoing.build());
}
};
and add it to your client builder:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.interceptors().add(interceptor);
PHP recognises 'PUT' calls. Extracted from PHP.net:
'REQUEST_METHOD' Which request method was used to access the page;
i.e. 'GET', 'HEAD', 'POST', 'PUT'.
You don't need to send any header if your server isn't expecting any
header.
Prior to use Retrofit or any other networking library, you should check the endpoint using a request http builder, like Postman or Advanced Rest Client. To debug the request/response when running your app or unit tests use a proxy like Charles, it will help you a lot to watch how your request/response really looks.
I have a question relating to sending a POST request from an iOS app to a web service written in php, that will ultimately query a MySQL database.
tldr: How do I view the contents of the POST variables directly in the browser window, without refreshing?
Long version:
I had written my Swift code in Xcode, with NSURLSession, request, data etc.
I had a php web page set to var_dump($_POST); so that I could check that the data was sent in correctly (my data was a hard-coded string in Xcode for testing purposes).
I couldn't for the life of me figure out why I kept getting empty POST variables, until I decided to add a test query statement to my web page binding the POST variable. Lo and behold, the query ran successfully and my table updated.
I now realise that the reason I thought the POST variable was empty was because I was refreshing the web page in order to see the results of my var_dump. I now also know that this was deleting the POST data, because when I repeated this action with the query statement, my table was getting NULL rows.
My question is how do I view the contents of the POST variables directly in the browser window, without refreshing? I know this must be a real noob goose chase I've led myself on... but I am a noob.
Thank you
You would need to modify the service itself to output those values in some way. If this is strictly for debugging, you are better off having the service write out to a log file instead. If this is part of the requesting applications call and the data needs to be displayed to the user, the service should probably return either an XML or JSON string response that your application can parse. Otherwise, you can use Fiddler to monitor your web traffic.
Of course overtime you refresh the page you just get an empty variable.
This is what I used to test if my code was working:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
testPost() // this function will test that the code is sending the variable to your server
return true
}
func testPost() {
let variableToPost = "someVariable"
let myUrl = NSURL(string: "http://www.yourserver.com/api/v1.0/post.php")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let postString = "variable=\(variableToPost)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
{ data, response, error in
if error != nil {
print(error)
return
}
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = json{
let result = parseJSON["status"] as? String
let message = parseJSON["message"] as? String
if result == "Success"{
//this should return your variable
print(message)
}else{
// print the message if it failed ie. Missing required field
print(message)
}
}//if parse
} catch let error as NSError {
print("error in registering: \(error)")
} //catch
}
task.resume()
}
then your php file will only check if there is no empty post and return the variable as JSON:
post.php
<?php
$postValue = htmlentities($_POST["variable"]);
if(empty($postValue))
{
$returnValue["status"] = "error";
$returnValue["message"] = "Missing required field";
echo json_encode($returnValue);
return;
} else {
$returnValue["status"] = "success";
$returnValue["message"] = "your post value is ".$postValue."";
echo json_encode($returnValue);
}