Data Mapping library for Objective C

Last update: Jul 3, 2022

Data Mapping library for Objective C

Build Status Version

OCMapper is a data mapping library for Objective C that converts NSDictionary to NSObject. My inspiration behind writing OCMapper was to achieve two things:

  • Simplify/Automate Data retrieval through web services
  • Avoid adding parsing logic to model objects (I'm a big fan of separation of responsibilities!!!)

Swift Support

OCMapper takes advantage of the objective c runtime API, and will only work with classes that inherit from NSObject.

** Don't use OCMApper with classes written in swift **

Alamofire Extension

https://github.com/Alamofire/Alamofire

public extension Request {
    
    public func responseObjects<T: NSObject> (type: T.Type, completion: (NSURLRequest, NSURLResponse?, [T]?, NSError?)->()) -> Self {
        
        return response(serializer: Request.JSONResponseSerializer(options: .AllowFragments)) { request, response, json, error in
            
            if let error = error {
                completion(request, response, nil, error)
            }
            else {
                let objects = ObjectMapper.sharedInstance().objectFromSource(json, toInstanceOfClass: type) as? [T]
                completion(request, response, objects, nil)
            }
        }
    }
    
    public func responseObject<T: NSObject> (type: T.Type, completion: (NSURLRequest, NSURLResponse?, T?, NSError?)->()) -> Self {
        
        return response(serializer: Request.JSONResponseSerializer(options: .AllowFragments)) { request, response, json, error in
            
            if let error = error {
                completion(request, response, nil, error)
            }
            else {
                let object = ObjectMapper.sharedInstance().objectFromSource(json, toInstanceOfClass: type) as? T
                completion(request, response, object, nil)
            }
        }
    }
    
}

Extension Usage

let request = Manager.sharedInstance.request(requestWithPath("example.com/users", method: .GET, parameters: nil))
        
request.responseObjects(User.self) { request, response, users, error in
    // users is an array of User objects
}


let request = Manager.sharedInstance.request(requestWithPath("example.com/users/5", method: .GET, parameters: nil))
        
request.responseObject(User.self) { request, response, user, error in
    // user is an instance of User
}

Features:

  • Supports array mapping
  • Supports tree structure mapping
  • Auto maps everything based on key/values
  • You can write mapping for non-matching dictionary/property keys
  • Override portion of mapping using transformers
  • Supports Core Data (NSManagedObjects mapping)
  • Does not require subclassing or adding any extra code to your models
  • Auto date conversion, and configurable DateFormatters
  • Auto underscore to camel case mapping

Examples

@interface User
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSNumber *age;
@property (nonatomic, strong) NSDate *dateOfBirth;
@property (nonatomic, strong) NSDate *accountCreationDate;
@property (nonatomic, strong) Address *address;
@property (nonatomic, strong) NSMutableArray *posts;
@end

@interface Address
@property (nonatomic, strong) NSString *city;
@property (nonatomic, strong) NSString *country;
@end

@interface Post
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) User *author;
@property (nonatomic, strong) NSDate *datePosted;
@end

Simple Automatic Mapping

{
   "firstName"   : "Aryan",
   "lastName"    : "Ghassemi",
   "age"         : 26,
   "dateOfBirth" : "01/01/2013"
}

User *user = [User objectFromDictionary:aDictionary];

Nested Automatic Mapping

In this case everything is mapped automaticly because all key/values are similar. "address" will automatically convert to "Address" Object. "posts" will automatically convert to an array of "Post" objects. The library detect the plural nouns, and finds the right class to be used for mapping

{
   "firstName"   : "Aryan",
   "lastName"    : "Ghassemi",
   "age"         : 26,
   "dateOfBirth" : "01/01/2013",
   "address"     : { 
                        "city" : "San Diego", 
                        "country" : "US"  
                   },
   "posts"       : [
                         {
                             "title" : "Post 1 title",
                             "datePosted : "04/15/2013",
                         },
                         {
                             "title" : "Post 2 title",
                             "datePosted : "04/12/2013",
                         }
                   ]
}

