Swift: How to save a Decodable.Protocol object to a variable? - ios

In my application, several controllers have a very similar code structure, the differences are minimal, so for optimization I decided to create a basis for these controllers, and inherit each specific controller from the basis.
I have a function for sending network requests and processing a response, I pass the response structure as a parameter to this function, so that the function returns a ready-made response structure to me. Each such structure is Decodable.
An example of such a structure:
struct APIAnswerUserActivity: Decodable {
let status: String
let code: Int?
let data: [UserActivity]?
let total: Int?
}
Function for network requests, an object (structure) of the Decodable.Protocol type is accepted as a jsonType parameter:
public func networkRequest<T: Decodable> (
url: String,
timeout: Double = 30,
method: URLMethods = .GET,
data: [String : String]? = nil,
files: [URL]? = nil,
jsonType: T.Type,
success: #escaping (T) -> Void,
failure: #escaping (APIError) -> Void
) -> URLSessionDataTask { ... }
There are several parameters in the main controller that I override through override in the child controllers, one of these parameters should be an object of type Decodable for the general function to receive data correctly. The JSON structures of the response are very similar, but still slightly different, a common structure for them cannot be created, because the data is still a little different.
If in the main controller do this:
public var decodableType: Decodable.Type {
return APIAnswerUserActivity.self
}
That will work, and it is possible to redefine types, but the network function does not accept this, it needs the Decodable.Protocol object. If the type decodable.Protocol is specified for the variable decodableType, then it is no longer possible to add APIAnswerUserActivity.self, which is quietly accepted when the networkRequest function is called.
How to be in this situation? I hope that I managed to correctly and clearly state the essence of my problem. Thanks!

#Владислав Артемьев, I'm still not sure that I completely understand the problem because you haven't shared the code that takes the Decodable class. But the issues seems to be about how to pass a Decodable class.
I hope the following can help clarify how you can impose the right constraint on the generic and how you should declare the variable. You can paste it into a playground and experiment.
import Foundation
struct FakeToDo: Decodable {
var userId: Int
var id: Int
var title: String
var completed: Bool
}
enum URLMethods {
case GET
case POST
}
func networkRequest<T: Decodable> (
url: String,
timeout: Double = 30,
method: URLMethods = .GET,
data: [String : String]? = nil,
files: [URL]? = nil,
jsonType: T.Type,
success: #escaping (T) -> Void,
failure: #escaping (Error) -> Void
) -> URLSessionDataTask {
let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { (data, response, error) in
if error != nil {
failure(error!)
return
}
guard let data = data else { return }
let decoder = JSONDecoder()
guard let value = try? decoder.decode(T.self, from: data) else { return }
// get back on the main queue for UI
DispatchQueue.main.async {
success(value)
}
})
return task
}
class Example<T> where T: Decodable {
let type: T.Type
init(_ type: T.Type) {
self.type = type
}
public var decodableType: T.Type {
return type
}
}
let decodableType = Example(FakeToDo.self).decodableType
let url = "https://jsonplaceholder.typicode.com/todos/1"
let task = networkRequest(url: url, jsonType: decodableType,
success: { value in print(value) },
failure: { error in print(error) })
task.resume()

Related

Function not returning value from closure

