Return Json from Php to Swift Alamofire - php

Hi guys i am using alamofire on a swift 3 iphone program, my problem is that i need to return a value from the php page my problem is that the value that comes back to me is this. How do I make sure that the value I return is: no prova#email.it
I hope I have explained
RETURN VALUE(NOT CORRECT):
SUCCESS: {
message = "no Optional(\"prova#email.it\")";
}
no Optional("prova#email.it")
SWIFT CODE:
import Foundation
import Alamofire
class User{
//URL to our web service
var email=""
var password=""
func PrintValue(){
// print(username);
//print(password);
}
func Login() -> String{
//var ris="";
var readvalue=""
let URLString = "http://localhost/test/login_mobile.php"
let parameters_value: Parameters = [
"email": email,
"password": password
]
//Sending http post request
Alamofire.request(URLString, method: .post, parameters: parameters_value).responseJSON
{
response in
//printing response
print(response)
//getting the json value from the server
if let result = response.result.value {
//converting it as NSDictionary
let jsonData = result as! NSDictionary
//displaying the message in label
readvalue = (jsonData.value(forKey: "message") as! String?)!
print(readvalue)
}
}
return readvalue
}
}
PHP CODE:
<?php
include 'user.php';
header('Content-Type: application/json');
$email= $_POST['email'];
$password = $_POST['password'];
$ris['message']="";
$user = new User();
//procedo con il login
if($user->login($email,$password,"MOBILE")==true){
$ris['message']="yes";
}
else{
$ris['message']="no $email";
}
echo json_encode($ris);
?>

I think it can be done something like:
if let readvalue = jsonData.value(forKey: "message") as? String {
print(readvalue)
}
must print wihtout Optional

Just did this in a playground and it works as expected..
import UIKit
let response: [AnyHashable: Any] = [
"message": "hello world"
]
class MyCoolClass {
func login() {
var readvalue = ""
let jsonData = response as NSDictionary
readvalue = jsonData.value(forKey: "message") as! String
debugPrint("the readvalue is: \(readvalue)")
}
}
let instance = MyCoolClass()
instance.login()
This will print: "the readvalue is: hello world"
The code is not very failsafe...

You need to use nil coalescing to make your value non-optional. e.g. print(readvalue ?? "nil"). Something better would be reengineer your response handling to properly return a typed value or a specific error.

Related

I get error while I send three array post with Alamofire in database?

This is my php code. I need to send here 3 parameters like cammand , mobile and token. include "../db.php";
//$_POST['command'] ;//
$command = $_POST['command'];
if ($command == "register_user") {//register user
$mobile = $_POST['mobile'];
$token = $_POST['token'];
$sql = "SELECT * FROM tbl_user where mobile ={$mobile}";
$result = mysqli_query($connection, $sql);
$num = mysqli_num_rows($result);
This my swift code.
import Foundation
import UIKit
import Alamofire
class LoginViewController: UIViewController {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
#IBOutlet weak var inputTelephoneNumber: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func loginBtn(_ sender: Any) {
let Parametrs : Parameters = [
"command": "register_user",
"mobile": inputTelephoneNumber.text!,
"token": appDelegate.myToken!
]
AF.request("http://192.xxxxxxxxx/xxxxxxxx/api/sms_verify.php", method: .post, parameters: Parametrs, encoding: JSONEncoding.default)
.responseJSON { response in
print(response)
}
let tokenURL = "http://192xxxxxx/xxxxxxxxx/api/sms_verify.php"
if let url = URL(string: tokenURL) {
let task = URLSession.shared.dataTask(with: url) {
data, response, error in
if error != nil {
print(error!)
} else {
if let responseString = String(data: data!, encoding: .utf8) {
print(responseString)
}
}
}
task.resume()
}
}
}
I get this error from xcode.
<br />
<b>Notice</b>: Undefined index: command in <b>/opt/lampp/htdocs/foroshgah1/api/sms_verify.php</b> on line <b>5</b><br />
failure(Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(error: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))
I try to send three parameters like cammand = register_user , mobile and token.
I try to send them like json encode but I did not know I correct form or no?
To pass URL encoded parameters in a post request, you need to call the request function of Alamofire passing an instance of URLEncoding as encoding parameter:
AF.request(
"http://192.xxxxxxxxx/xxxxxxxx/api/sms_verify.php",
method: .post,
parameters: Parametrs,
encoding: URLEncoding.default
).responseJSON { response in
print(response)
}

