ライブラリObjectMapperを使用してjsonをオブジェクトにマッピングしますが、ルートjson配列をマッピングするためにいくつかの問題があります。
これは、受け取ったjsonです。
_[
{
CustomerId = "A000015",
...
},
{
CustomerId = "A000016",
...
},
{
CustomerId = "A000017",
...
}
]
_
これは私のオブジェクトです
_class Customer : Mappable
{
var CustomerId : String? = nil
class func newInstance(map: Map) -> Mappable? {
return Customer()
}
func mapping(map: Map) {
CustomerId <- map["CustomerId"]
}
}
_
コントローラーのjsonをマッピングします
_let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as! NSArray
if (error != nil) {
return completionHandler(nil, error)
} else {
var customers = Mapper<Customer>().map(json)
}
_
しかし、動作しません。Mapper<[Customer]>().map(json)
を試しましたが、動作しません。最後に、Customer配列を含む新しいSwiftオブジェクトCustomerListを作成しようとしましたが、機能しません。
ルート配列のjsonをマップする方法のアイデアはありますか?
ありがとう。
私は最終的に私の問題を解決します:
コントローラーのマッピング方法は
let json : AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error)
if (error != nil) {
return completionHandler(nil, error)
} else {
var customer = Mapper<Customer>().mapArray(json)! //Swift 2
var customer = Mapper<Customer>().mapArray(JSONArray: json)! //Swift 3
}
それが誰かを助けることができるなら。
JSONObjectWithData(::)
を使用するJSONのタイプは_[[String: AnyObject]]
_です。したがって、Swift 2)では、_NSArray
または_[[String: AnyObject]]
_の使用を防ぐために、JSONObjectWithData(::)
をタイプ_AnyObject!
_の条件付きダウンキャストとともに使用できます。
_do {
if let jsonArray = try NSJSONSerialization
.JSONObjectWithData(data, options: []) as? [[String: AnyObject]] {
/* perform your ObjectMapper's mapping operation here */
} else {
/* ... */
}
}
catch let error as NSError {
print(error)
}
_
mapArray(:)
メソッドを使用したCustomer
へのマッピングObjectMapper
のMapper
クラスは、次の宣言を持つmapArray(:)
というメソッドを提供します。
public func mapArray(JSONArray: [[String : AnyObject]]) -> [N]?
ObjectMapper
ドキュメントには、それについて次のように記載されています。
JSON辞書の配列をMappableオブジェクトの配列にマップします
したがって、最終的なコードは次のようになります。
_do {
if let jsonArray = try NSJSONSerialization
.JSONObjectWithData(data, options: []) as? [[String: AnyObject]] {
let customerArray = Mapper<Customer>().mapArray(jsonArray)
print(customerArray) // customerArray is of type [Customer]?
} else {
/* ... */
}
}
catch let error as NSError {
print(error)
}
_
map(:)
メソッドを使用したCustomer
へのマッピングObjectMapper
のMapper
クラスは、次の宣言を持つmap(:)
というメソッドを提供します。
func map(JSONDictionary: [String : AnyObject]) -> N?
ObjectMapper
ドキュメントには、それについて次のように記載されています。
JSONディクショナリをMappableに準拠するオブジェクトにマップします
前のコードの代替として、次のコードは、map(:)
を使用してJSONをCustomer
にマップする方法を示しています。
_do {
if let jsonArray = try NSJSONSerialization
.JSONObjectWithData(data, options: []) as? [[String: AnyObject]] {
for element in jsonArray {
let customer = Mapper<Customer>().map(element)
print(customer) // customer is of type Customer?
}
} else {
/* ... */
}
}
catch let error as NSError {
print(error)
}
_
最も簡単な解決策は AlamofireObjectMapper によって提供されます。 responseArray()
簡易メソッドを使用します。
Alamofire.request(endpoint).responseArray { (response: DataResponse<[MyMappableClass]>) in
if let result = response.result.value {
// Customer array is here
} else if let error = response.result.error {
// Handle error
} else {
// Handle some other not networking error
}
}
私の最近のSwift 3の同じ状況で、ルートとしてオブジェクトマッパーが配列に存在するように解決できます。
最初に、シリアル化を使用してJSON文字列をオブジェクトに変換します。
let parsedMapperString = Mapper<Customer>.parseJSONString(JSONString: result) //result is string from json serializer
次に、JSON辞書のMapSetからMappableオブジェクトの配列にCustomer DTOを取得できます。
let customerDto = Mapper<Customer>().mapSet(JSONArray: jsonParsed as! [[String : Any]])
それが役に立てば幸い。ソリューションを取得するために私を近づけた@Nicolasに感謝します。
配列をjsonに変換して戻す:
let json = shops.toJSONString()
let shops = Array<Shop>(JSONString: json)
ルート配列を汎用オブジェクトにマッピングする問題を解決する良い方法は、クラス実装内のオブジェクトでリストを作成する汎用オブジェクトを作成することです。以下に、この種の実装の例を見てみましょう。
Alamofire.request(REQ_URL_STRING,
method: REQ_METHOD(eg.: .GET),
parameters: REQ_PARAMS,
encoding: REQ_ENCODING,
headers: REQ_HEADERS).responseObject { (response: DataResponse<GenericResponseList<SingleElement>>) in
//your code after serialization here
}
上記のコードでは、大文字の変数に独自の値を入力します。クロージャーで返される応答がAlamofireからの汎用オブジェクトDataResponseであることを確認し、GenericResponseListという別のオブジェクトを作成しました。サーバーからリストを取得するオブジェクトのタイプ「<>」を内部に配置します。私の場合、それはSingleElementsのリストでした。
次に、以下のGenericResponseListの実装を見てみましょう。
final class GenericResponseList<T: Mappable>: Mappable {
var result: [T]?
required convenience init?(map: Map) {
self.init()
}
func mapping(map: Map) {
result <- map["result"]
}
}
ご覧ください。このクラスに送信したジェネリック型のリストであるクラス内の変数があります。
var result: [T]?
したがって、JSONを取得すると、SingleElementのリストに変換されます。
それが助けたことを願っています:)