2016-12-05 14 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已有的现有值。担心的是如果内容是可变对象,则可以在观察者未收到通知的情况下将其更改。 –