I need to return a value from a function that has a closure in it.
I researched about returning value from closures, and found out that I should use 'completion handler' to get the result I want.
I saw posts here and articles explaining it but could not apply because I didn't find anything that matches with my problem.
class ViewController: UIViewController {
let urls = URLs()
override func viewDidLoad() {
super.viewDidLoad()
var leagueId = getLeagueId(country: "brazil", season: "2019")
print(leagueId) //PRINTING 0
}
func getLeagueId (country: String, season: String) -> Int {
let headers = Headers().getHeaders()
var leagueId = 0
let url = urls.getLeagueUrlByCountryAndSeason(country: country, season: season)
Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers).responseJSON {
response in
if response.result.isSuccess {
let leagueJSON: JSON = JSON(response.result.value!)
leagueId = (leagueJSON["api"]["leagues"][0]["league_id"].intValue)
}
else {
print("error")
}
}
return leagueId
}
}
The value returned is always 0 because the closure value is not passing to the function itself.
Thanks a lot
So the reason why you're having this issue is because AlamoFire.request is asynchronous. There's a great explanation of asynchronous vs synchronous here But basically when you execute something asynchronously, the compiler does not wait for the task to complete before continuing to the next task, but instead will execute the next task immediately.
So in your case, the AlamoFire.request is executed, and while it's running, the next line after the block is immediately run which is the line to return leagueId which will obviously still be equal to zero since the AlamoFire.request task (function) has not yet finished.
This is why you need to use a closure. A closure will allow you to return the value, after AlamoFire.request (or any other asynchronous task for that matter) has finished running. Manav's answer above shows you the proper way to do this in Swift. I just thought I'd help you understand why this is necessary.
Hope this helps somewhat!
Edit:
Manav's answer above is actually partially correct. Here's how you make it so you can reuse that value the proper way.
var myLeagueId = 0;
getLeagueId(country: "brazil", season: "2019",success: { (leagueId) in
// leagueId is the value returned from the closure
myLeagueId = leagueId
print(myLeagueId)
})
The code below will not work because it's setting myLeagueId to the return value of getLeagueId and getLeagueId doesn't have a return value so it won't even compile.
myLeagueId = getLeagueId(country: "brazil", season: "2019",success: { (leagueId) in
print(leagueId)
})
You need to either return value from the function.
func getLeagueId (country: String, season: String)->Int
Else you need to use completion handlers.
func getLeagueId (country: String, season: String,success:#escaping (leagueId: Int) -> Void) {
let headers = Headers().getHeaders()
var leagueId = 0
let url = urls.getLeagueUrlByCountryAndSeason(country: country, season: season)
Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers).responseJSON {
response in
if response.result.isSuccess {
let leagueJSON: JSON = JSON(response.result.value!)
leagueId = (leagueJSON["api"]["leagues"][0]["league_id"].intValue)
success(leagueId)
}
else {
print("error")
}
}
}
And then use it in your code :
getLeagueId(country: "brazil", season: "2019",success: { (leagueId) in
print(leagueId)
self.leagueId = leagueId
})
This is how you should implement completionBLock
func getLeagueId (country: String, season: String, completionBlock:((_ id: String, _ error: Error?) -> Void)?) {
let headers = Headers().getHeaders()
var leagueId = 0
let url = urls.getLeagueUrlByCountryAndSeason(country: country, season: season)
Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers).responseJSON {
response in
if response.result.isSuccess {
let leagueJSON: JSON = JSON(response.result.value!)
if let leagueId = (leagueJSON["api"]["leagues"][0]["league_id"].intValue){
completionBlock?(leagueId,nil)
}else {
completionBlock?(nil,nil) // PASS YOUR ERROR
}
}
else {
completionBlock?(nil,nil) // PASS YOUR ERROR
}
}
}
func getLeagueId isn't return anything so you get 0, if you want to get the result from func getLeagueId you should add completion handler function that will update this value.

iOS Networking Layer Architecture