User *user = [User objectFromDictionary:aDictionary];

Complex Mapping

Here is a more complex scenario where the dictionary keys do not match the model property names. The key for date of birth changes from "dateOfBirth" to "dob", and the key for "author" is named "from"

{
   "firstName"   : "Aryan",
   "lastName"    : "Ghassemi",
   "age"         : 26,
   "dob" : "01/01/2013",
   "address"     : { 
                        "city" : "San Diego", 
                        "country" : "US"  
                   },
   "posts"       : [
                         {
                             "title" : "Post 1 title",
                             "datePosted : "04/15/2013",
                             "from" : { 
                                             "firstName" : "Chuck", 
                                             "lastName" : "Norris" 
                                        }
                         },
                         {
                             "title" : "Post 2 title",
                             "datePosted : "04/12/2013",
                             "form" : { 
                                             "firstName" : "Chuck", 
                                             "lastName" : "Norris" 
                                        }
                         }
                   ]
}

// Handle different key for dateOfBirth
[inCodeMappingProvider mapFromDictionaryKey:@"dob" toPropertyKey:@"dateOfBirth" forClass:[User class]];

// Handle mapping of "form" to "auther" object
// Mapping would NOT be required if dictionary key and property were both named the same
[inCodeMappingProvider mapFromDictionaryKey:@"from" toPropertyKey:@"author" withObjectType:[User class] forClass:[Comment class]];

User *user = [User objectFromDictionary:aDictionary];

Mapping Array on root level

[
   {
      "firstName" : "Aryan",
      ... rest of JSON data ...
   },
   {
      "firstName" : "Chuck",
      ... rest of JSON data ...
   },
]

NSArray *users = [User objectFromDictionary:aDictionary];

Flat Data to Complex Object

This is no longer enabled on default in order to improve performance. There is a property named normalizeDictionary in ObjectMapper class that allows you to turn this feature on if needed.

{
      "firstName"           : "Aryan",
      "city"                : "San Diego"
      "country"             : "United States"
}

   // We map city and country to a nested object called 'address' inside the 'user' object
	[self.mappingProvider mapFromDictionaryKey:@"city" toPropertyKey:@"address.city" forClass:[User class]];
	[self.mappingProvider mapFromDictionaryKey:@"country" toPropertyKey:@"address.country" forClass:[User class]];
	
	User *user = [User objectFromDictionary:aDictionary];
      NSLog(@"FirstName:%@   City:%@  Country:%@", 
      user.firstName,
      user.address.city, 
      user.address.coutnry);

Date Conversion

Automapper has a property named defaultDateFormatter, and when the property is set it'll use this NSDateFormatter for date conversions on all NSDate properties. It's recomended to set the defaultDateFormatter for best performance. Note that custom dateFormatters have priority over defaultDateFormatter

[inCodeMappingProvider setDefaultDateFormatter:aDefaultDateFormatter];

ObjectMapper uses a list of common NSDateFormatters to convert string to NSDate. Here is a list of common dateFormats supported out of the box

"yyyy-MM-dd"
"MM/dd/yyyy"
"yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ"
"yyyy-MM-dd HH:mm:ss"
"MM/dd/yyyy HH:mm:ss aaa"
"yyyy-MM-dd'T'HH:mm:ss'Z'"

You can also have custom NSDateFormatter specific to classes & properties

NOTE: Setting DateFormatter is not required as long as all date formats are standard or if the defaultDateFormatter knows how to parse the dates. The code below is just to demonstrate that it's possible to set custom dateformatters but it is not required due to use of standard date formats in this example.

{
      "firstName"           : "Aryan",
      "accountCreationDate" : "01/21/2005"
      "dateOfBirth"         : "2005-21-01"
}

// Custom formatter for account creation date
NSDateFormatter *accountCreationFormatter = [[NSDateFormatter alloc] init];
[accountCreationFormatter setDateFormat:@"MM/dd/yyyy"];
[inCodeMappingProvider setDateFormatter:accountCreationFormatter forProperty:@"accountCreationDate" andClass:[User class]];