I have this issue when trying to read my data which is json encoded from the php page to the swift page

I have this issue when trying to read my data which is json encoded from the php page to the swift page.
this is the code I am using
import Foundation
protocol HomeModelProtocol: class {
func itemsDownloaded(items: NSArray)
}
class HomeModel: NSObject, URLSessionDataDelegate {
//properties
weak var delegate: HomeModelProtocol!
var data = Data()
let urlPath: String = "http://localhost/service.php" //this will be changed to the path where service.php lives
func downloadItems() {
let url: URL = URL(string: urlPath)!
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
let task = defaultSession.dataTask(with: url) { (data, response, error) in
if error != nil {
print("Failed to download data")
}else {
print("Data downloaded") // this work fine
self.parseJSON(data!)
}
}
task.resume()
}
func parseJSON(_ data:Data) {
var jsonResult = NSArray()
print(jsonResult) // this print empty parentheses
print(String(data: data, encoding: .utf8)) // this prints out the array
//the code below throughs an arror
do{
jsonResult = try JSONSerialization.jsonObject(with:data, options:JSONSerialization.ReadingOptions.allowFragments) as! [NSArray] as NSArray
print(jsonResult)
} catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let locations = NSMutableArray()
for i in 0 ..< jsonResult.count
{
jsonElement = jsonResult[i] as! NSDictionary
let location = LocationModel()
//the following insures none of the JsonElement values are nil through optional binding
if let name = jsonElement["Name"] as? String,
let address = jsonElement["Address"] as? String,
let latitude = jsonElement["Latitude"] as? String,
let longitude = jsonElement["Longitude"] as? String
{
location.name = name
location.address = address
location.latitude = latitude
location.longitude = longitude
}
locations.add(location)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.itemsDownloaded(items: locations)
})
}
}
this is the output which I am receiving:
Data downloaded
(
)
Optional(" \nconnectedinside[{\"name\":\"One\",\"add\":\"One\",\"lat\":\"1\",\"long\":\"1\"},{\"name\":\"Two\",\"add\":\"Two\",\"lat\":\"2\",\"long\":\"2\"},{\"name\":\"One\",\"add\":\"One\",\"lat\":\"1\",\"long\":\"1\"},{\"name\":\"Two\",\"add\":\"Two\",\"lat\":\"2\",\"long\":\"2\"}]")
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around
character 2." UserInfo={NSDebugDescription=Invalid value around
character 2.}
You get this error, because the json response you receive is not an array but a dictionary.
EDIT: as pointed out in a comment, you first need to fix your json response in your php code. There is ":" missing after "connectedinside".
It should look like this:
{\"connectedinside\":[{\"name\":\"One\",\"add\":"One",...},...]}
My suggestion to fix this:
You should have two models:
struct HomeModelResponse: Codable {
let connectedinside: [LocationModel]
}
// your LocationModel should look like this:
struct LocationModel: Codable {
let name: String
let add: String
let lat: String
let long: String
}
And change your JSONDecoding code to:
do {
jsonResult = try? JSONDecoder().decode(HomeModelResponse.self, from: data)
print()
} catch let exception {
print("received exception while decoding: \(exception)"
}
Then you can access your LocationModels by jsonResult.connectedinside
The problem was on my php side and I fixed it.it is working now.

Swift send parameters in Alamofire

I want to send two values in the request:
1) operation string
2) user object
I am getting message Operation is not set even though I included in parameters "operation": "register"
I am new to Alamofire. Can anyone explain to me:
1) how to send values in the request?
2) how to send the user object?
3) how to deal with both results .Success and .Failure
Swift Code:
let urlString = URLFactory()
let url = URL(string: urlString.getAppURL())!
print("Log url: \(url)")
let user = User()
user.setEmail(email: email)
let parameters: Parameters = ["operation": "register", "user": user]
Alamofire.request(url, method: .post, parameters: parameters).responseJSON { response in
print("Log \(response)")
print("Log response.request: \(response.request)")
print("Log response.error: \(response.error)")
print("Log response.data: \(response.data)")
print("Log response.result: \(response.result)")
}
Swift Output:
Log url: http://192.168.0.101/GeolocationNews/NewsDataCrawler/app.php
Log SUCCESS: {
message = "Invalid Parameters";
result = failure;
}
Log response.request: Optional(http://192.168.0.101/GeolocationNews/NewsDataCrawler/app.php)
Log response.error: nil
Log response.data: Optional(51 bytes)
Log response.result: SUCCESS
PHP Code:
$login = new Login();
$fun = new FunctionsValidation();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$data = json_decode(file_get_contents("php://input"));
if(isset($data->operation)) {
$operation = $data->operation;
if(!empty($operation)) {
if($operation == 'register') {
echo $login->register($data);
}
} else { // if operation is empty
$response["result"] = "failure";
$response["message"] = "Operation is empty";
echo json_encode($response);
}
} else { // if operation is not set
$response["result"] = "failure";
$response["message"] = "Operation is not set";
echo json_encode($response);
}
}
UPDATE
I have tested the API by Postman sending:
{
"operation": "register",
"user":
{
"email": "email value"
}
}
It gives me: {"result":"failure","message":"Invalid Email"} so the API is working good!
I have tried sending Alamofire request with just operation in the parameters and it works. So it seems like the problem is in converting the user object to dictionary. Can anyone give me an example of how to do that?
User object:
class User: NSObject {
private var name: String,
email: String,
password: String,
oldPassword: String,
newPassword: String,
code: String
private var id: Int
override init() {
self.name = ""
self.email = ""
self.password = ""
self.oldPassword = ""
self.newPassword = ""
self.code = ""
self.id = 0
}
// set and get methods ...
}
I think the problem is with encoding. As per your PHP code it accepts application/json as a content type and this should be sent through Almofire with JSON encoding.
Try this instead:
Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default)
.responseJSON { response in
print("Log \(response)")
print("Log response.request: \(response.request)")
print("Log response.error: \(response.error)")
print("Log response.data: \(response.data)")
print("Log response.result: \(response.result)")
}
Reference:
https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#parameter-encoding
The problem was with converting the user object to a dictionary. Instead of using an object, I just set the user as a dictionary.
let userDictionary: Dictionary = ["email": email, "password": password]
let parameters: Parameters = ["operation": operation, "user": userDictionary]
Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { response in
...
}