Reason For Post
There are so many different solutions & examples on how to build a proper networking layer, but every app has different constraints, and design decisions are made based on trade-offs, leaving me uncertain about the quality of code I've written. If there are any Anti-Patterns, redundancies, or flat out bad solutions within my code that I have overlooked or simply lacked the knowledge to address, please do critique. This is a project I'd like to add to my portfolio, so I'm posting it here to get eyes on it, with some advice/tips.
Thanks for your time in advanced!
Some characteristics of my networking layer that I think could raise eyebrows:
Method contains a GETALL case, to indicate a list of data that must be fetched. I have not seen this in any of the open source code I've read. Is this a code smell?
enum Method {
case GET
/// Indicates how JSON response should be handled differently to abastract a list of entities
case GETALL
case PUT
case DELETE
}
I've made it, so each Swift Entity conforms to JSONable protocol, meaning it can be initialized with json and converted to json.
protocol JSONable {
init?(json: [String: AnyObject])
func toJSON() -> Data?
}
JSONable in practice with one of my entities:
struct User {
var id: String
var name: String
var location: String
var rating: Double
var keywords: NSArray
var profileImageUrl: String
}
extension User: JSONable {
init?(json: [String : AnyObject]) {
guard let id = json[Constant.id] as? String, let name = json[Constant.name] as? String, let location = json[Constant.location] as? String, let rating = json[Constant.rating] as? Double, let keywords = json[Constant.keywords] as? NSArray, let profileImageUrl = json[Constant.profileImageUrl] as? String else {
return nil
}
self.init(id: id, name: name, location: location, rating: rating, keywords: keywords, profileImageUrl: profileImageUrl)
}
func toJSON() -> Data? {
let data: [String: Any] = [Constant.id: id, Constant.name: name, Constant.location: location, Constant.rating: rating, Constant.keywords: keywords, Constant.profileImageUrl: profileImageUrl]
let jsonData = try? JSONSerialization.data(withJSONObject: data, options: [])
return jsonData
}
}
This allows me to use generics to initialize all my entities in my client- FirebaseAPI, after I retrieve JSON response. I also haven't seen this technique in the code I've read.
In the code below, notice how GETALL is implemented to flatten the list of JSON objects. Should I have to do this at all? Is there a better way to handle any type of Json structure response?
AND Entities are initialized generically, and returned as an Observable ( Using RxSwift ).
Do you sense any code smells?
/// Responsible for Making actual API requests & Handling response
/// Returns an observable object that conforms to JSONable protocol.
/// Entities that confrom to JSONable just means they can be initialized with json & transformed from swift to JSON.
func rx_fireRequest<Entity: JSONable>(_ endpoint: FirebaseEndpoint, ofType _: Entity.Type ) -> Observable<[Entity]> {
return Observable.create { [weak self] observer in
self?.session.dataTask(with: endpoint.request, completionHandler: { (data, response, error) in
/// Parse response from request.
let parsedResponse = Parser(data: data, response: response, error: error)
.parse()
switch parsedResponse {
case .error(let error):
observer.onError(error)
return
case .success(let data):
var entities = [Entity]()
switch endpoint.method {
/// Flatten JSON strucuture to retrieve a list of entities.
/// Denoted by 'GETALL' method.
case .GETALL:
/// Key (underscored) is unique identifier for each entity
/// value is k/v pairs of entity attributes.
for (_, value) in data {
if let value = value as? [String: AnyObject], let entity = Entity(json: value) {
entities.append(entity)
}
}
/// Force downcast for generic type inference.
observer.onNext(entities as! [Entity])
//observer.onCompleted()
/// All other methods return JSON that can be used to initialize JSONable entities
default:
if let entity = Entity(json: data) {
observer.onNext([entity] as! [Entity])
//observer.onCompleted()
} else {
observer.onError(NetworkError.initializationFailure)
}
}
}
}).resume()
return Disposables.create()
}
}
}
I manage different endpoints like so:
enum FirebaseEndpoint {
case saveUser(data: [String: AnyObject])
case fetchUser(id: String)
case removeUser(id: String)
case saveItem(data: [String: AnyObject])
case fetchItem(id: String)
case fetchItems
case removeItem(id: String)
case saveMessage(data: [String: AnyObject])
case fetchMessages(chatroomId: String)
case removeMessage(id: String)
}
extension FirebaseEndpoint: Endpoint {
var base: String {
// Add this as a constant to APP Secrts struct & dont include secrets file when pushed to github.
return "https://AppName.firebaseio.com"
}
var path: String {
switch self {
case .saveUser(let data): return "/\(Constant.users)/\(data[Constant.id])"
case .fetchUser(let id): return "/\(Constant.users)/\(id)"
case .removeUser(let id): return "/\(Constant.users)/\(id)"
case .saveItem(let data): return "/\(Constant.items)/\(data[Constant.id])"
case .fetchItem(let id): return "/\(Constant.items)/\(id)"
case .fetchItems: return "/\(Constant.items)"
case .removeItem(let id): return "/\(Constant.items)/\(id)"
case .saveMessage(let data): return "/\(Constant.messages)/\(data[Constant.id])"
case .fetchMessages(let chatroomId): return "\(Constant.messages)/\(chatroomId)"
case .removeMessage(let id): return "/\(Constant.messages)/\(id)"
}
}
var method: Method {
switch self {
case .fetchUser, .fetchItem: return .GET
case .fetchItems, .fetchMessages: return .GETALL
case .saveUser, .saveItem, .saveMessage: return .PUT
case .removeUser, .removeItem, .removeMessage: return .DELETE
}
}
var body: [String : AnyObject]? {
switch self {
case .saveItem(let data), .saveUser(let data), .saveMessage(let data): return data
default: return nil
}
}
}
Last thing, I'd like someone with professional eyes to look at is, how I use MVVM. I make all network requests from view model, which comes out looking something like this:
struct SearchViewModel {
// Outputs
var collectionItems: Observable<[Item]>
var error: Observable<Error>
init(controlValue: Observable<Int>, api: FirebaseAPI, user: User) {
let serverItems = controlValue
.map { ItemCategory(rawValue: $0) }
.filter { $0 != nil }.map { $0! }
.flatMap { api.rx_fetchItems(for: user, category: $0)
.materialize()
}
.filter { !$0.isCompleted }
.shareReplayLatestWhileConnected()
collectionItems = serverItems.filter { $0.element != nil }.dematerialize()
error = serverItems.filter { $0.error != nil }.map { $0.error! }
}
}
In order to call api requests in a more expressive, formalized way, I am able to call api.rx_fetchItems(for:) inside flatmap above, because I extend FirebaseAPI to conform to FetchItemsAPI. I will probably have to follow the same pattern for most other requests.
extension FirebaseAPI: FetchItemsAPI {
// MARK: Fetch Items Protocol
func rx_fetchItems(for user: User, category: ItemCategory) -> Observable<[Item]> {
// fetched items returns all items in database as Observable<[Item]>
let fetchedItems = rx_fireRequest(.fetchItems, ofType: Item.self)
switch category {
case .Local:
let localItems = fetchedItems
.flatMapLatest { (itemList) -> Observable<[Item]> in
return self.rx_localItems(user: user, items: itemList)
}
return localItems
case .RecentlyAdded:
// Compare current date to creation date of item. If its within 24 hours, It makes the cut.
let recentlyAddedItems = fetchedItems
.flatMapLatest { (itemList) -> Observable<[Item]> in
return self.rx_recentlyAddedItems(items: itemList)
}
return recentlyAddedItems
case .Trending:
let trendingItems = fetchedItems
.flatMapLatest { (itemList) -> Observable<[Item]> in
return self.rx_trendingItems(items: itemList)
}
return trendingItems
default:
let stubItem = Item(id: "DEFAULT", createdById: "createdBy", creationDate: 1.3, expirationDate: 2.4, title: "title", price: 2, info: "info", imageUrl: "url", bidCount: 4, location: "LA")
return Observable.just([stubItem])
}
}
// MARK: Helper Methods
private func rx_localItems(user: User, items: [Item]) -> Observable<[Item]> {
return Observable<[Item]>.create { observer in
observer.onNext(items.filter { $0.location == user.location }) // LA Matches stubs in db
return Disposables.create()
}
}
func rx_recentlyAddedItems(items: [Item]) -> Observable<[Item]> {
return Observable<[Item]>.create { observer in
let recentItems = items
.filter {
let now = Date(timeIntervalSinceReferenceDate: 0)
let creationDate = Date(timeIntervalSince1970: $0.creationDate)
if let hoursAgo = now.offset(from: creationDate, units: [.hour], maxUnits: 1) {
return Int(hoursAgo)! < 24
} else {
return false
}
}
observer.onNext(recentItems)
return Disposables.create()
}
}
func rx_trendingItems(items: [Item]) -> Observable<[Item]> {
return Observable<[Item]>.create { observer in
observer.onNext(items.filter { $0.bidCount > 8 })
return Disposables.create()
}
}
}
I'm attempting to follow SOLID principles, and level up with RxSWift + MVVM, so I'm still unsure about the best OOP design for clean, maintainable code.