// Custom formatter for date of birth
NSDateFormatter *dateOfBirthFormatter = [[NSDateFormatter alloc] init];
[dateOfBirthFormatter setDateFormat:@"yyyy-dd-MM"];
[inCodeMappingProvider setDateFormatter:dateOfBirthFormatter forProperty:@"dateOfBirth" andClass:[User class]];

User *user = [User objectFromDictionary:aDictionary];

Data Transformers

Data transformers allow you to capture a certain part of mapping and manually map it. It alsso opens room for polymorphic mapping.

Transform a field to another

{
   "firstName" : "Aryan",
   "country" : "United States"
}

@implementation User
@property(nonatomic, strong) NSString *firstName;
@property(nonatomic, strong) Country *country;
@end

[mappingProvider mapFromDictionaryKey:@"country" toPropertyKey:@"country" forClass:[User class] withTransformer:^id(id currentNode, id parentNode) {
    return [[Country alloc] initWithName:currentNode];
}];

Using transformer for polymorphic relationships

{
   "firstName" : "Aryan",
   "vehicleType" : "car",
   "vehicle" : { /*specific product Info*/ },
}

@implementation User
@property(nonatomic, strong) NSString *firstName;
@property(nonatomic, strong) Vehicle *vehicle;
@end

[mappingProvider mapFromDictionaryKey:@"vehicle" toPropertyKey:@"vehicle" forClass:[User class] withTransformer:^id(id currentNode, id parentNode) {
    NSString *productType = [parentNode objectForKey:@"vehicleType"];
    Vehicle *vehicle;
    
    if ([productType isEqual:@"car"])
    {
    	vehicle = [Car objectFromDictionary:currentNode];
    }
    else if ([productType isEqual:@"bike"])
    {
    	vehicle = [Bike objectFromDictionary:currentNode];
    }
    
    
    return vehicle;
}];

// Or event better

[mappingProvider mapFromDictionaryKey:@"vehicle" toPropertyKey:@"vehicle" forClass:[User class] withTransformer:^id(id currentNode, id parentNode) {

    NSString *productType = [parentNode objectForKey:@"vehicleType"];
    Class class = NSClassFromString(productType.capitalizedString);
    return [class objectFromDictionary:currentNode];
}];

Other posibilities with the transformer

{
   "firstName" : "Aryan",
   "image" : "BASE64_ENCODED_STRING"
}

@implementation User
@property(nonatomic, strong) NSString *firstName;
@property(nonatomic, strong) UIImage *image;
@end

[mappingProvider mapFromDictionaryKey:@"image" toPropertyKey:@"image" forClass:[User class] withTransformer:^id(id currentNode, id parentNode) {

    return [UIImage imageFromBase64String:currentNode];
}];

Inverse mapping

Inverse mapping referrs to mapping of an object to a dictionary. This is very similar to a standard dictionary to property mapping. The following methods can be used in order to setup custom mapping for object to dictionary mapping.

- (void)mapFromPropertyKey:(NSString *)propertyKey toDictionaryKey:(NSString *)dictionaryKey forClass:(Class)class;
- (void)mapFromPropertyKey:(NSString *)propertyKey toDictionaryKey:(NSString *)dictionaryKey forClass:(Class)class withTransformer:(MappingTransformer)transformer;
- (void)setDateFormatter:(NSDateFormatter *)dateFormatter forDictionary:(NSString *)property andClass:(Class)class;

InCodeMappingProvider class has a property named automaticallyGenerateInverseMapping. This property is set to true on default, which means whenever a dictionary-to-property mapping is set, an inverse-mapping is automatically generated, and therefore there is no need to manually write mapping for object-to-dictionary mapping. The only exception is that mapping dictionary-to-property with data-transformers cannot be automatically inversed.

Date formatters are also created for an inverse relationship when automaticallyGenerateInverseMapping is set to true.

Core Data Support

In order to use core data you can add a ManagedObjectInstanceProvider to ObjectMapper

