An Alamofire extension which converts JSON response data into swift objects using EVReflection

Overview

AlamofireJsonToObjects

🚨 This is now a subspec of EVReflection and the code is maintained there. 🚨

You can install it as a subspec like this:

use_frameworks!
pod "EVReflection/Alamofire"

Besideds this subspec there are also subspecs for: XML, AlamofireXML, Moya, MoyaRxSwift and MoyaReflectiveSwift

Issues Documentation Stars Awesome

Version Language Platform Support License

Git Twitter LinkedIn Website eMail

If you have a question and don't want to create an issue, then we can Join the chat at https://gitter.im/evermeer/EVReflection (EVReflection is the base of AlamofireJsonToObjects)

With AlamofireJsonToObjects it's extremely easy to fetch a json feed and parse it into objects. No property mapping is required. Reflection is used to put the values in the corresponding properties.

AlamofireJsonToObjects is based on the folowing libraries:

  • Alamofire is an elegant HTTP Networking library in Swift
  • EVReflection is used to parse the JSON result to your objects

This library was greatly inspired by AlamofireObjectMapper

At this moment the master branch is for Swift3. If you want to continue using Swift 2.2 (or 2.3) then switch to the Swift2.2 branch. Run the tests to see AlamofireJsonToObjects in action.

Using AlamofireJsonToObjects in your own App

'AlamofireJsonToObjects' is available through the dependency manager CocoaPods.

You can just add AlamofireJsonToObjects to your workspace by adding the folowing 2 lines to your Podfile:

use_frameworks!
pod "AlamofireJsonToObjects"

you also have to add an import at the top of your swift file like this:

import AlamofireJsonToObjects

Sample code

class WeatherResponse: EVNetworkingObject {
    var location: String?
    var three_day_forecast: [Forecast] = [Forecast]()
}

class Forecast: EVNetworkingObject {
    var day: String?
    var temperature: NSNumber?
    var conditions: String?
}

class AlamofireJsonToObjectsTests: XCTestCase { 
    func testResponseObject() {
        let URL = "https://raw.githubusercontent.com/evermeer/AlamofireJsonToObjects/master/AlamofireJsonToObjectsTests/sample_json"
        Alamofire.request(URL)
            .responseObject { (response: DataResponse<WeatherResponse>) in
            if let result = response.result.value {
                // That was all... You now have a WeatherResponse object with data
           }
        }
        waitForExpectationsWithTimeout(10, handler: { (error: NSError!) -> Void in
            XCTAssertNil(error, "\(error)")
        })
    }
}

The code above will pass the folowing json to the objects:

{  "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 
      }
   ]
}

Advanced object mapping

AlamofireJsonToObjects is based on EVReflection and you can use all EVReflection features like property mapping, converters, validators and key kleanup. See EVReflection for more information.

Handling HTTP status >= 300

When a network call returns a HTTP error status (300 or highter) then this will be added to the evReflectionStatuses as a custom error. see the unit test testErrorResponse as a sample. In order to make this work, you do have to set EVNetworkingObject as your bass class and not EVObject. You then also have to be aware that if you override the initValidation or the propertyMapping function, that you also have to call the super for that function.

License

AlamofireJsonToObjects is available under the MIT 3 license. See the LICENSE file for more info.

My other libraries:

Also see my other open source iOS libraries:

  • EVReflection - Swift library with reflection functions with support for NSCoding, Printable, Hashable, Equatable and JSON
  • EVCloudKitDao - Simplified access to Apple's CloudKit
  • EVFaceTracker - Calculate the distance and angle of your device with regards to your face in order to simulate a 3D effect
  • EVURLCache - a NSURLCache subclass for handling all web requests that use NSURLReques
  • AlamofireJsonToObject - An Alamofire extension which converts JSON response data into swift objects using EVReflection
  • AlamofireXmlToObject - An Alamofire extension which converts XML response data into swift objects using EVReflection and XMLDictionary
  • AlamofireOauth2 - A swift implementation of OAuth2 using Alamofire
  • EVWordPressAPI - Swift Implementation of the WordPress (Jetpack) API using AlamofireOauth2, AlomofireJsonToObjects and EVReflection (work in progress)
  • PassportScanner - Scan the MRZ code of a passport and extract the firstname, lastname, passport number, nationality, date of birth, expiration date and personal numer.