Can swift closures be set to a default value when used as a parameter in a function?

A pretty handy feature of Swift functions is that function parameters can have default values:
func someFunction(parameterWithDefault: Int = 42) {
//if no arguments are passed to the function call,
//value of parameterWithDefault is 42
}
If a parameter is a closure, is there a way to make it have a default value? See the example below:
func sendBody(
body: NSData? = nil,
success: (data: NSData) -> Void,
failure: (data: NSData?) -> Void) {
}
Is there a way to not force the developer to pass a value for success or failure when calling sendBody?
Yes, functions are just values, so you can supply them as defaults
// just to show you can do it with inline closures or regular functions
func doNothing<T>(t: T) -> Void { }
func sendBody(
body: NSData? = nil,
success: (data: NSData) -> Void = { _ in return },
failure: (data: NSData?) -> Void = doNothing
)
{ }
Alternatively, you could make them optional, that way you can detect if the caller passed one:
func sendBody(
body: NSData? = nil,
success: ((NSData) -> Void)? = nil,
failure: ((NSData?) -> Void)? = nil
)
{ success?(NSData()) }
sendBody(success: { _ in print("ah, yeah!") })
Also worth noting if you’re doing this: if the caller uses the trailing closure syntax, this will be the last closure in the argument list. So you want the last one to be the one the user is most likely to want to supply, which is probably the success closure:
func sendBody(
body: NSData? = nil,
success: ((NSData) -> Void)? = nil,
failure: ((NSData?) -> Void)? = nil
)
{
if success != nil { print("passed a success closure") }
if failure != nil { print("passed a failure closure") }
}
// this prints "passed a failure closure"
sendBody { data in
print("which closure is this?")
}
Other than this, the order in the function declaration doesn’t matter to the caller – defaulted arguments can be supplied in any order.
You could do something like this,
let defaultSuccess: NSData -> Void = {
(data: NSData) in
}
let defaultFailure: NSData? -> Void = {
(data: NSData?) in
}
func sendBody( body: NSData? = nil, success: (data: NSData) -> Void = defaultSuccess, failure: (data: NSData?) -> Void = defaultFailure) {
}
Then, you may be able to call either one of these methods. Notice sendBody which is called with default parameters.
sendBody()
sendBody(body: , success: , failure: )
You can also call with all the variants like passing just one of the argument in the above method, for that you have to call it with named parameter.
sendBody()
sendBody(body:)
sendBody(failure: )
sendBody(success:)
sendBody(body: , success: , failure: )
How to set a default value for a function parameter. Swift 4 and (probably) 5.
func someFunction(age: Int, doSomething:#escaping () -> Void = {}){
//do work here
//
doSomething()
}
Then you can do this
someFunction(age: 18) {
print("hello")
}
someFunction(age: 19)
You may or may not need to use the #escaping keyword. See Swift #escaping and Completion Handler for that.
My preferred way to specify public facing closures - in particular completion closures which you might want to store somewhere for later - is to define a typealias for them, like this:
public typealias FooCompletion = (String) -> Void
Then in the public facing function you can easily make it optional like this:
var onCompletion: FooCompletion? = nil
public func foo(completion: FooCompletion? = nil) {
// Store completion for later
onCompletion = completion
}
The completion parameter is optional, so it's allowed to be nil, and the default value is nil, meaning the caller doesn't have to specify it. Also, because you use the type in more than one place, if you need to change its definition during development there's only one place to do so. It's easy to call too:
private func someBackgroundThing() {
var completionString = "done"
...
onCompletion?(completionString)
}

