AlamofireObjectMappe - An Alamofire extension which converts JSON response data into swift objects using ObjectMapper

Overview

AlamofireObjectMapper

Build Status CocoaPods Carthage compatible

An extension to Alamofire which automatically converts JSON response data into swift objects using ObjectMapper.

Usage

Given a URL which returns weather data in the following form:

{
    "location": "Toronto, Canada",    
    "three_day_forecast": [
        { 
            "conditions": "Partly cloudy",
            "day" : "Monday",
            "temperature": 20 
        },
        { 
            "conditions": "Showers",
            "day" : "Tuesday",
            "temperature": 22 
        },
        { 
            "conditions": "Sunny",
            "day" : "Wednesday",
            "temperature": 28 
        }
    ]
}

You can use the extension as the follows:

) in let weatherResponse = response.result.value print(weatherResponse?.location) if let threeDayForecast = weatherResponse?.threeDayForecast { for forecast in threeDayForecast { print(forecast.day) print(forecast.temperature) } } } ">
import AlamofireObjectMapper

let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/d8bb95982be8a11a2308e779bb9a9707ebe42ede/sample_json"
Alamofire.request(URL).responseObject { (response: DataResponse<WeatherResponse>) in

    let weatherResponse = response.result.value
    print(weatherResponse?.location)
    
    if let threeDayForecast = weatherResponse?.threeDayForecast {
        for forecast in threeDayForecast {
            print(forecast.day)
            print(forecast.temperature)           
        }
    }
}

The WeatherResponse object in the completion handler is a custom object which you define. The only requirement is that the object must conform to ObjectMapper's Mappable protocol. In the above example, the WeatherResponse object looks like the following:

import ObjectMapper

class WeatherResponse: Mappable {
    var location: String?
    var threeDayForecast: [Forecast]?
    
	required init?(map: Map){

	}
    
    func mapping(map: Map) {
        location <- map["location"]
        threeDayForecast <- map["three_day_forecast"]
    }
}

class Forecast: Mappable {
    var day: String?
    var temperature: Int?
    var conditions: String?
    
	required init?(map: Map){

	}
    
    func mapping(map: Map) {
        day <- map["day"]
        temperature <- map["temperature"]
        conditions <- map["conditions"]
    }
}

The extension uses Generics to allow you to create your own custom response objects. Below is the responseObject function definition. Just replace T in the completionHandler with your custom response object and the extension handles the rest:

public func responseObject<T: BaseMappable>(queue: DispatchQueue? = nil, keyPath: String? = nil, mapToObject object: T? = nil, context: MapContext? = nil, completionHandler: @escaping (DataResponse) -> Void) -> Self

The responseObject function has 4 optional parameters and a required completionHandler:

  • queue: The queue on which the completion handler is dispatched.
  • keyPath: The key path of the JSON where object mapping should be performed.
  • mapToObject: An object to perform the mapping on to.
  • context: A context object that is passed to the mapping function.
  • completionHandler: A closure to be executed once the request has finished and the data has been mapped by ObjectMapper.

Easy Mapping of Nested Objects

AlamofireObjectMapper supports dot notation within keys for easy mapping of nested objects. Given the following JSON String:

"distance" : {
     "text" : "102 ft",
     "value" : 31
}

You can access the nested objects as follows:

func mapping(map: Map) {
    distance <- map["distance.value"]
}

See complete documentation

KeyPath

The keyPath variable is used to drill down into a JSON response and only map the data found at that keyPath. It supports nested values such as data.weather to drill down several levels in a JSON response.

) in expectation.fulfill() let weatherResponse = response.result.value print(weatherResponse?.location) if let threeDayForecast = weatherResponse?.threeDayForecast { for forecast in threeDayForecast { print(forecast.day) print(forecast.temperature) } } } ">
let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/2ee8f34d21e8febfdefb2b3a403f18a43818d70a/sample_keypath_json"
let expectation = expectationWithDescription("\(URL)")

