2016-12-05 11 views
2

私はSiestaとSwift 3をXcode 8で使用してAPIクライアントを構築しています。シエスタリソースを使用してエンティティを取得してから、データの一部を更新して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をシエスタといっしょに?彼らは本当に簡単に変更して読むことができます! siestaのドキュメントとgithubの問題を無事に閲覧しました...

答えて

2

問題は、SwiftyJSONとFoundationのJSONSerializationの不一致です。シエスタはちょうどその途中にある。

は、ファンデーションがあなたに与えたことを理解していないことを伝えています。あなたのtoDictionary()メソッドによって返された値です。その辞書のほとんどのものはよく見えます。文字列、int、浮動小数点数です。 (。ところで、お金のためにフロートを使用する方法について慎重に)

犯人はそのproducts配列である:それはJSONは、財団はと何をするかわからないSwiftyJSONタイプである[JSON]、です。あなたは、単純な辞書に戻すJSON値を有効にした場合明確にする必要があります:

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

をそれはそれをしない場合、またはあなたが将来的に同様のエラーを診断する必要がある場合は、すべて削除します値を問題のディクショナリから削除して、一度に1つずつ追加してJSONSerializationをトリプルしているものを確認してください。

+0

恐ろしい!製品の配列を編集するには、私はまだそれを正しくキャストする必要がありますか?私がしなければ、「下付きメンバはありません」というエラーが出ます。 Siestaのドキュメントでは、エンティティの属性を変更するのは良い考えではありません...そうですか? – SkarXa

+1

コンテンツが 'struct'の場合は、エンティティのコンテンツを変更するだけです。構造体には値のセマンティクスがあるため、実際には新しい値を作成しており、すでに保持されている既存の値は変更しません。懸念事項は、コンテンツが変更可能なオブジェクトである場合、オブザーバーに通知されることなくそのコンテンツを変更できることです。 –

関連する問題