EXC_BAD_ACCESS using Generics in Swift

Related question: Generic completion handler in Swift
In a Swift app I'm writing, I'm downloading JSON and I want to convert it into model objects. Right now, I'm doing that like this:
func convertJSONData<T: Entity>(jsonData: NSData?, jsonKey: JSONKey, _: T.Type) -> [T]? {
var entities = [T]()
if let data = jsonData {
// Left out error checking for brevity
var json = JSON(data: data, options: nil, error: nil)
var entitiesJSON = json[jsonKey.rawValue]
for (index: String, subJson: JSON) in entitiesJSON {
// Error: EXC_BAD_ACCESS(code=EXC_I386_GPFLT)
let entity = T(json: subJson)
entities.append(entity)
}
}
return entities
}
Each object conforming to Entity implements init(json: JSON). JSON is a type defined in the SwiftyJSON library. That's also the reason the enumeration looks a bit weird.
I call convertJSONData() in this method:
public func performJSONRequest<T where T: Entity>(jsonRequest: JSONRequest<T>) {
var urlString = ...
Alamofire.request(.GET, urlString, parameters: nil, encoding: .JSON).response { (request, response, data, error) -> Void in
var books = self.convertJSONData(data as? NSData, jsonKey: jsonRequest.jsonKey, T.self)
jsonRequest.completionHandler(books, error)
}
}
I get a runtime EXC_BAD_ACCESS(code=EXC_I386_GPFLT) error calling T(json: subJSON). There are no compiler warnings or errors. Although I left out error checking in the above code, there is error checking in the actual code and error is nil.
I'm not sure whether this is a compiler bug or my fault and any help figuring that out is much appreciated.
Several things are going on here, and I suspect the problem lies somewhere in the initializer of the class implementing the Entity protocol.
Assuming the code resembles the following:
protocol Entity {
init(json: JSON)
}
class EntityBase: Entity {
var name: String = ""
required init(json: JSON) { // required keyword is vital for correct type inference
if let nameFromJson = json["name"].string {
self.name = nameFromJson
}
}
func getName() -> String { return "Base with \(name)" }
}
class EntitySub: EntityBase {
convenience required init(json: JSON) {
self.init(json: json) // the offending line
}
override func getName() -> String { return "Sub with \(name)" }
}
The code compiles with self.init(json: json) in the sub-class, but actually trying to initialize the instance using the convenience method results in an EXC_BAD_ACCESS.
Either remove the initializer on the sub-class or simply implement required init and call super.
class EntitySub: EntityBase {
required init(json: JSON) {
super.init(json: json)
}
override func getName() -> String { return "Sub with \(name)" }
}
The method to convert the jsonData to an Entity (modified slightly to specifically return .None when jsonData is nil):
func convertJSONData<T:Entity>(jsonData: NSData?, jsonKey: JSONKey, type _:T.Type) -> [T]? {
if let jsonData = jsonData {
var entities = [T]()
let json = JSON(data: jsonData, options:nil, error:nil)
let entitiesJSON = json[jsonKey.rawValue]
for (index:String, subJson:JSON) in entitiesJSON {
let entity:T = T(json: subJson)
entities.append(entity)
}
return entities
}
return .None
}

