2017-02-09 4 views
0

Я работаю над приложением iOS, которому необходимо получить данные с удаленного сервера.Получение JSON из PHP-скрипта

Это Swift код, который получает массив JSON из PHP сценария:

func doSearch(_ searchWord: String) 
    { 
     // Dismiss the keyboard 


     // Create URL 
     let myUrl = URL(string: "...getAsesores.php") 

     // Create HTTP Request 
     let request = NSMutableURLRequest(url:myUrl!); 
     request.httpMethod = "POST"; 

     if let x = UserDefaults.standard.object(forKey:"miCodigoAgencia") as? String 
     { 
      print (x) 
     } 


     let postString = "searchWord=\(UserDefaults.standard.object(forKey:"miCodigoAgencia"))"; 
     print (postString) 
     request.httpBody = postString.data(using: String.Encoding.utf8); 

     // Execute HTTP Request 
     URLSession.shared.dataTask(with: request as URLRequest, 
            completionHandler: { (data, response,error) -> Void in 

      // Run new async task to be able to interact with UI 
      DispatchQueue.main.async { 

       // Check if error took place 
       if error != nil 
       { 
        // display an alert message 
        self.displayAlertMessage(error!.localizedDescription) 
        return 
       } 


       do { 

        // Convert data returned from server to NSDictionary 
        let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary 



        // Cleare old search data and reload table 
        self.searchResults.removeAll(keepingCapacity: false) 


        // If friends array is not empty, populate searchResults array 
        if let parseJSON = json { 

         if let friends = parseJSON["friends"] as? [AnyObject] 
         { 
          let primerName = ["Nombre": "Selecciona un asesor" ,"Apellidos": " ", "Id": " ", "Tel": " ", "Email": " " ] 
          self.searchResults.append(primerName) 

          for friendObj in friends 
          { 
           let fullName = ["Nombre": friendObj["nombre"] as! String, "Apellidos": friendObj["apellidos"] as! String, "Id": friendObj["id"] as! String, "Tel": friendObj["tel"] as! String, "Email": friendObj["email"] as! String] 

           self.searchResults.append(fullName) 

          } 


          self.pickerAsesores.reloadAllComponents() 

         } else if(parseJSON["message"] != nil) 
         { 
          // if no friends returned, display message returned from server side 
          let errorMessage = parseJSON["message"] as? String 

          if(errorMessage != nil) 
          { 
           // display an alert message 
           self.displayAlertMessage(errorMessage!) 
          } 
         } 
        } 

       } catch { 
        print(error); 
       } 

      } // End of dispatch_async 


     }) // End of data task 


     .resume() 

    } // end of doSearch() function 

Тогда есть PHP часть на два файла:

FILE 1 getAsesores.php:

<?php 
require("../db/MySQLDAO.php"); 


$config = parse_ini_file('../../../SwiftPhp.ini'); 
$dbhost = trim($config["dbhost"]); 
$dbuser = trim($config["dbuser"]); 
$dbpassword = trim($config["dbpassword"]); 
$dbname = trim($config["dbname"]); 


$dao = new MySQLDAO($dbhost, $dbuser, $dbpassword, $dbname); 
$dao->openConnection(); 

$searchWord = null; 

if(!empty($_REQUEST["searchWord"])) 
{ 
    $searchWord = htmlentities($_REQUEST["searchWord"]); 
} 

$friends = $dao->buscarAsesores($searchWord); 


if(!empty($friends)) 
{ 
    $returnValue["friends"] = $friends; 
} else { 
    $returnValue["message"] = "Could not find records"; 
} 

$dao->closeConnection(); 

echo json_encode($returnValue); 

?> 

И файл 2: MySQLDAO.php:

public function buscarAsesores($searchWord) 
{ 
    $returnValue = array(); 

    $sql = "select * from members LEFT JOIN tb_agencias ON members.agencia_usuario = tb_agencias.id_agencia where 1"; 

    if(!empty($searchWord)) 
    { 
     $sql .= " and (codigo_agencia like ? )"; 
      $sql .= " ORDER BY nombre"; 

    } 

    $statement = $this->conn->prepare($sql); 

    if (!$statement) 
     throw new Exception($statement->error); 

    if(!empty($searchWord)) 
    { 
     $searchWord = '%' ; 
     $statement->bind_param("s", $searchWord); 
    } 

    $statement->execute(); 

    $result = $statement->get_result(); 

    while ($myrow = $result->fetch_assoc()) 
    { 
     $returnValue[] = $myrow; 
    } 

    return $returnValue; 
} 

Если я вызываю PHP непосредственно из браузера, результат неверен, запрос не фильтрует записи, как я хочу, и приложение iOS показывает все записи.

Если удалить строку:

$searchWord = '%' ; 

, как комментировали в мой предыдущий вопрос здесь SO Weird filter result in PHP function

в MySQLDAO.php, то запрос фильтрует записи, как я хочу, но приложение показывает сообщение: Could not find records

Любая помощь приветствуется.

EDITED КОД ОБНОВЛЕНО Свифта 3 ОТ ПРАВИЛЬНОГО ОТВЕТА НА @ Крис:

if let x = UserDefaults.standard.object(forKey:"miCodigoAgencia") as? String { 
      print (x) 
      var postString = "searchWord=\(x)".addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed); 
      print (postString) 
      request.httpBody = postString?.data(using: String.Encoding.utf8) 
      request.setValue("\(request.httpBody?.count)", forHTTPHeaderField:"Content-Length") 
     } 

ответ

1

Я вижу несколько вещей.

  1. Вы переписываете значение $searchWord всегда на «%».
  2. В вашем приложении iOS вам может понадобиться set the Content-Type header до Form-savvy value в вашем запросе. Вам также может потребоваться установить Content-Length. EDIT: По умолчанию значение application/x-www-form-urlencoded, вам нужно на самом деле URL-кодировать значение ;-)
  3. Вы, вероятно, хотите, чтобы окружать условия поиска с% 's в вашем SQL

Для номер 1, это код:

if(!empty($searchWord)) 
    { 
     $searchWord = '%' ; 
     $statement->bind_param("s", $searchWord); 
    } 

Должно быть, как это

if(!empty($searchWord)) { 
    $statement->bind_param("s", $searchWord); 
} 

за номером 2 в приложении IOS, добавить код как это (обратите внимание, что я удалил избыточный вызов UserDefaults):

let request = NSMutableURLRequest(url:myUrl!); 
request.httpMethod = "POST"; 

if let x = UserDefaults.standard.object(forKey:"miCodigoAgencia") as? String { 
    print (x) 
    var postString = "searchWord=\(x))".addingPercentEncoding(withAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet()); 
    print (postString) 
    request.httpBody = postString.data(using: String.Encoding.utf8) 
    request.setValue("\(request.httpBody.length)", forHTTPHeaderField:"Content-Length") 
} 

Для номера 3, изменить " and (codigo_agencia like ? )" к " and (codigo_agencia like %?%)" (или использовать только последний один, чтобы сделать ваш поиск требует согласование начала данных).

+0

Спасибо @ Крис, как указано в моем вопросе, точка № 1 решает проблему фильтрации. Но мне нужна ваша помощь в решении пункта 2 – mvasco

+0

@mvasco обновлен с примером и обновлен до # 2, я думаю, вам нужно было на самом деле URL-кодировать тело. –

+0

Спасибо, @Chris, я получаю сообщение об ошибке: var postString = "searchWord = \ (x))". StringByAddingPercentEncodingWithAllowedCharacters (NSCharacterSet.URLQueryAllowedCharacterSet()); Статический член init (сегмент интерполяции строк не может использоваться на экземпляре типа String – mvasco

Смежные вопросы