Comments
  • Array mapping return empty array

    Array mapping return empty array

    Hi,

    I try to map an array of objects like this:

    Models

    open class ApiGenericBase: EVNetworkingObject {
        var success: NSNumber?
        var message: String?
        var status_code: String?
    }
    
    open class ApiResponse<T>: ApiGenericBase, EVGenericsKVC where T:NSObject {
        var data: T = T()
        
        public func setGenericValue(_ value: AnyObject!, forUndefinedKey key: String) {
            switch key {
            case "data":
                data = value as? T ?? T()
            default:
                print("---> setGenericValue '\(value)' forUndefinedKey '\(key)' should be handled.")
            }
        }
        
        public func getGenericType() -> NSObject {
            return T()
        }
    }
    
    public class Vehicle: EVNetworkingObject {
        var uuid: String?
        ...
    }
    
    open class List<T>: EVNetworkingObject, EVGenericsKVC where T:NSObject {
        var records: [T] = [T]()
        
        public func setGenericValue(_ value: AnyObject!, forUndefinedKey key: String) {
            records = value as? [T] ?? [T]()
        }
        
        public func getGenericType() -> NSObject {
            return [T]() as NSObject
        }
        
    }
    
    

    and I'm calling like this:

    manager.request(GetVehicleFromArgusPlateProvider, method: .get,
                            parameters: parameters,
                            encoding: URLEncoding.default,
                            headers: nil).responseObject { (response: DataResponse<ApiResponse<List<Vehicle>>>) in
                ...
            }
    

    but when I dump response I have an empty array:

    dump(response)
    
    ▿ _TtGC9xxx_v24ListCS_7Vehicle_ = {
      "records" : [
    
      ]
    } #0
      - super: AlamofireJsonToObjects.EVNetworkingObject
        ▿ super: EVReflection.EVObject
          - super: NSObject
          - evReflectionStatuses: 0 elements
      - records: 0 elements
    
    

    My JSON server response:

    {
      "data": [
        {
          "uuid": "52ec7e70-eb02-11e6-b6f3-1bb7c380e65e",
          ...
        },
        {
          "uuid": "53230b60-eb02-11e6-aee4-47e7e9e49d51",
          ...
        },
        {
          "uuid": "5366e810-eb02-11e6-93b6-91512741054a",
          ...
        },
        {
          "uuid": "53aa9cd0-eb02-11e6-a958-215ccabe8e51",
          ...
        }
      ]
    }
    

    Any idea or help please. Thanks.

    opened by aliasdoc 13
  • Incorrect arguments label in call

    Incorrect arguments label in call

    Hi there,

    I just updated my podfile to use the main branch instead of the Swift3, and now I'm facing several instances of the same error.

    "Incorrect argument label in call (have 'dictionary:', expected 'coder:')"

    This error occurs in both line 61 and 125.

    Fixed? 
    opened by Dbigshooter 12
  • Custom mapping problem

    Custom mapping problem

    Hi,

    I try to use AlamofireJsonToObjects 1.2.0 with a custom mapping.

    Alamofire.request(.GET, "http://myendpointurl/", parameters: nil).responseArray { (response: Result<[Site]>) -> Void in NSLog("sites count: %d", response.value!.count) }

    class Site: EVObject {

    /*var id: NSNumber?
    var openDataId: NSString?
    var title: NSString?
    var nature: NSString?
    var latitude: NSNumber?
    var longitude: NSNumber?
    var startDate: NSDate?
    var endDate: NSDate?
    var carNuisanceLevel: NSNumber?
    var carNuisanceDescription: NSString?
    var bikeNuisanceLevel: NSNumber?
    var bikeNuisanceDescription: NSString?
    var pedestrianNuisanceLevel: NSNumber?
    var pedestrianNuisanceDescription: NSString?
    var contactUrl: NSString?*/
    
    var id: Int?
    var openDataId: String?
    var title: String?
    var nature: String?
    var latitude: Double?
    var longitude: Double?
    var startDate: NSDate?
    var endDate: NSDate?
    var carNuisanceLevel: Double?
    var carNuisanceDescription: String?
    var bikeNuisanceLevel: Double?
    var bikeNuisanceDescription: String?
    var pedestrianNuisanceLevel: Double?
    var pedestrianNuisanceDescription: String?
    var contactUrl:String?
    
    override func propertyMapping() -> [(String?, String?)] {
        return [("openDataId","record_id"), ("startDate","start_date"), ("endDate","end_date"), ("carNuisanceLevel","nuisance_car"), ("carNuisanceDescription","nuisance_car_description"), ("bikeNuisanceLevel","nuisance_bike"), ("bikeNuisanceDescription","nuisance_bike_description"), ("pedestrianNuisanceLevel","nuisance_pedestrian"), ("pedestrianNuisanceDescription","nuisance_pedestrian_description"), ("contactUrl","myfeelback_url")]
    }
    

    }

    In this configuration (Swift types use Int, String), I have this error on each field binding try

    WARNING: The class 'Site' is not key value coding-compliant for the key 'carNuisanceLevel' There is no support for optional type, array of optionals or enum properties. As a workaround you can implement the function 'setValue forUndefinedKey' for this. See the unit tests for more information

    When I use other configuration (ObjC types use NSNumber, NSString), I don't have warning message anymore but a breakpoint (I suppose on each field binding try) in init method assemblor code of my relative class

    0x9c6e0 <+0>:   pushl  %ebp
    0x9c6e1 <+1>:   movl   %esp, %ebp
    0x9c6e3 <+3>:   pushl  %esi
    0x9c6e4 <+4>:   subl   $0x84, %esp
    0x9c6ea <+10>:  calll  0x9c6ef                   ; <+15> at Site.swift:12
    0x9c6ef <+15>:  popl   %eax
    0x9c6f0 <+16>:  movl   0x8(%ebp), %ecx
    0x9c6f3 <+19>:  movl   %ecx, -0x8(%ebp)
    

    -> 0x9c6f6 <+22>: movl $0x0, -0x10(%ebp)

    What am I doing wrong?

    Other question, for example for startDate, I get a string in UTC format, is AlamofireJsonToObjects able to manage conversion to NSDate natively or do I add some specific process ?

    Thanks in advance.

    bug Fixed? 
    opened by Narayane 12
  • Is not key value coding-compliant for the key __response_statusCode?

    Is not key value coding-compliant for the key __response_statusCode?

    Just updated EVReflection and this lib, and all my classes says this, what is that?

    
    WARNING: The class 'ClassName' is not key value coding-compliant for the key '__response_statusCode'
     There is no support for optional type, array of optionals or enum properties.
    As a workaround you can implement the function 'setValue forUndefinedKey' for this. See the unit tests for more information
    
    question 
    opened by Dbigshooter 10
  • Could not create an instance for type

    Could not create an instance for type "Forecast"

    Hi. I used your library my old project and it was very helpful for me. Thank you.

    Now I'm using your library again. But I faced a problem this time. I suspected my model class and because of that I used your example for the test.

    I got this error "Could not create an instance for type Forecast".

    now my versions :
    xcode : 7.3.1 pod version : 1.0.1 imported some pods : Alamofire (3.5.0) AlamofireJsonToObjects (1.6.0) EVReflection (2.46.0)

    I think this is about versions but I dont know. Do you have any idea about that? Thanks.

    Fixed? 
    opened by BeBetter7 10
  • Migration help needed

    Migration help needed

    Hi there,

    I've trying to use the Swift 3 branch, and adopt some thing to Alamofire 4. I get this warning, and I can't quite understand it? This is my code:

    `Alamofire.request(apiURL + "users", headers: headers).responseObject { (response: Result<User>) in
                    if let user = response.value {
                        completionHandler(user, nil);
                    } else {
                        completionHandler(nil, response.error as NSError?);
                    }
                }
        }
    `
    

    My previous code looked like this:

    Alamofire.request(.GET, apiURL + "users", headers: headers).responseObject { (response: Result<User, Error>) in
                    if let user = response.value {
                        print(user)
                        completionHandler(user, nil);
                    } else {
                        completionHandler(nil, response.error);
                    }
                }
        }
    

    However this gives me this error: Generic type Result specialized with too many type parameters (got 2, but expected 1)

    I also seem to get another, for me, not understandable error in this piece of code

    
    func getPackage(completionHandler: @escaping (Package?, NSError?) -> ()){
    
            Alamofire.request(URL + "package", method: .get, headers: headers())
                .responseObject { (response: Result<Package>) in
                    if let userPackage = response.value {
                        print(userPackage);
    
                        completionHandler(userPackage, nil);
                    } else {
                        completionHandler(nil, response.error);
                    }
            }
        }
    

    This gives me the following error: Cannot convert value of type '(Result<Package>) -> ()' to expected argument type '(URLRequest?, HTTPURLResponse?, Result<_>) -> Void'

    Fixed? 
    opened by Dbigshooter 9
  • Build error happened within carthage

    Build error happened within carthage

    Thank you for your works,

    I tried to get and build your project within carthage, but error happened. It seems that there is no Info.plist in master branch or so. Please fix it.


    The following build commands failed: ProcessInfoPlistFile /Users/XXX/Library/Developer/Xcode/DerivedData/AlamofireJsonToObjects-fjegefcudpictvaahsrfpcutkyjr/Build/Products/Release-iphoneos/AlamofireJsonToObjects.framework/Info.plist AlamofireJsonToObjects/Info.plist (1 failure)

    help wanted 
    opened by tk0927 9
  • Swift Compiler Error for Xcode 8.3

    Swift Compiler Error for Xcode 8.3

    Please help to solve the problem Through a pod installed AlamofireJsonToObjects (2.4.1) When compiling, I see 2 errors: AlamofireJsonToObjects.swift: 68: 72: 'NSDictionary' is not convertible to '[AnyHashable: Any]'; Did you mean to use 'as!' To force downcast? AlamofireJsonToObjects.swift: 130: 98: 'NSDictionary' is not convertible to '[AnyHashable: Any]'; Did you mean to use 'as!' To force downcast?

    Xcode Version 8.3 (8E162)

    In their Xcode 8.2.1 everything worked fine

    question Fixed? 
    opened by KarpenkoAV 7
  • Custom parser

    Custom parser

    Hi, i have the following class:

    class EventModel : MyModel {
        var name : String?
        var dateStart : String?
        var dateEnd : String?
        var allDay : Int = 0
        var objectFull : NSObject?
        var objectType : String?
    
     override func setValue(value: AnyObject!, forUndefinedKey key: String) {
            switch key {
            case "objectFull":
                if (objectType == "task") {
                    objectFull = (value as? TaskModel)!
                }
                else if (objectType == "sale") {
                    objectFull = (value as? SaleModel)!
                }
                break
            default:
                print("---> setValue '\(value)' for key '\(key)' should be handled.")
            }
        } 
    
    
    }
    

    I know i could solve this with generics, but i receive an array of events from my server, so i cant instantiate it with generics. This approach (NSObject) isnt working. May you help me please? Thanks in advance.

    question 
    opened by sagits 7
  • Compilation errors in Xcode 7.0 (7A220)

    Compilation errors in Xcode 7.0 (7A220)

    Hi,

    still the same error when I try to use AlamofireJsonToObjects 1.2.0 with Alamofire 3.0.0-beta.3 (now public enum Result< Value, Error: ErrorType> in Result.swift) from Cocoapods

    alamofire

    Regards.

    bug Fixed? 
    opened by Narayane 7
  • Generic list parse

    Generic list parse

    Hi, im trying to parse a generic list, i think that there is no support for it for now, but is there any way i can use setValue forUndefinedKey function to pass a class type and be able to parse the list? Maybe is there another way? Thanks in advance.

    What i have now:

    class JsonMessage : EVObject {
      var _meta : MetaModel
    
      override
      init() {
          _meta = MetaModel()
      }
    } 
    
    
    class JsonMessageList<T> : JsonMessage {
      var records = [T]()
    
      override
      init() {
    
      }
    
    }
    
       Alamofire.request(.GET, URL, headers: headers)
                .responseObject { (response: JsonMessageList<ProductModel>?, error: NSError?) in
                   if (error == nil && response != nil) {
                       for product in response!.records {
                           println("id: " + product.name!);
                       }
                    }
                    else {
                        println("Error on request");
                    }
                }
    

    Im an Android Developer, and i have created a lib that does this on android. I pass a Model.class (Class) to a ListHelperModel and use this list as a type for gson (a google library that parse json to objects) to parse the list.

    Take a look if you want:

    ListHelperModel

    Check getList() method

    Unfortunelly im very new to swift/ios, so i just dont know how and if i can reproduce this.

    opened by sagits 6
  • Compiling for iOS 8.0, but module 'Alamofire' has a minimum deployment target of iOS 10.0

    Compiling for iOS 8.0, but module 'Alamofire' has a minimum deployment target of iOS 10.0

    Both AlamofireJsonToObjects and AlamofireXmlToObjects are moved into EVReflection. You can use these by puting this in your podfile:

    pod 'EVReflection/Alamofire'

    There are now also sub specs for Moya, RxSwift and ReactiveSwift

    opened by pramodshukla1011 0