Alamofire.request(URL).responseObject(keyPath: "data") { (response: DataResponse<WeatherResponse>) in
    expectation.fulfill()
    
    let weatherResponse = response.result.value
    print(weatherResponse?.location)
    
    if let threeDayForecast = weatherResponse?.threeDayForecast {
        for forecast in threeDayForecast {
            print(forecast.day)
            print(forecast.temperature)           
        }
    }
}

Array Responses

If you have an endpoint that returns data in Array form you can map it with the following function:

public func responseArray<T: Mappable>(queue queue: dispatch_queue_t? = nil, keyPath: String? = nil, completionHandler: DataResponse<[T]> -> Void) -> Self

For example, if your endpoint returns the following:

[
    { 
        "conditions": "Partly cloudy",
        "day" : "Monday",
        "temperature": 20 
    },
    { 
        "conditions": "Showers",
        "day" : "Tuesday",
        "temperature": 22 
    },
    { 
        "conditions": "Sunny",
        "day" : "Wednesday",
        "temperature": 28 
    }
]

You can request and map it as follows:

) in let forecastArray = response.result.value if let forecastArray = forecastArray { for forecast in forecastArray { print(forecast.day) print(forecast.temperature) } } } ">
let URL = "https://raw.githubusercontent.com/tristanhimmelman/AlamofireObjectMapper/f583be1121dbc5e9b0381b3017718a70c31054f7/sample_array_json"
Alamofire.request(URL).responseArray { (response: DataResponse<[Forecast]>) in

    let forecastArray = response.result.value
    
    if let forecastArray = forecastArray {
        for forecast in forecastArray {
            print(forecast.day)
            print(forecast.temperature)           
        }
    }
}

Installation

AlamofireObjectMapper can be added to your project using CocoaPods by adding the following line to your Podfile:

pod 'AlamofireObjectMapper', '~> 5.2'

If you're using Carthage you can add a dependency on AlamofireObjectMapper by adding it to your Cartfile:

5.2 ">
github "tristanhimmelman/AlamofireObjectMapper" ~> 5.2
Comments
  •  Generic type 'DataResponse' specialized with too few type parameters (got 1, but expected 2)

    Generic type 'DataResponse' specialized with too few type parameters (got 1, but expected 2)

    Versions i use:

    AlamofireObjectMapper 6.1.0 ObjectMapper 3.5.1 Alamofire 5.0.0-rc.2

    Problem with .responseArray:

          AF.request(getUrlAPI(.GetAllMembers, apiVersion: "v4"), parameters: self.apiParams)
             
             .responseArray{ (response: DataResponse<[MemberJSON]>) in    
    

    Error:

    image

    opened by deezaster 14
  • dyld`dyld_fatal_error

    dyld`dyld_fatal_error

    Hi,

    My configuration:

    • Xcode 7.3.1
    • Carthage 0.16.2

    On my Cartfile:

    github "tristanhimmelman/AlamofireObjectMapper" == 3.0.0
    

    On each time I run the application on the device (not the simulator) it's crash like this:

    dyld`dyld_fatal_error:
    ->  0x120075088 <+0>: brk    #0x3
    

    After some investigation I changed my Cartfile like this:

    github "Alamofire/Alamofire" == 3.4.0
    github "Hearst-DD/ObjectMapper" == 1.2.0
    github "tristanhimmelman/AlamofireObjectMapper" == 3.0.0
    

    With ObjectMapper 1.2.0 no crash AlamofireObjectMapper is not compatible with ObjectMapper 1.3.0?!?!?

    opened by TofPlay 14
  • Alamofire 4.0.0-beta1 support

    Alamofire 4.0.0-beta1 support

    - `Alamofire (from `https://github.com/Alamofire/Alamofire.git`, branch `swift3`)` required by `Podfile`
    - `Alamofire (= 4.0.0)` required by `Podfile.lock`
    - `Alamofire (~> 3.2)` required by `AlamofireObjectMapper (3.0.0)`
    

    I am using the swift-3 branch but I'm quite sure it is the same with the master branch.

    opened by Tulleb 13
  • Add functionality to automatically parse JSON to Mappable Swift classes.

    Add functionality to automatically parse JSON to Mappable Swift classes.

    I wrote a little method in my own project to add this functionality and figured it'd be useful in the main project. I can reformat it and/or unstage any unwanted changes to existing project files if it's a welcome addition. Thanks for taking a look.

    opened by jacoblubecki 13
  • Runtime crash due to ObjectMapper update till 2.2.2

    Runtime crash due to ObjectMapper update till 2.2.2

    3 days ago ObjectMapper was updated to 2.2.2 version. Main change - added new parameter to init https://github.com/Hearst-DD/ObjectMapper/commit/fc44253abc5b1d79e6d68c46c61940a45d642929

    This cause runtime crash

    dyld: lazy symbol binding failed: Symbol not found: _TFC12ObjectMapper6MapperCfT7contextGSqPS_10MapContext___GS0_x Referenced from: /Users/romanvolkov/Library/Developer/CoreSimulator/Devices/B7317F47-8E47-497D-93FB-F72C5B14D11C/data/Containers/Bundle/Application/D733CFF5-CE84-4773-A037-0AE9735BF0B3/Treasure Hunt.app/Frameworks/AlamofireObjectMapper.framework/AlamofireObjectMapper Expected in: /Users/romanvolkov/Library/Developer/CoreSimulator/Devices/B7317F47-8E47-497D-93FB-F72C5B14D11C/data/Containers/Bundle/Application/D733CFF5-CE84-4773-A037-0AE9735BF0B3/Treasure Hunt.app/Frameworks/ObjectMapper.framework/ObjectMapper

    dyld: Symbol not found: _TFC12ObjectMapper6MapperCfT7contextGSqPS_10MapContext___GS0_x Referenced from: /Users/romanvolkov/Library/Developer/CoreSimulator/Devices/B7317F47-8E47-497D-93FB-F72C5B14D11C/data/Containers/Bundle/Application/D733CFF5-CE84-4773-A037-0AE9735BF0B3/Treasure Hunt.app/Frameworks/AlamofireObjectMapper.framework/AlamofireObjectMapper Expected in: /Users/romanvolkov/Library/Developer/CoreSimulator/Devices/B7317F47-8E47-497D-93FB-F72C5B14D11C/data/Containers/Bundle/Application/D733CFF5-CE84-4773-A037-0AE9735BF0B3/Treasure Hunt.app/Frameworks/ObjectMapper.framework/ObjectMapper

    Current solution: define exact version of ObjectMapper github "Hearst-DD/ObjectMapper" == 2.2.1

    opened by RomanVolkov 12
  • Fixes for Swift 3 and Xcode 8b6

    Fixes for Swift 3 and Xcode 8b6

    • Update Alamofire and ObjectMapper dependencies • ~~Fix Carthage framework references in Xcode workspace~~ • Add missing SWIFT_VERSION flags to targets • Update test cases with Alamofire API changes • Use xcodebuild for Travis due to xctool not yet supporting Xcode 8

    Updated (d9e4716) • Add Alamofire and ObjectMapper as subprojects to allow use of Carthage's --no-build flag • Update .gitignore with latest config for Xcode/Swift and to exclude macOS files such as .DS_Store

    opened by bdbergeron 9
  • I always got 'objectmapper failed to serialize response' when parsing error response

    I always got 'objectmapper failed to serialize response' when parsing error response

    import Foundation
    import ObjectMapper
    import AlamofireObjectMapper
    
    private let NameKey = "name"
    private let DescriptionKey = "description"
    private let CoverURLKey = "cover_url"
    private let MembersAmountKey = "members_count"
    private let SportNameKey = "sport_name"
    private let PagePolicyKey = "policy"
    
    class Tribe: Mappable {
        var name: String?
        var desc: String?
        var coverURL: NSURL?
        var membersAmount: Int?
        var sportName: String?
        var policy: ObjectPolicy?
        required init?(_ map: Map){
    
        }
    
        func mapping(map: Map) {
            name <- map[NameKey]
            desc <- map[DescriptionKey]
            coverURL <- (map[CoverURLKey], URLTransform())
            membersAmount <- map[MembersAmountKey]
            sportName <- map[SportNameKey]
            policy <- map[PagePolicyKey]
        }
    }
    

    this is my class and I just used simply -responseObject object method in APIClient Thank in advance.

    opened by macbaszii 9
  • Carthage deprecation warning

    Carthage deprecation warning

    32 instances of the following warning:

    warning: 'errorWithCode(_:failureReason:)' is deprecated

    This is only likely to get worse in the next Xcode/swift releases.

    Full list attached: AlamofireObjectMapper-deprecationList.txt

    opened by andre-wolfe 7
  • responseObject build error

    responseObject build error

    Hi, I got this error when build this class : Cannot convert value of type '(Response<InventoryCategory, NSError>) -> ()' to expected argument type 'Response<_, NSError> -> Void'

    import Foundation
    import Alamofire
    import ObjectMapper
    import AlamofireObjectMapper
    import RealmSwift
    
    class ProductCategorySync {
        static func get (){
            Alamofire.request(ProductCategory.ReadAll())
                .responseObject { (response: Response<InventoryCategory, NSError>)  in
                    switch response.result {
                    case .Success:
    
                        let items = response.result.value
                        if let items = items?.result {
                            let realm = try! Realm()
                            try! realm.write {
                                for item in items {
                                    realm.add(item, update: true)
                                }
                            }
                        }
                    case .Failure:
                        break
                    }
            }
        }
    }
    
    

    Here the class for Alamofire request :

    import UIKit
    import Alamofire
    
    enum ProductCategory: URLRequestConvertible {
        static let baseURLString = ApiConfig.baseURL
    
        case ReadAll()
    
        var method: Alamofire.Method {
            switch self {
            case .ReadAll:
                return .POST
            }
        }
    
        // MARK: URLRequestConvertible
    
        var URLRequest: NSMutableURLRequest {
            ApiConfig.model = ApiConfig.MODEL_PRODUCT_CATEGORY
    
            let URL:NSURL! = NSURL(string: ProductCategory.baseURLString)
            let mutableURLRequest = NSMutableURLRequest(URL: URL)
            mutableURLRequest.HTTPMethod = method.rawValue
            var param_detail : Array<Dictionary<String, AnyObject>> = Array()
    
            switch self {
            case .ReadAll():
                ApiConfig.method = ApiConfig.METHOD_SEARCH_READ
                param_detail.append(["opts" : ApiConfig.opts, "moduleDetail" : ApiConfig.moduleDetailArr])
                let parameters = ["jsonrpc": "2.0", "method": "api", "params": param_detail, "id" : 1]
                return Alamofire.ParameterEncoding.JSON.encode(mutableURLRequest, parameters: (parameters as! [String : AnyObject])).0
    
            default:
                return mutableURLRequest
            }
        }
    }
    

    The code worked fine for parsing JSON data, but got error when I added lines for mapping JSON to Realm.
    Thank you and appreciate for any help ...

    opened by martinfanio 7
  • Support for mapping onto existing objects

    Support for mapping onto existing objects

    I use ObjectMapper with Realm to have a persistant storage and to support an offline mode.

    I realized that ObjectMapper recreates existing objects instead of updating them. I suppose it happens in this method of my object:

        required convenience init?(_ map: Map) {
            self.init()
        }
    

    triggered from Mapper

        /// Maps a JSON dictionary to an object that conforms to Mappable
        public func map(JSONDictionary: [String : AnyObject]) -> N? {
            let map = Map(mappingType: .FromJSON, JSONDictionary: JSONDictionary)
    
            // check if N is of type MappableCluster
            if let klass = N.self as? MappableCluster.Type {
                if var object = klass.objectForMapping(map) as? N {
                    object.mapping(map)
                    return object
                }
            }
    
            if var object = N(map) {
                object.mapping(map)
                return object
            }
            return nil
        }
    

    Is there something I have to do? My problem is that my objects has other properties that do not get loaded from the network and will be changed by the user manually.

    enhancement 
    opened by ogezue 7
  • Building for iphonesimulator

    Building for iphonesimulator

    when installing via Carthage building for iphonesimulator fails if signature is not present (no iPhone developer account) Base ObjectMapper library builds fine for iphonesimulator target

    opened by AAverin 7
  • it's still working ????? i am working on this but always show some error i don't no why

    it's still working ????? i am working on this but always show some error i don't no why

    func getUsers() { let URLSTring = "https://jsonplaceholder.typicode.com/posts" AF.request(URLSTring).responseJSON { response in if let JSON = response.data { let str = String(decoding: JSON, as: UTF8.self) //print(str)

            let result = Mapper<ArrayResponse<ResponseModel>>().map(JSONString: str)
            
            
            //self.userlist = Mapper<ResponseModel>().mapArray(JSONString: String(str))
            let responseModel = Mapper<ResponseModel>().mapArray(JSONString: "\(String(describing: response.data))")
            print(responseModel)
            
            
            
            
            //let JSONString = Mapper().toJSONString(responseModel, prettyPrint: true)
            
            // Convert JSON String to Model
            //let responseModel = Mapper<ResponseModel>().map(JSONString: str)
            
            // Create JSON String from Model
            
            
            //let JSONString = Mapper<ResponseModel>().map(JSONString: str)
            
            
            
            
            //let responseModel = Mapper<ResponseModel>().mapArray(JSONString: str)
            
            
            
            
        }
        
        
        //let users = Mapper<ResponseModel>().mapArray(JSONObject: data)
        
        
        
    }
    

    }

    opened by exploitcrew 0
  • compile error

    compile error

    Alamofire verison is (pod info): Installing Alamofire 5.0.5 (was 5.4.1) AlamofireObjectMapper version is (pod info): Installing AlamofireObjectMapper (6.0.0)

    image

    Generic type 'DataResponse' specialized with too few type parameters (got 1, but expected 2)

    opened by coder-free 1
  • Memcpy Function

    Memcpy Function

    A security scan ran by a third party that we coordinate with picked up a trace of the Memcpy function used within the AlamofireObjecMapper pod v6.2.0.

    Is there any known use of this function within a transitive dependency? I did not find it in a code search.

    opened by SwiftDev2020 0
Releases(6.3.0)
Owner
Tristan Himmelman
Tristan Himmelman
ObjectMapper is a framework written in Swift that makes it easy for you to convert your model objects to and from JSON.

ObjectMapper is a framework written in Swift that makes it easy for you to convert your model objects (classes and structs) to and from J

Tristan Himmelman 9k Jan 2, 2023
JSONHelper - ✌ Convert anything into anything in one operation; JSON data into class instances, hex strings into UIColor/NSColor, y/n strings to booleans, arrays and dictionaries of these; anything you can make sense of!

JSONHelper Convert anything into anything in one operation; hex strings into UIColor/NSColor, JSON strings into class instances, y/n strings to boolea

Baris Sencan 788 Jul 19, 2022
HandyJSON is a framework written in Swift which to make converting model objects to and from JSON easy on iOS.

HandyJSON To deal with crash on iOS 14 beta4 please try version 5.0.3-beta HandyJSON is a framework written in Swift which to make converting model ob

Alibaba 4.1k Dec 29, 2022
JSONExport is a desktop application for Mac OS X which enables you to export JSON objects as model classes with their associated constructors, utility methods, setters and getters in your favorite language.

JSONExport JSONExport is a desktop application for Mac OS X written in Swift. Using JSONExport you will be able to: Convert any valid JSON object to a

Ahmed Ali 4.7k Dec 30, 2022
Encode and decode deeply-nested data into flat Swift objects

DeepCodable: Encode and decode deeply-nested data into flat Swift objects Have you ever gotten a response from an API that looked like this and wanted

Mike Lewis 91 Dec 26, 2022
Reflection based (Dictionary, CKRecord, NSManagedObject, Realm, JSON and XML) object mapping with extensions for Alamofire and Moya with RxSwift or ReactiveSwift

EVReflection General information At this moment the master branch is tested with Swift 4.2 and 5.0 beta If you want to continue using EVReflection in

Edwin Vermeer 964 Dec 14, 2022
JSONJoy - Convert JSON to Swift objects

JSONJoy Convert JSON to Swift objects. The Objective-C counterpart can be found here: JSONJoy. Parsing JSON in Swift has be likened to a trip through

Dalton 350 Oct 15, 2022
Magical Data Modeling Framework for JSON - allows rapid creation of smart data models. You can use it in your iOS, macOS, watchOS and tvOS apps.

JSONModel - Magical Data Modeling Framework for JSON JSONModel allows rapid creation of smart data models. You can use it in your iOS, macOS, watchOS

JSONModel 6.9k Dec 8, 2022
Magical Data Modeling Framework for JSON - allows rapid creation of smart data models. You can use it in your iOS, macOS, watchOS and tvOS apps.

JSONModel - Magical Data Modeling Framework for JSON JSONModel allows rapid creation of smart data models. You can use it in your iOS, macOS, watchOS

JSONModel 6.8k Nov 19, 2021
JSEN (JSON Swift Enum Notation) is a lightweight enum representation of a JSON, written in Swift.

JSEN /ˈdʒeɪsən/ JAY-sən JSEN (JSON Swift Enum Notation) is a lightweight enum representation of a JSON, written in Swift. A JSON, as defined in the EC

Roger Oba 8 Nov 22, 2022
Swift-json - High-performance json parsing in swift

json 0.1.4 swift-json is a pure-Swift JSON parsing library designed for high-per

kelvin 43 Dec 15, 2022
Codable code is a Swift Package that allows you to convert JSON Strings into Swift structs

Codable code is a Swift Package that allows you to convert JSON Strings into Swift structs.

Julio Cesar Guzman Villanueva 2 Oct 6, 2022
JSON-Practice - JSON Practice With Swift

JSON Practice Vista creada con: Programmatic + AutoLayout Breve explicación de l

Vanesa Giselle Korbenfeld 0 Oct 29, 2021
Ss-json - High-performance json parsing in swift

json 0.1.1 swift-json is a pure-Swift JSON parsing library designed for high-per

kelvin 43 Dec 15, 2022
Swift parser for JSON Feed — a new format similar to RSS and Atom but in JSON.

JSONFeed Swift parser for JSON Feed — a new format similar to RSS and Atom but in JSON. For more information about this new feed format visit: https:/

Toto Tvalavadze 31 Nov 22, 2021
JSONNeverDie - Auto reflection tool from JSON to Model, user friendly JSON encoder / decoder, aims to never die

JSONNeverDie is an auto reflection tool from JSON to Model, a user friendly JSON encoder / decoder, aims to never die. Also JSONNeverDie is a very important part of Pitaya.

John Lui 454 Oct 30, 2022
Developed with use Swift language. As a third party library used SDWebImage. JSON parsing using URLSession with TMDB API. This app provide by the Core Data structure.

Capstone Project ?? About Developed with use Swift language. As a third party library used SDWebImage. JSON parsing using URLSession with TMDB API. Ad

Ensar Batuhan Unverdi 9 Aug 22, 2022
A tiny Safari Web Extension for presenting highlighted JSON files

A tiny Safari Web Extension for presenting highlighted JSON files

Lex Tang 31 Sep 9, 2022
Coding Challenge using NYC JSON data

Coding Challenge using NYC JSON data This was my submission to JPMorgan's code challenge prior to an interview. It represents my solution to asyncrono

null 0 Dec 9, 2021