ManagedObjectInstanceProvider *instanceProvider = [[ManagedObjectInstanceProvider alloc] initWithManagedObjectContext:moc];
	
[[ObjectMapper sharedInstance] addInstanceProvider:instanceProvider];

On default Object mapper creates a new instance of NSManagedObject on every mapping. In order to update an existing record you could provide unique keys for a given class and ObjectMapper would automatically update the existing record.

[managedObjectInstanceProvider setUniqueKeys:@[@"userId"] forClass:[User class] withUpsertMode:UpsertModePurgeExistingObject];

When assigning keys for classes OCMApper also requires an enum describes how ObjectMapper should upsert existing records.

  • UpsertModeUpdateExistingObject: This option creates a new temporary instance of managed object, and then based on the given keys it attempts to find an existing record. If it finds ONE record it updates all properties of the existing managed object and finally removes the temporary object. When using this upsert mode, delete does not get called on any of the related managed objects, and therefore records remain in memory. For instance if the user's address has changed from A to B address would be updated properly, but both records would remain in core data.

  • UpsertModePurgeExistingObject: This option creates a new instance of managed object, and then based on the given keys it attempts to find an existing record. If it finds ONE record it calls delete on that record, and then inserts the newly created object into context. Using this upser mode, delete gets called on existing managed object, and therefore core data would delete all related relational objects, and all "delete rules" in core data model would be applied. For instance, if a user get's updated, and phone number changes from A to B, and if trhe delete rule is marked as cascade, then Address A would be removed and address B would be assigned to the user.

Different Usage & Helpers

// Using ObjectMapper Directly
ObjectMapper *mapper = [[ObjectMapper alloc] init];
Urse *user = [mapper objectFromSource:dictionary toInstanceOfClass:[User class]];

// Using ObjectMapper Singleton Instance
Urse *user = [[ObjectMapper sharedInstance] objectFromSource:dictionary toInstanceOfClass:[User class]];

In order to use these categories you must add your mapping provider to the singleton Instance

// Using NSObject Category
User *user = [User objectFromDictionary:aDictionary];

// Using NSDictionary Category
User *user = [aDictionary objectForClass:[User class]];

Change Log

2.1

Allow automatic conversion of underscore keys to camelCase properties

  • first_name to firstName as String
  • email_confirmation to emailConfirmation as EmailConfirmation class
  • email_confirmations to emailConfirmations as NSArray of EmailConfirmation class

2.0

Fixed a bug that was instroduced in 1.8 where classes with two words in they weren't getting mapped automatically. EX (sessionUser would try to map to Sessionuser class instead of SessionUser and would fail to map)

1.9

Automatic NSString to NSNumber and NSNumber to NSString conversion

1.8

  • No longer loading bundle class names in memory on init
  • Fixed for #22
  • No longer need to write mapping for non-array pointers as long as key/property names match (ex: "location" key would automatically map to "location" property event if the class type is named "Address" )
  • Wrote tests for mapping swift classes

Note:

Automatic mapping treats nested array differently. ObjectMapper capitalizes the first character of the dictionary key before checking for a conversion class.

  • "UserAddress" will automatically be mapped to "UserAddress"
  • "userAddress" will automatically be mapped to "UserAddress"
  • "useraddress" will NOT be mapped to "UserAddress", you need to manually write mapping

GitHub

