2016-12-05 79 views
2

我正在Xcode 8上使用Siesta和Swift 3構建API客戶端。我希望能夠使用Siesta資源獲取實體,然後更新一些數據並執行patch API。Swift Siesta編輯獲取的實體

的問題是,有一個實體,如果我救我的實體領域的JSON數組我不能送他們回服務器,我收到以下錯誤:

▿ Siesta.RequestError 
    - userMessage: "Cannot send request" 
    - httpStatusCode: nil 
    - entity: nil 
    ▿ cause: Optional(Siesta.RequestError.Cause.InvalidJSONObject()) 
    - some: Siesta.RequestError.Cause.InvalidJSONObject 
    - timestamp: 502652734.40489101 

我的實體是:

import SwiftyJSON 
import Foundation 
struct Order { 
    let id: String? 
    let sessionId: String? 
    let userId: Int? 
    let status: String? 
    let comment: String? 
    let price: Float? 
    let products: Array<JSON>? 

    init(json: JSON) throws { 
     id   = json["id"].string 
     sessionId  = json["sessionId"].string 
     userId  = json["userId"].int 
     status  = json["status"].string 
     comment  = json["comment"].string 
     price  = json["price"].float 
     products = json["products"].arrayValue 

    } 

    /** 
    * Helper method to return data as a Dictionary to be able to modify it and do a patch 
    **/ 
    public func toDictionary() -> Dictionary<String, Any> { 
     var dictionary: [String:Any] = [ 
      "id": id ?? "", 
      "sessionId": sessionId ?? "", 
      "userId": userId ?? 0, 
      "status": status ?? "", 
      "comment": comment ?? "" 
     ] 
     dictionary["products"] = products ?? [] 

     return dictionary 
    } 
} 

我在做什麼是:

MyAPI.sessionOrders(sessionId: sessionId).request(.post, json: ["products": [["product": productId, "amount": 2]], "comment": "get Swifty"]).onSuccess() { response in 
    let createdObject : Order? = response.typedContent() 
    expect(createdObject?.sessionId).to(equal(sessionId)) 
    expect(createdObject?.comment).to(equal("get Swifty")) 
    expect(createdObject?.products).to(haveCount(1)) 
    expect(createdObject?.price).to(equal(product.price! * 2)) 

    if let createdId = createdObject?.id { 
     var data = createdObject?.toDictionary() 
     data?["comment"] = "edited Swifty" // can set paid because the user is the business owner 
     MyAPI.order(id: createdId).request(.patch, json: data!).onSuccess() { response in 
      result = true 

     }.onFailure() { response in 
       dump(response) //error is here 
     } 
    } 
} 

資源:

func sessionOrders(sessionId: String) -> Resource { 
    return self 
     .resource("/sessions") 
     .child(sessionId) 
     .child("orders") 
} 
func order(id: String) -> Resource { 
    return self 
     .resource("/orders") 
     .child(id) 
} 

變形金剛:

self.configureTransformer("/sessions/*/orders", requestMethods: [.post, .put]) { 
     try Order(json: ($0.content as JSON)["data"]) 
    } 

    self.configureTransformer("/orders/*") { 
     try Order(json: ($0.content as JSON)["data"]) 
    } 

我已經通過創建像字典結構設法圈這樣的:

let products: Array<Dictionary<String, Any>>? 

    products = json["products"].arrayValue.map({ 
     ["product": $0.dictionaryValue["product"]!.stringValue, "amount": $0.dictionaryValue["amount"]!.intValue] 
    }) 

但是我住在向下轉換的地獄,如果我需要做任何修改:

var data = createdObject?.toDictionary() 
data?["comment"] = "edited Swifty" 
//if I want to modify the products... 
var products = data?["products"] as! Array<Dictionary<String, Any>> 
products[0]["amount"] = 4 
data?["products"] = products 

如何發送那些原始的JSON a與Siesta混戰?他們很容易修改和閱讀!我瀏覽了午睡文檔和github問題沒有成功...

回答

2

您的問題是SwiftyJSON和Foundation的JSONSerialization之間不匹配;午睡恰好在它的中間。

InvalidJSONObject是西耶斯塔告訴你,基金會不明白你給它的東西 - 這將是你的toDictionary()方法返回的價值。該字典中的大部分內容看起來都很好:字符串,整數,浮點數。 (小心使用浮動貨幣,BTW)

罪魁禍首是products數組:它的[JSON],其中JSON是SwiftyJSON類型基金不知道該怎麼做。你應該在明確的,如果你把JSON值回簡單的字典:

dictionary["products"] = (products ?? []).map { $0.dictionaryObject } 

如果不這樣做,或者如果您需要在將來診斷一個類似的錯誤,刪除所有來自違規字典的值,然後將它們一次添加回來,以查看哪一個正在跳出JSONSerialization。

+0

太棒了!要編輯產品陣列,我仍然必須將其投射對嗎?如果我沒有,我會得到一個「沒有下標成員」的錯誤。我讀過Siesta docs,這不是一個好主意來修改你的實體屬性......是嗎? – SkarXa

+1

如果內容是'struct',那麼修改實體的內容就好了。 (包括字典和數組)。因爲結構具有價值語義,所以您確實創建了一個新值,而不是修改Resource已有的現有值。擔心的是如果內容是可變對象,則可以在觀察者未收到通知的情況下將其更改。 –