AnyObject to array in swift

Following function is given:
class func collection(#response: NSHTTPURLResponse,
representation: AnyObject) -> [City] {
return []
}
So this function should return an array of city objects. I have to somehow transform the representation variable that is of type AnyObject to a city array.
I don't know what the exact type of representation is but I can do things like
println(representation[0])
and it will print the object. Any ideas how to transform representation to [City] array?
Update
Doing
println(representation as [City])
prints nil.
City.swift:
final class City : ResponseCollectionSerializable {
let id: String
let name: String
class func collection(#response: NSHTTPURLResponse, representation: AnyObject) -> [City] {
return []
}
}
This is just copy and pasted from https://github.com/Alamofire/Alamofire#generic-response-object-serialization It should serialize a JSON response into objects:
#objc public protocol ResponseCollectionSerializable {
class func collection(#response: NSHTTPURLResponse, representation: AnyObject) -> [Self]
}
extension Alamofire.Request {
public func responseCollection<T: ResponseCollectionSerializable>(completionHandler: (NSURLRequest, NSHTTPURLResponse?, [T]?, NSError?) -> Void) -> Self {
let serializer: Serializer = { (request, response, data) in
let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
let (JSON: AnyObject?, serializationError) = JSONSerializer(request, response, data)
if response != nil && JSON != nil {
return (T.collection(response: response!, representation: JSON!), nil)
} else {
return (nil, serializationError)
}
}
return response(serializer: serializer, completionHandler: { (request, response, object, error) in
completionHandler(request, response, object as? [T], error)
})
}
}
The representation parameter you're getting back is the result of a call to NSJSONSerialization.JSONObjectWithData..., so it's either a NSArray or a NSDictionary. Since you get a value for representation[0], we know it's an NSArray. Exactly what your code looks like will depend on the JSON (a sample of which you should include in a question like this), but your code will need to be something like (untested code ahead):
class func collection(#response: NSHTTPURLResponse, representation: AnyObject) -> [City] {
var cities: [City] = []
for cityRep in representation {
// these next two lines should grab the city data using the correct key
let id = cityRep.valueForKey("cityID") as String
let name = cityRep.valueForKey("cityName") as String
// now add the city to our list
cities.append(City(id: id, name: name))
}
return cities
}
Assuming (and although I hate to make assumptions, your question is a bit vague about the details) that the representation is either an NSData object that represents the response, or an Array that you have created from the response.
In my experience, such a response is an array of dictionaries that you can use to create city objects. So you need to write a function that transforms this dictionary into a City object. Something with the signature:
parser (AnyObject) -> City
Now, you could just iterate through the array, apply this function to each dictionary, collect the results into an Array and return the result.
But you could be classier and map your function over the array and return the result.

Resources