Owner
Edwin Vermeer
Edwin Vermeer
Elegantly connect to a JSON api. (Alamofire + Promises + JSON Parsing)

⚠ Important Notice: Farewell ws... hello Networking ! Networking is the next generation of the ws project. Think of it as ws 2.0 built for iOS13. It u

Fresh 351 Oct 2, 2022
TupleResult - A micro library that easily converts tuple result into Swift.Result

TupleResult A micro library that easily converts c-style tuple result into Swift

Ernest SeongHo Hong 0 Jan 29, 2022
Lazily deserialize JSON into strongly typed Swift objects

LazyObject Lazily deserialize JSON into strongly typed Swift objects, with a few getter style options. Is your app using it? Let me know! Installation

rob phillips 11 Nov 16, 2022
NSURLSession network abstraction layer, using Codable and Decodable for response and Encodable for request. ⚙️🚀

SONetworking NSURLSession network abstraction layer, using Codable and Decodable for response and Encodable for request. Project Folder and File Struc

Ahmad AlSofi 4 Jan 28, 2022
Type-safe networking abstraction layer that associates request type with response type.

APIKit APIKit is a type-safe networking abstraction layer that associates request type with response type. // SearchRepositoriesRequest conforms to Re

Yosuke Ishikawa 1.9k Dec 30, 2022
Bamboots - Extension 4 Alamofire

