2015-12-13 27 views
0

我嘗試將JSON發佈到我的Web服務器,但它根本不起作用。它適用於「DELETE」和「GET」,但對於「POST」它根本不起作用並獲取錯誤。如何將數據序列化爲JSON對象

這是我的代碼:

let postsEndpoint:String = "http://ideabase.herokuapp.com/categories" 
    guard let postsURL = NSURL(string: postsEndpoint) else { 
     print("Error: cannot create URL") 
     return 
    } 
    let postsUrlRequest = NSMutableURLRequest(URL: postsURL) 
    postsUrlRequest.HTTPMethod = "POST" 

    let newPost: NSDictionary = ["id":7, "title": "Purple","created_at": "2015-12-08 08:06:55","updated_at":"2015-12-08 08:06:55"] 
    do { 
     let jsonPost = try NSJSONSerialization.dataWithJSONObject(newPost, options: []) 
     postsUrlRequest.HTTPBody = jsonPost 

     let config = NSURLSessionConfiguration.defaultSessionConfiguration() 
     let session = NSURLSession(configuration: config) 

     let createTask = session.dataTaskWithRequest(postsUrlRequest, completionHandler: { 
      (data, response, error) in 
      guard let responseData = data else { 
       print("Error: did not receive data") 
       return 
      } 
      guard error == nil else { 
       print("error calling GET on /categories/1") 
       print(error) 
       return 
      } 
      // parse the result as JSON, since that's what the API provides 
      let post: NSDictionary 
      do { 
       post = try NSJSONSerialization.JSONObjectWithData(responseData, 
        options: []) as! NSDictionary 
      } catch { 
       print("error parsing response from POST on /categories") 
       return 
      } 
      // now we have the post, let's just print it to prove we can access it 
      print("The post is: " + post.description) 

      // the post object is a dictionary 
      // so we just access the title using the "title" key 
      // so check for a title and print it if we have one 
      if let postID = post["id"] as? Int 
      { 
       print("The ID is: \(postID)") 
      } 
     }) 
     createTask.resume() 

我得到的錯誤 「解析響應從POST上/類別」

你能幫幫我嗎?

+0

嘗試使用查爾斯或其他代理,可以讓你看到所有的HTTP流量將在/你的系統。然後,您可以確保該信息是您所期望的,並查看有關回復的詳細信息。 – farhadf

+0

@Gharay,我已經添加了一個工作POST請求的示例 –

回答

2

你說:

我嘗試發佈一個JSON到我的Web服務器,但它並沒有在所有

工作有我們知道肯定看時兩件事情你碼。

  1. 你有數據或你的警衛已經返回。
  2. 您沒有錯誤或您的第二名後衛已經返回。

你把它歸結到你的NSJSONSerialization,所以你很好,直到那一點。現在你只需要調整你的序列化類型,你應該(也許)很好。

您需要將您的post類型更改爲[[String:AnyObject]],因爲我們將在您的嘗試抓取中扮演您的角色。

let post: [[String:AnyObject]] 
do { 
    post = try NSJSONSerialization.JSONObjectWithData(responseData, 
        options: .MutableLeaves) as! [[String:AnyObject]] 
} catch { 
    print("error parsing response from POST on /categories") 
    return 
} 

當你做這種方式很容易通過傳遞您的文章爲這樣的函數,讓您的返回值:

func valuesFromData(jsonDict: [[String:AnyObject]]) { 
    let myValue = jsonDict["key"] as? String 
    let another = jsonDict["SomeOtherKey"] as? Int 
} 

如果你仍然有問題,你只需要打印瞭解我們的狀態代碼以瞭解您的POST不起作用的原因。裏面你完成處理器(關閉)的添加以下內容:

guard let status = response.statusCode as? NSHTTPURLResponse else { 
    return 
} 
print("status code: \(status)") 

這裏是一個完美的工作的NSURLRequest

func postNewMessage(messageType: String, messageBody: String) { 

     guard let token = AppDelegate.userDefaults.valueForKey("token") else { 
      return 
     } 

     let params = [ 
      "messageType": messageType, 
      "messageBody": messageBody 
     ] 

     var jsonData: NSData? 
     var jsonString: NSString? 
     var tokenResponse: String? 

     do { 
      jsonData = try NSJSONSerialization.dataWithJSONObject(params, options: []) 
     } catch { 
      print(error) 
      return 
     } 

     let request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8080/messages")!) 
     let session = NSURLSession.sharedSession() 

     request.HTTPMethod = "POST" 
     request.addValue(token as! String, forHTTPHeaderField: "user-auth-token") 
     request.HTTPBody = jsonData! 
     request.addValue("application/json", forHTTPHeaderField: "Content-Type") 
     request.addValue("application/json", forHTTPHeaderField: "Accept") 

     let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in 

      guard let testResponse = response as? NSHTTPURLResponse else { 
       print("failed \(response)") 
       return 
      } 

      guard let status = HTTPStatusCodes(rawValue: testResponse.statusCode) else { 
       print("failed again") 
       return 
      } 

      switch status { 
      case .Created: 
       let headerFields = testResponse.allHeaderFields 
       tokenResponse = headerFields["user-auth-token"] as? String 
       guard let returnedData = data else { 
        print("no data was returned") 
        break 
       } 
       // convert data to string 
       jsonString = NSString(data: returnedData, encoding: NSUTF8StringEncoding) ?? "Invalid JSON" 
       print("\(tokenResponse)\n\n\(jsonString!)") 

       // update user interface 
       dispatch_sync(dispatch_get_main_queue()) { 
        print("derp") 
       } 

      default: 
       print("asdf") 
      } 
     } 
     task.resume() 
    } 

你想也需要有這樣枚舉使它工作的例子。

enum HTTPStatusCodes : Int { 
    case Ok = 200 
    case Created = 201 
    case BadRequest = 404 
} 

(簡體)

+0

我已經嘗試過,但它仍然沒有開火,並且響應也沒有statusCode成員!它給我一個錯誤 – Gharary

+0

@Gharary我已經添加了一個完全可操作的NSURLSession爲你比較你的代碼 –