https://github.com/aryaxt/OCMapper
Comments
  • 1. How to use InCodeMappingProvider with swift

    Hi,

    I'm not sure this question is relevant but how do you use:

    • (void)mapFromDictionaryKey:(NSString *)dictionaryKey toPropertyKey:(NSString *)propertyKey forClass:(Class)class withTransformer:(MappingTransformer)transformer;

    in swift?

    I always got the following error: Argument withTransformer must precede argument forClass.

    Could you post an example of this method used in Swift please.

    Thanks.

    Reviewed by hopiaw at 2015-02-14 22:26
  • 2. class keyword causes issues withIn the subclassed objective-c class

    I've been using OCMapper in Swift and I've run into a compilation problem. This may be an issue with XCode/Swift/Objective-C, but I figured I would open an issue here.

    All was working well until I tried to subclass a custom Objective-C class that I had created (a subclass of UIViewController). When I tried to do this, I ran into a build error which pointed to OCMapper.

    screenshot 2015-05-20 11 58 55 screenshot 2015-05-20 11 57 26

    Not subclassing the custom Objective-C class makes the build error go away (even if I still do the import).

    Any ideas?

    Reviewed by jessepollak at 2015-05-20 18:59
  • 3. MissingMappingProvider is Swift usage

    Hello,

    could you help me, when I try to run the following command

    ObjectMapper.sharedInstance().objectFromSource(self.data, toInstanceOfClass: Message.self) as? Message 
    

    it returns the following error:

    2015-03-12 11:31:16.385 websocket[41545:3347379] *** Terminating app due to uncaught exception 'MissingMappingProvider', reason: 'Mapping provider is not set'
    

    I'm forgetting to do something?

    Reviewed by victorjussiani at 2015-03-12 15:42
  • 4. How to specify which property to extract when using dictionaryFromObject() method?

    Hi,

    When using the following method:

    (id)dictionaryFromObject:(NSObject *)object;
    

    and object inherit NSManagedObject, the dictionary returned has a lot of NSManagedObject properties that I'd like to remove (like inserted, deleted, hasChanges, faultingState etc). Is there is an easy way to do that?

    Thanks

    Reviewed by hopiaw at 2015-02-16 03:06
  • 5. Alamofire extension for Alamofire 3.x

    Hi!

    I see there is an Alamofire Request extension example in the README, but if I'm correct it is not for the newest, 3.x version of Alamofire. Can you update it to show how can OCMapper be used with Alamofire 3.x. It would be really appreciated!

    Reviewed by balazsgerlei at 2016-06-21 16:58
  • 6. Manual setting of mapping provider to return currentNode is needed to prevent empty fetched data from JSON

    I have 2 model classes

    @interface PBQuiz : NSObject <OCMapperConfigurable>
    
    @property (nonatomic, strong) NSString* name;
    @property (nonatomic, strong) NSString* image;
    @property (nonatomic, strong) NSNumber* weight;
    @property (nonatomic, strong) NSArray<NSString*>* tags;
    @property (nonatomic, strong) NSString* desc;
    @property (nonatomic, strong) NSString* descriptionImage;
    @property (nonatomic, strong) NSString* quizId;
    
    @end
    

    and

    @interface PBQuizDetail : PBQuiz <OCMapperConfigurable>
    
    @property (nonatomic, strong) NSDate* dateStart;
    @property (nonatomic, strong) NSDate* dateExpire;
    @property (nonatomic, strong) PBQuizType* type;
    @property (nonatomic, strong) NSArray<PBQuizGrade*>* quizGrades;
    @property (nonatomic, strong) NSNumber* status;
    @property (nonatomic, strong) NSNumber* questionOrder;
    @property (nonatomic, strong) NSNumber* deleted;
    @property (nonatomic, strong) NSNumber* totalMaxScore;
    @property (nonatomic, strong) NSNumber* totalQuestions;
    @property (nonatomic, strong) NSNumber* questions;
    @property (nonatomic, strong) NSNumber* totalScore;
    @property (nonatomic, strong) NSDate* dateJoin;
    
    @end
    

    I have to manually add the following code

    [mappingProvider mapFromDictionaryKey:@"grades" toPropertyKey:@"grades" forClass:[PBQuizDetail class] withTransformer:^id(id currentNode, id parentNode) {
            return currentNode;
        }];
    

    just to return currentNode in order to receive value from JSON. If I didn't do this, I will always get 0 elements. Interesting thing also is that it's marked as JKArray type when I see it in debugger. I also use JSONKit. I'm not sure if OCMapper is conflict with JSONKit and cause this issue.

    Note, OCMapperConfigurable is just protocol I use which has no effect of this issue.

    Reviewed by haxpor at 2016-08-01 18:45
  • 7. Fix converting classes to Json that are part of "sub bundles"

    Fixes #23

    Fix converting classes to Json that are part of 'sub bundles' of the main app (e.g. unit tests or cocoa pods).

    This will:

    • Fix using OCMapper in unit tests (as described in #23)
    • Fix using OCMapper in pods which are in turn used by the main app
    • Still keep preventing OCMapper from converting classes that are not part of the main app or its "sub bundles" (e.g. Foundation)

    Feedback appreciated. Please let me know if there is a better solution :-)

    Reviewed by mikumi at 2015-07-14 07:16
  • 8. OCMapper2.1 seems not working in Xcode 5?

    Hello,

    I am using OCMapper in my Xcode 5 project which is under OS X 10.8.5.

    I am trying the sample test as following, but the user_id is null, the object didn't get mapped I don't know why?

    Here is my Model:

    
    #import <Foundation/Foundation.h>
    
    @interface User : NSObject
    
    @property (nonatomic) int user_id;
    
    @property (nonatomic) NSString* registration;
    
    
    @end
    
    

    Here is my Test

    
    #import <XCTest/XCTest.h>
    #import "ObjectMapper.h"
    #import "InCodeMappingProvider.h"
    #import "ObjectInstanceProvider.h"
    #import "CommonLoggingProvider.h"
    #import "User.h"
    
    @interface TestJson : XCTestCase
    
    @property (nonatomic, strong) ObjectMapper *mapper;
    @property (nonatomic, strong) InCodeMappingProvider *mappingProvider;
    
    @end
    
    
    @implementation TestJson
    @synthesize mapper;
    @synthesize mappingProvider;
    
    - (void)setUp
    {
        [super setUp];
    
        self.mappingProvider = [[InCodeMappingProvider alloc] init];
        self.mapper = [[ObjectMapper alloc] init];
        self.mapper.mappingProvider = self.mappingProvider;
    }
    
    - (void)tearDown
    {
        self.mapper = nil;
        self.mappingProvider =  nil;
        [super tearDown];
    }
    
    
    - (void)test1
    {
    
        NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
        [dic setObject:[NSNumber numberWithInt:10] forKey:@"user_id"];
        [dic setObject:@"Value2" forKey:@"registration"];
    
        User *user = [self.mapper objectFromSource:dic toInstanceOfClass:[User class]];
        NSLog(@" user.user_id - %@", user.user_id);    // here the user.user_id is null
    }
    
    @end
    
    

    So I have 3 questins: 1, is Xcode 5 + OS X 10.8 supported by the latest OCMapper 2.1 version?

    2, I tried to use like this (I saw on StackOverflow) User *user = [User objectFromDictionary:dic]; but this needs to add #import "NSObject+ObjectMapper.h"

    Is this the right way to use OCMapper, why we need a mapper and mappingProvider?
    

    3, in case the Model has more properties than the dictionary, for exampel, we have only user_id in the dictionary while User has user_id + registration, does OCMapper support the optional mapping?

    Reviewed by seaguest at 2016-04-01 16:31
  • 9. Support for custom factory methods

    In this particular situation I need to map an array to a nested object.

    From
    {p:[3,4]}
    To
    X
    _p
    __a
    __b
    

    The Jackson Java library supports custom factory methods, e.g., through the @JsonCreator annotation, that allow me to realize such a mapping in the following way. Jackson then searches for a suitable factory method whenever it has to map int[] to P. Support for some sort of factory methods would be a powerful feature.

    public class X {
        @JsonProperty("p")
        private P p;
    }
    
    public class P {
        private int a;
        private int b;
    
        public P(int a, int b) {
            this.a= a;
            this.b= b;
        }
    
        @JsonCreator
        public static P fromValue(int[] array) {
            return new P(array[0], array[1]);
        }
    }
    
    Reviewed by laenger at 2015-01-14 17:00
  • 10. Array of Custom objects

    I have an array of treatments. The class name is ICATreatment. The mapper maps the array to dictionary correctly, but fails to map from dictionary to array.

    Reviewed by abduranjum at 2016-03-14 14:58
  • 11. Automatically convert between underscores and camelCase

    I often have to interact with APIs that use underscores in their JSON responses (e.g. 'some_property'). This forces me to do a lot of manual mapping to convert to ObjC/Swift camel case properties (e.g. 'someProperty). It would be fantastic if OCMapper could automatically convert between the two.

    Reviewed by poetmountain at 2015-06-16 23:04
  • 12. OCMapper SDK is crashing on iOS 11.2.2 Version using xCode10.1

    My application we are using OC Mapper SDK.Its works on Xcode 10.0 Version properly in my app. After updating to xCode 10.1 the application is crashing on devices iOS 11.2.2 and 9.3.5 versions but its working on iOS 12.1.4. I got this below warning and will crashing.

    warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.

    Its related to OCMapper SDK Crash here i am attaching proper screen shots.

    Please help me, how we sort out.

    screenshot 2019-02-21 at 6 12 02 am screenshot 2019-02-21 at 6 12 25 am
    Reviewed by vasuippili at 2019-02-21 12:32
  • 13. Crash on ObjectMapper processDictionaryFromObject

    I got some crash logs from Fabric on this method.

    This is where the crash originates, basically converting an object into dictionary : https://github.com/ooni/probe-ios/blob/master/ooniprobe/Model/Settings/Settings.m#L19

    Crash log : https://github.com/ooni/probe-ios/issues/223 Wasn't able to reproduce it on my own

    Reviewed by lorenzoPrimi at 2019-01-18 04:09
  • 14. watchOS support

    Is there a way to use OCMapper with watchOS? If not at the moment are there any chances to support watchOS platform any soon?

    I'm integrating watch support in my project and already using OCMapper in the iOS app. I thought to pass my objects as json between host app and watch and to automatically serialize/deserialize them but I've stuck integrating OCMapper to watch extension and getting the following error while executing pod install:

    Analyzing dependencies [!] The platform of the target Watch Extension (watchOS 3.1) is not compatible with OCMapper (2.1), which does not support watchos.

    the podfile:

    target 'Watch Extension' do pod 'OCMapper' end

    Reviewed by arthabus at 2016-12-08 15:50
  • 15. Make automatic conversion between underscores and camelCase optional

    You added automatic conversion from underscores to camelCase in 2.1 (#31), which is great but I think it would be better if it is optional.

    I mean, if a property with underscore case found, parse the json node to that, and only try to parse to a camelCase one if a parameter with the exact same underscore case-d name not found.

    Reviewed by balazsgerlei at 2016-11-06 12:53
  • 16. Automatically convert between camelCase and underscores (the other way around)

    You added automatic conversion from underscores to camelCase in 2.1 (#31), but it doesn't seem to work the other way: converting camelCase to underscores. This way it is not possible to communicate with a server using underscores correctly without creating separate modell classes for incomming and outgoing communication.

    Or am I doing something wrong? I am using it from Swift if it matters.

    Reviewed by balazsgerlei at 2016-11-06 12:51
Related tags
Soulful docs for Swift & Objective-C
Soulful docs for Swift & Objective-C

jazzy is a command-line utility that generates documentation for Swift or Objective-C About Both Swift and Objective-C projects are supported. Instead

Aug 8, 2022
Catch Objective-C exceptions in Swift

ExceptionCatcher Catch Objective-C exceptions in Swift There are many Cocoa APIs that can throw exceptions that cannot be caught in Swift (NSKeyedUnar

Jul 5, 2022
💡 A light Swift wrapper around Objective-C Runtime
💡 A light Swift wrapper around Objective-C Runtime

A light wrapper around Objective-C Runtime. What exactly is lumos? lumos as mentioned is a light wrapper around objective-c runtime functions to allow

Jul 7, 2022
Swift-friendly API for a set of powerful Objective C runtime functions.
Swift-friendly API for a set of powerful Objective C runtime functions.

ObjectiveKit ObjectiveKit provides a Swift friendly API for a set of powerful Objective C runtime functions. Usage To use ObjectiveKit: Import Objecti

Jul 29, 2022
Swift Property Wrappers, but in Objective-C. And done horribly.

TOPropertyAccessor is an open source, Objective-C abstract class. Similar to Realm's Cocoa API, it uses the dynamic nature of the Objective-C runtime to access the properties of any of its subclasses, and routes calling them through overridable access points.

May 23, 2021
Reflection for enumerations in Objective-C.

ReflectableEnum A macro and a set of functions introducing reflection for enumerations in Objective-C. Features: get a string value for an enumeration

Jun 29, 2022
Because Objective-C should have inherited more from Smalltalk

OpinionatedC Sometimes, Objective-C is just overly verbose. Life is too short to enumerateObjectsUsingBlock and who has the time to create sub-arrays

Apr 7, 2022
The Objective-C block utilities you always wish you had.

BlocksKit Blocks in C and Objective-C are downright magical. They make coding easier and potentially quicker, not to mention faster on the front end w

Jul 31, 2022
Proper YAML support for Objective-C. Based on recommended libyaml.

YAML.framework for Objective-C Based on C LibYAML library (http://pyyaml.org/wiki/LibYAML) by Kirill Simonov. YAML.framework provides support for YAML

Aug 6, 2022
Contacts wrapper for iOS 9 or upper with Objective-C

ContactsWrapper Contacts wrapper for iOS 9 or upper with Objective-C. For the information translated to Russian, take a look at this link. Requirement

Jun 18, 2022
A reverse engineering tool to restore stripped symbol table and dump Objective-C class or Swift types for machO file.

A reverse engineering tool to restore stripped symbol table and dump Objective-C class or Swift types for machO file.

Aug 2, 2022
A quick and "lean" way to swizzle methods for your Objective-C development needs.

Swizzlean A quick and "lean" way to swizzle methods for your Objective-C development needs. Adding Swizzlean to your project Cocoapods CocoaPods is th

Jun 29, 2022
Pigeon is a SwiftUI and UIKit library that relies on Combine to deal with asynchronous data.

Pigeon ?? Introduction Pigeon is a SwiftUI and UIKit library that relies on Combine to deal with asynchronous data. It is heavily inspired by React Qu

Aug 10, 2022
swift-highlight a pure-Swift data structure library designed for server applications that need to store a lot of styled text

swift-highlight is a pure-Swift data structure library designed for server applications that need to store a lot of styled text. The Highlight module is memory-efficient and uses slab allocations and small-string optimizations to pack large amounts of styled text into a small amount of memory, while still supporting efficient traversal through the Sequence protocol.

Jul 17, 2022
RandomKit is a Swift framework that makes random data generation simple and easy.
RandomKit is a Swift framework that makes random data generation simple and easy.

RandomKit is a Swift framework that makes random data generation simple and easy. Build Status Installation Compatibility Swift Package Manager CocoaP

Aug 3, 2022
A tiny generator of random data for swift

SwiftRandom SwiftRandom is a tiny help suite for generating random data such as Random human stuff like: names, gender, titles, tags, conversations Ra

Jul 10, 2022
Functional data types and functions for any project

Swiftx Swiftx is a Swift library containing functional abstractions and extensions to the Swift Standard Library. Swiftx is a smaller and simpler way

Jun 29, 2022
A simple Pokedex app written in Swift that implements the PokeAPI, using Combine and data driven UI.
A simple Pokedex app written in Swift that implements the PokeAPI, using Combine and data driven UI.

SwiftPokedex SwiftPokedex is a simple Pokedex app written by Viktor Gidlöf in Swift that implements the PokeAPI. For full documentation and implementa

Aug 5, 2022
Passing data from a couple of screen into a Model
Passing data from a couple of screen into a Model

Passing-Data Passing data from a couple of screen into a Model Introduction Hi, this video is just a representation project from this Video by Essenti

Oct 12, 2021