Bamboots is a network request framework based on Alamofire , aiming at making network request easier for business development. Protocols Features Requ

mmoaay 442 Dec 22, 2022
Alamofire extension for serialize NSData to SwiftyJSON

Alamofire-SwiftyJSON An extension to make serializing Alamofire's response with SwiftyJSON easily. ⚠️ To use with Swift 3.x please ensure you are usin

SwiftyJSON 1.4k Dec 22, 2022
Alamofire Network Layer written in swift 5 using the protocol oriented, combine, UIKit, MVVM.

CoreAPI-iOS This project Contains Alamofire Network layer Based on Protocol Oriented Concept and Combine Framework. It is created with UIKit, Alamofir

Mehran Kamalifard 27 Nov 11, 2022
Advanced Networking Layer Using Alamofire with Unit Testing

Advanced Networking Layer Using Alamofire with Unit Testing

Ali Fayed 8 May 23, 2022
A network extension app to block a user input URI. Meant as a network extension filter proof of concept.

URIBlockNE A network extension app to block a user input URI. Meant as a network extension filter proof of concept. This is just a research effort to

Charles Edge 5 Oct 17, 2022
A frida tool that capture GET/POST HTTP requests of iOS Swift library 'Alamofire' and disable SSL Pinning.

FridaHookSwiftAlamofire A frida tool that capture GET/POST HTTP requests of iOS Swift library 'Alamofire' and disable SSL Pinning. 中文文档及过程 Features Ca

