2015-11-03 1 views
1

У меня есть страница регистрации в приложении iOS, которое я пытаюсь написать в Swift. Первое, что я тестируя посылает POST с адресом электронной почты, это путь, я делаю так:Отправка простого POST в Swift, получение ответа «Пустое сообщение»

var bodyData = ("userEmail=%@\" \" &userPassword=%@\" \"&userDevice=%@\" \"", emailAddress.text, password.text, deviceModel) 

    let dataToSend = (bodyData as NSString).dataUsingEncoding(NSUTF8StringEncoding) 

      request.HTTPMethod = "POST" 
      request.HTTPBody = dataToSend 
      let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { 
       data, response, error in 

       if error != nil { 
        print("error=\(error)") 
        return 
       } 
       // print("response = \(response)") 

       let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) 
       print("responseString = \(responseString)") 
      } 
      task.resume() 

Однако я получаю сообщение об ошибке назад о том, что это был пустой пост , Это точный ответ на результат выше: responseString = Optional({"complete":"false","message":"Empty Post"}) Я исследовал различные способы отправки простой POST в Swift, и это кажется правильным. Я не вижу в этом ничего плохого или почему он выводит сообщение о том, что сообщение было пустым ... За исключением, может быть, формата строки?

База данных ожидает несколько вещей для службы «новый пользователь», и я отправляю только одну часть из-за того, что она является тестом. Может ли это быть проблемой? Ожидается следующее:

Service URL : https://test.com/services/new-user/ 
Required Post Fields: 
For New User: 
'userEmail' 
'userPassword' 
'userDevice' 

(Из документации).

Я не работал с веб-сервисами. После мозгового штурма я думаю, что это могут быть преступники: я могу получить ответ, потому что я не отправляю сразу все данные. Я также могу отправить его неправильно. Могу ли я отправить его в виде текста или мне нужно отправить его как JSON?

+0

Было бы полезно знать, что сервис нового пользователя ожидает на другом конце, так как он посылает JSON обратно – spirographer

+1

@spirographer Спасибо вам, что это правда, я буду обновлять свои ОП в настоящее время. – John

+0

попробуйте проверить что-то вроде этого: var bodyData = userEmail = \ "\" & userPassword = \ "\" & userDevice = \ "\" "', чтобы увидеть, могут ли они использовать параметры в этом формате. Другим распространенным форматом является JSON, и вы можете легко изменить код, чтобы поддерживать это тоже – spirographer

ответ

4

Пару вопросов:

  1. У вас есть линия, которая говорит:

    var bodyData = ("userEmail=%@\" \" &userPassword=%@\" \"&userDevice=%@\" \"", emailAddress.text, password.text, deviceModel) 
    

    Это не делать то, что вы хотели. Он создает кортеж с четырьмя элементами, который состоит из строки формата и трех значений, а не одной форматированной строки. Распечатайте bodyData, и вы поймете, что я имею в виду.

    Вы либо хотите использовать String(format: ...), либо даже проще использовать интерполяцию строк. (См фрагмент кода ниже).

  2. Предполагая, что emailAddress и password являются UITextField объекты, обратите внимание, что text свойство является необязательным, так что вы должны разворачивать эти УСТРОЙСТВА, прежде чем использовать их. Посмотрите на строку bodyData, и вы поймете, что я имею в виду.

    Я не знаю, был ли deviceModel был факультативным, но если да, разверните это, тоже.

  3. У вас есть пробел перед параметром userPassword запроса. Это сделает его недостаточно сформированным. Удалите это пространство. Вы, вероятно, можете упростить эту строку формата, избавившись от кучи этих \" ссылок.

  4. Возможно, вам необходимо указать Content-Type с запросом. Это часто не обязательно, но это хорошая практика.

  5. Вы явно получаете ответ JSON, поэтому вы можете его разобрать.

Таким образом, вы могли бы сделать что-то вроде:

guard emailAddress.text != nil && password.text != nil else { 
    print("please fill in both email address and password") 
    return 
} 

// use 
// 
// let bodyString = String(format: "userEmail=%@&userPassword=%@&userDevice=%@", emailAddress.text!, password.text!, deviceModel) 
// 
// or use string interpolation, like below: 

let bodyString = "userEmail=\(emailAddress.text!)&userPassword=\(password.text!)&userDevice=\(deviceModel)" 

let bodyData = bodyString.dataUsingEncoding(NSUTF8StringEncoding) 

request.HTTPMethod = "POST" 
request.HTTPBody = bodyData 
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") 

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in 
    guard error == nil && data != nil else { 
     print("error=\(error)") 
     return 
    } 

    do { 
     let responseObject = try NSJSONSerialization.JSONObjectWithData(data!, options: []) 

     print(responseObject) 
    } catch let parseError as NSError { 
     print(parseError) 
    } 
} 
task.resume() 

Примечание, вы действительно должны быть процентов, спасаясь значения, добавляемые к телу, тоже (в частности, если значения могут иметь пробелы , +, & или другие зарезервированные символы в них). См. https://stackoverflow.com/a/28027627/1271826.

Если вы не хотите попасть в сорняки такого рода вещей, подумайте об использовании фрейма, такого как Alamofire, который позаботится об этом для вас. Например:

guard emailAddress.text != nil && password.text != nil else { 
    print("please fill in both email address and password") 
    return 
} 

let parameters = [ 
    "userEmail" : emailAddress.text!, 
    "userPassword" : password.text!, 
    "userDevice" : deviceModel 
] 

Alamofire.request(.POST, urlString, parameters: parameters) 
    .responseJSON { response in 
     switch response.result { 
     case .Failure(let error): 
      print(error) 
     case .Success(let value): 
      print(value) 
     } 
} 
+0

Большое вам спасибо @Rob! Я очень признателен, что вы нашли время, чтобы объяснить это подробно. – John

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