2015-06-26 3 views
1

Я приспособил это от IOS Apprentice учебника части Ray Wenderlich в 4.Как выполнить запросы GET и POST в Swift?

Этот код работает как запрос GET отправляется на мой Strongloop API с помощью простой модели базы данных, однако:

  1. Это работает, но я не знаю, почему он работает, поскольку он не вызывает никакого метода, который я могу увидеть, чтобы отправить запрос.

  2. Я не вижу средств для того, чтобы сделать запрос POST.

Мой вопрос: Как я могу выполнить POST-запрос? Это делается совершенно по-другому?

Дайте мне знать, если вам нужна дополнительная информация.

class ViewController: UIViewController { 


    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    @IBAction func getFromDB() { 
     let url = urlWithSearchText("") 
     println("URL: '\(url)'") 
     if let jsonString = performGetRequestWithURL(url) { 
      println("Received JSON string '\(jsonString)'") 
     } 
    } 


    func urlWithSearchText(searchText: String) -> NSURL { 
     let escapedSearchText = searchText.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)! 
     let urlString = String(format: "http://localhost:3000/api/Tests", escapedSearchText) 
     let url = NSURL(string: urlString) 
     return url! 
    }  

    func performGetRequestWithURL(url: NSURL) -> String? { 
     var error: NSError? 
     if let resultString = String(contentsOfURL: url, encoding: NSUTF8StringEncoding, error: &error) { 
      return resultString 
     } else if let error = error { 
      println("Download Error: \(error)") 
     } else { 
      println("Unknown Download Error") 
     } 
     return nil 
    } 

Вот фотография этой работы:

https://dl.dropboxusercontent.com/u/14464971/Images/Messages%20Image%281477993527%29.png

ответ

3

Ниже приведены два метода POST. В зависимости от того, хотите ли вы синхронно (все остальное ждет, пока метод post не будет завершен) или асинхронный (метод POST работает в фоновом режиме, другие методы запускаются параллельно).

Методы

// POST data to url 
func postDataAsynchronous(url: String, bodyData: String, completionHandler: (responseString: String!, error: NSError!) ->()) { 
    var URL: NSURL = NSURL(string: url)! 
    var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL) 
    request.HTTPMethod = "POST"; 
    request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding); 

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()){ 

     response, data, error in 

     var output: String! 

     if data != nil { 
      output = NSString(data: data, encoding: NSUTF8StringEncoding) as! String 
     } 

     completionHandler(responseString: output, error: error) 
    } 
} 

// Obtain the data 
func postDataSynchronous(url: String, bodyData: String, completionHandler: (responseString: String!, error: NSError!) ->()) 
{ 
    let URL: NSURL = NSURL(string: url)! 
    var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL) 
    request.HTTPMethod = "POST" 
    request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding); 
    request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") 

    var response: NSURLResponse? 
    var error: NSError? 

    // Send data 
    let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error) 

    var output: String! // Default to nil 

    if data != nil{ 
     output = NSString(data: data!, encoding: NSUTF8StringEncoding) as! String 
    } 

    completionHandler(responseString: output, error: error) 

} 

Используя их

Затем можно вызвать (использование) их следующим образом:

postDataSynchronous(url, bodyData: bodyData) { 
    responseString, error in 

     if error != nil { 
      println("Error during post: \(error)") 
      return 
     } 
     else{ 
      //Success 
      println(responseString) 
      userType = responseString // Set usertype based on server response 
     }   
    } 

СВИФТ 2,0

func postData(url: String, params: Dictionary<String, String>, completionHandler: (data: NSData?, response: NSURLResponse?, error: NSError?) ->()) { 

    // Indicate download 
    UIApplication.sharedApplication().networkActivityIndicatorVisible = true 

    let url = NSURL(string: url)! 
    //  print("URL: \(url)") 
    let request = NSMutableURLRequest(URL: url) 
    let session = NSURLSession.sharedSession() 
    request.HTTPMethod = "POST" 
    request.addValue("application/json", forHTTPHeaderField: "Content-Type") 
    request.addValue("application/json", forHTTPHeaderField: "Accept") 

    // Verify downloading data is allowed 
    do { 
     request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: []) 
    } catch let error as NSError { 
     print("Error in request post: \(error)") 
     request.HTTPBody = nil 
    } catch { 
     print("Catch all error: \(error)") 
    } 

    // Post the data 
    let task = session.dataTaskWithRequest(request) { data, response, error in 
     completionHandler(data: data, response: response, error: error) 

     // Stop download indication 
     UIApplication.sharedApplication().networkActivityIndicatorVisible = false // Stop download indication 

    } 

    task.resume() 

} 
+0