neilwu 69 Dec 16, 2022
Lightweight network abstraction layer, written on top of Alamofire

TRON is a lightweight network abstraction layer, built on top of Alamofire. It can be used to dramatically simplify interacting with RESTful JSON web-

MLSDev 528 Dec 26, 2022
Restofire is a protocol oriented networking client for Alamofire

Restofire is a protocol oriented networking client for Alamofire. Features Requirements Installation Usage License Features Global Configuration for h

Restofire 381 Sep 29, 2022
A progressive download manager for Alamofire

ALDownloadManager A progressive download manager for Alamofire (Alamofire下载器) The default support breakpoint continues. Sequential Download(顺序下载 ) Dow

null 48 May 1, 2022
Alamofire network layer

NVNetworkRequest Alamofire network layer Installation Add this to your Package dependencies: dependencies: [ .package(url: "https://github.com/vin

Vinh Nguyen 0 Nov 19, 2021
Simple REST Client based on RxSwift and Alamofire.

RxRestClient Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 10.0+ tvOS 10.

STDev 16 Nov 19, 2022
EasyImplementationAlamoFire - An iOS project to demonstrate the usage of Alamofire in an efficient and organised way.

EasyImplementationAlamoFire Tutorial to demonstrate an efficient way of handling the APIs structure for your iOS Applications. Prerequisites Swift 5 X

null 0 Jan 3, 2022
Simple REST Client based on RxSwift and Alamofire.

RxRestClient Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 10.0+ tvOS 10.

STDev 16 Nov 19, 2022
To practice URLSession to fetch json data from open weather API

⛅️ weatherApp-iOS-practice ?? 기능 상세 도시 이름을 입력하면 현재 날씨 정보를 가져와 화면에 표시되게 만들어야 합니다

Jacob Ko 0 Dec 18, 2021