4

I'm replacing SwifyJSON library with Gloss. I have problems with converting my WS response to JSON format. In SwiftyJSON I did it this way:

guard let data = response.result.value else  {
            ...
            return
        }

let jsonData = JSON(data)

My response looks like this:

[{
  "lat": "45.2",
  "lon": "-79.38333",
  "name": "Sample"
}, {
  "lat": "23.43",
  "lon": "45.3",
  "name": "Sample"
}]

I need to create from this an array of JSON object ([JSON]) so I can use in this method:

let jsonArray = ?
guard let destinations = [Destination].fromJSONArray(jsonArray) else
{
    ...
    return
}

I tried:

guard let data = response.result.value as? [(String,AnyObject)] else  {
            ...
            return
}

and

guard let data = response.result.value as? [Gloss.JSON] else  {
            ...
            return
}

First one says: Cannot convert value of type '[(String, AnyObject)]' to expected argument type '[JSON]' Second: Initializer for conditional binding must have Optional type, not '[Destination]'

Cahir09
  • 501
  • 6
  • 14

2 Answers2

1

I had the exact same problem with the exact same "first" and "second" error messages from the question. Bellow is an extract of how I have solved it:

import Gloss
import Alamofire

...

Alamofire.request(.GET, url, parameters: params).responseJSON {
    response in switch response.result {
    case .Success(let json):
        // Here, stations is already an array of Station class
        let stations = [Station].fromJSONArray(json as! [Gloss.JSON])
        ...
    ...
}

And here is what looks like my Station class:

import Gloss

class Station: Decodable {
    var id: Int = 0
    var attribute1: Int = 0
    var attribute2: Int = 0

    init(id: Int, attribute1: Int, attribute2: Int) {
        super.init()
        self.id = id
        self.attribute1 = attribute1
        self.attribute2 = attribute2
    }

    required init?(json: JSON) {
        super.init()
        self.id = ("id" <~~ json)!
        self.attribute1 = ("attribute1" <~~ json)!
        self.attribute2 = ("attribute2" <~~ json)!
    }
}
Eduardo
  • 4,282
  • 2
  • 49
  • 63
0

Alamofire + Gloss do the work for you.

Following the docs (specifically here), I did this in one of my projects (simplified to remove distractions):

//iOS 9.3, Xcode 7.3

/// stripped-down version
struct Event: Decodable {
    var id: String?

    init?(json: JSON) {
    id = "id" <~~ json
    }
}

//...

func getEvents(completion: (AnyObject?) -> Void) {
    request(.GET, baseURL + endpointURL)
        .responseJSON { response in
            switch response.result {
            case .Failure(let error):
                print(error.localizedDescription)
            case .Success:
                guard let value = response.result.value as? JSON,
                let eventsArrayJSON = value["events"] as? [JSON] //Thus spake the particular API's docs
                else { fatalError() }
                let events = [Event].fromJSONArray(eventsArrayJSON)

                // do stuff with my new 'events' array of type [Events]
            }
        }
}

tl;dr

The magic is in combining Gloss's fromJSONArray[1] with Alamofire's .responseJSON serializer[2].

[1] Backed by init?(json: JSON), both in the Decodable protocol.

[2] Which spits out a Gloss-y JSON-type object, aka [String : AnyObject]-type.

Hope this helps. :)

Also check out this new cocoapod: Alamofire-Gloss

AmitaiB
  • 1,656
  • 1
  • 19
  • 19