Это очень полезно, но скажем, что bodyData является {"name": "Professor Dumbledore", " type ":" Wizard "} Как я могу превратить это в строку? В нем много кавычек, но я не уверен, как отформатировать его как строку. –

+0

Поцарапайте этот последний комментарий, я просто понял: «name = Professor Dumbledore & Type = Wizard» –

+0

Рад видеть, что вы поняли это - счастливое кодирование и хороший уикенд для вас! –

0

Этот метод вызывает запрос HTTP.

String(contentsOfURL: url, encoding: NSUTF8StringEncoding, error: &error) 

Поскольку Swift String не имеет такой подписи, как это.

Этот метод должен быть написан где-то в проекте, так как extension из String

Было бы что-то вроде этого

extension String{ 
    init(contentsOfURL: NSURL, encoding: NSUTF8StringEncoding, inout error: NSError){ 
     // load data from url 
     self = //parse data to string 
    } 
} 
+0

Я не имеют расширения, написанные для строки, хотя. Это встроено в SDK? –

+0

Да, это может быть – nRewik

+0

Любая идея, как сделать запрос POST с этим? –

0

Инициализатор String (contentsOfUrl: encoding: error) делает запрос GET под капотом и возвращает содержимое в виде строки с указанной кодировкой.

Одним из способов сделать запрос было бы создание NSURLConnection и использование NSMutablrURLRequest установить метод HTTP post. С помощью NSMutableURLRequest вы можете создать NSURLConnection и сразу же запустить его с помощью делегата, или вы можете вызвать NSURLConnection.sendSynchronousRequest или NSURLConnection.sendAsynchronousRequest для отправки запроса.

1

Swift 3

GET

private func httpRequest() { 

    //create the url with NSURL 
    let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")! //change the url 

    //create the session object 
    let session = URLSession.shared 

    //now create the URLRequest object using the url object 
    let request = URLRequest(url: url) 

    //create dataTask using the session object to send data to the server 
    let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in 

     guard error == nil else { 
      return 
     } 

     guard let data = data else { 
      return 
     } 

     do { 
      //create json object from data 
      if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] { 
       print(json) 
      } 
     } catch let error { 
      print(error.localizedDescription) 
     } 
    }) 
    task.resume() 
} 

POST

@IBAction func submitAction(sender: AnyObject) { 

    //declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid 

    let parameters = ["name": nametextField.text, "password": passwordTextField.text] as Dictionary<String, String> 

    //create the url with URL 
    let url = URL(string: "http://myServerName.com/api")! //change the url 

    //create the session object 
    let session = URLSession.shared 

    //now create the URLRequest object using the url object 
    var request = URLRequest(url: url) 
    request.httpMethod = "POST" //set http method as POST 

    do { 
     request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass dictionary to nsdata object and set it as request body 

    } catch let error { 
     print(error.localizedDescription) 
    } 

    request.addValue("application/json", forHTTPHeaderField: "Content-Type") 
    request.addValue("application/json", forHTTPHeaderField: "Accept") 

    //create dataTask using the session object to send data to the server 
    let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in 

     guard error == nil else { 
      return 
     } 

     guard let data = data else { 
      return 
     } 

     do { 
      //create json object from data 
      if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] { 
       print(json) 
       // handle json... 
      } 

     } catch let error { 
      print(error.localizedDescription) 
     } 
    }) 
    task.resume() 
} 
+0

Спасибо за обмен Suhit! Я настоятельно рекомендую установить это как общую функцию с URL-адресом и параметрами, передаваемыми ему. Может ли иметь обработчик, чтобы разработчик мог обрабатывать исключения/данные при вызове функции. Будет ли обновлять мой ответ, чтобы он содержал то же самое. –

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