Call Php from Swift 3 iOS

Hello I have update my old swift app in the new version of swift 3, The code was connected to a php page by passing values ​​in post and then returning a json message since I updated the app to swift 3 xcode me from the following errors, How can i fix these errors?
Error:
Swift Code:
let URL_SAVE_TEAM = "http://localhost/ios-login.php"
var email:String = "";
var password:String = "";
func PrintValue(){
// print(username);
//print(password);
}
func Login() -> Bool{
//created NSURL
let requestURL = NSURL(string: URL_SAVE_TEAM)
//creating NSMutableURLRequest
let request = NSMutableURLRequest(URL: requestURL)
//setting the method to post
request.HTTPMethod = "POST"
//getting values from text fields
//creating the post parameter by concatenating the keys and values from text field
let postParameters = "email="+email+"&password="+password;
//adding the parameters to request body
request.HTTPBody = postParameters.dataUsingEncoding(NSUTF8StringEncoding)
//creating a task to send the post request
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if error != nil{
print("error is \(error)")
return;
}
//parsing the response
do {
//converting resonse to NSDictionary
let myJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
//parsing the json
if let parseJSON = myJSON {
//creating a string
var msg : String!
//getting the json response
msg = parseJSON["message"] as! String?
//printing the response
print(msg)
}
} catch {
print(error)
}
}
//executing the task
task.resume()
return false;
}
Xcode Image of Error:
PHP CODE:
<?php
header('Content-Type: application/json');
$email= $_POST['email'];
$password = $_POST['password'];
$ris='Ti rispondo dal server zio';
echo json_encode($ris);
// echo "prova";
?>
I would write this more swiftly :)
func Login() -> Bool{
//created URL
guard let requestURL = URL(string: URL_SAVE_TEAM) else { return false }
//creating URLRequest
var request = URLRequest(url: requestURL)
//setting the method to post
request.httpMethod = "POST"
//getting values from text fields
//creating the post parameter by concatenating the keys and values from text field
let postParameters = "email=\(email)&password=\(password)"
//adding the parameters to request body
request.httpBody = postParameters.data(using: .utf8)
//creating a task to send the post request
let session = URLSession.shared
let task = session.dataTask(with: request) {
data, response, error in
guard error == nil else {
print("error is \(error!.localizedDescription)")
return
}
guard let data = data else {
print("No data was returned by the request!")
return
}
//parsing the response
do {
//converting resonse to NSDictionary
let myJSON = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? Dictionary<String, String?>
//parsing the json
guard let parseJSON = myJSON, let msg = parseJSON["message"] as? String else {
print("Error parsing data")
return
}
//printing the response
print(msg)
} catch {
print(error)
}
}
//executing the task
task.resume()
return false
}
You may think to add a completion handler to your function to handle the login success!

