sourcecode

iOS - 루트 JSON 어레이에 Object Mapper를 빠르게 매핑합니다.

copyscript 2023. 3. 10. 22:41
반응형

iOS - 루트 JSON 어레이에 Object Mapper를 빠르게 매핑합니다.

라이브러리 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 object Customer List를 작성하려고 했지만 작동하지 않습니다.

루트 어레이의 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에서는JSONObjectWithData(::)조건부 다운캐스팅으로[[String: AnyObject]]사용을 방지하기 위해NSArray또는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)
}

매핑처Customer사용.mapArray(:)방법

ObjectMapperMapperclass는 다음과 같은 메서드를 제공합니다.mapArray(:)다음 선언이 있습니다.

public func mapArray(JSONArray: [[String : AnyObject]]) -> [N]?

ObjectMapper매뉴얼에 기재되어 있습니다.

JSON 사전 배열을 표시 가능한 개체 배열에 매핑합니다.

따라서 최종 코드는 다음과 같습니다.

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)
}

매핑처Customer사용.map(:)방법

ObjectMapperMapperclass는 다음과 같은 메서드를 제공합니다.map(:)다음 선언이 있습니다.

func map(JSONDictionary: [String : AnyObject]) -> N?

ObjectMapper매뉴얼에 기재되어 있습니다.

JSON 사전을 Mappable에 적합한 개체에 매핑합니다.

이전 코드 대신 다음 코드는 JSON을 다음 코드에 매핑하는 방법을 보여줍니다.Customer사용.map(:):

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)
}

가장 쉬운 솔루션은 AlarmofireObjectMapper에서 제공합니다.를 사용합니다.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에서도 동일한 상황에서 root으로 Array에 객체 매퍼가 존재하도록 해결할 수 있습니다.

먼저 직렬화를 사용하여 json 문자열을 개체로 변환합니다.

let parsedMapperString = Mapper<Customer>.parseJSONString(JSONString: result) //result is string from json serializer

다음으로 JSON 딕셔너리의 MapSet에서 Mappable 객체의 배열로 고객 DTO를 가져올 수 있습니다.

let customerDto = Mapper<Customer>().mapSet(JSONArray: jsonParsed as! [[String : Any]])

도움이 됐으면 좋겠다.솔루션을 얻기 위해 저를 몰아붙인 @Nicolas님 덕분입니다.

루트 배열과 범용 개체를 매핑하는 문제를 해결하는 좋은 방법은 클래스 구현 내에서 개체를 사용하여 목록을 작성하는 범용 개체를 만드는 것입니다.다음에, 이러한 종류의 실장의 예를 나타냅니다.

    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
    }

위 코드에서는 대문자 변수를 사용자 고유의 값으로 채웁니다.클로징 내의 응답 반환이 Alarmofire의 범용 객체 DataResponse인지 확인하고 GenericResponseList라는 다른 객체를 작성했습니다.서버로부터 리스트를 취득하는 오브젝트 타입의 「< >」내부를 입력합니다.제 경우 SingleElements 목록입니다.

다음으로 Generic Response List의 실장을 살펴보겠습니다.

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 목록으로 변환됩니다.

도움이 됐으면 좋겠다:)

어레이를 json으로 변환한 후 되돌립니다.

let json = shops.toJSONString()
let shops = Array<Shop>(JSONString: json)

언급URL : https://stackoverflow.com/questions/32353026/ios-map-a-root-json-array-with-objectmapper-in-swift

반응형