Invalid JSON require Swift iOS

I am developing a simple iOS Swift app. I want to make a log-in screen for my app that will connect to already existing user database in Wordpress. I found some PHP scripts and Swift code.
I am trying to post username and login, check it and return the result(isUser = true/false or 1/0)
Here is a PHP script
<?php
// Read request parameters
$username= $_REQUEST["username"];
$password = $_REQUEST["password"];
// Store values in an array
$returnValue = array("username"=>$username, "password"=>$password);
// Send back request in JSON format
echo json_encode($returnValue);
?>
and a Swift function
func getPHPJson() {
let urlPath: String = "LINK_TO_PHP_FILE?username=\(user)&password=\(pass)"
let url: NSURL = NSURL(string: urlPath)!
let request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "GET"
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
do
{
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary
{
print(jsonResult)
//print(jsonResult["isUser"] as! Bool)
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("raw response: \(responseString!)")
}
} catch let error as NSError
{
print(error.localizedDescription)
print("error")
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("raw response: \(responseString)")
}
})
}
it gives me a desired result.
OUTPUT
{
password = iosappusettest1;
username = iosappusettest;
}
raw response: {"username":"iosappusettest","password":"iosappusettest1"}
But when I add function to check if user is registered - I always get an invalid JSON
here is PHP function
function authentication ($user, $pass){
global $wp, $wp_rewrite, $wp_the_query, $wp_query;
if(empty($user) || empty($pass)){
return 0;
} else {
require_once('../wp-blog-header.php');
$status = 0;
$auth = wp_authenticate($user, $pass );
if( is_wp_error($auth) ) {
$status = 0;
} else {
$status = 1;
}
return $status;
}
}
I believe the problem is require_once function. In raw response I get a lot of html tags and other data that make my JSON invalid.
Is there any way to clear the page and output in the JSON only? echo "<script> document.documentElement.innerHTML = ''; </script>"; in PHP did't help me. maybe jQuery will help?
Maybe I can check if user is registered in another way?
Maybe I can store my result in a separate place or temp file?
Maybe I should wrap my data not in JSON but something else?
So I need to pass username and password to PHP, check it with authentication function(that uses require_once) and send back the $status to iOS Swift app ass variable.
Question is answered.
The problem was in WP plugin, that redirected all unlogined users from all the links in that domain, so when i called require_once('../wp-blog-header.php'); i was always redirected to main page and that was the reason for wrong JSON file with all the HTML markup.
Keep your response in pure JSON, and leave out any html tags as they are not needed by your ios end.

Categories