SkillAgentSearch skills...

BaseModel

BaseModel provides a base class for building model objects for your iOS or Mac OS projects. It saves you the hassle of writing boilerplate code, and encourages good practices by reducing the incentive to cut corners in your model implementation.

Install / Use

/learn @nicklockwood/BaseModel
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Build Status

Purpose

BaseModel provides a base class for building model objects for your iOS or Mac OS projects. It saves you the hassle of writing boilerplate code, and encourages good practices by reducing the incentive to cut corners in your model implementation.

The BaseModel object uses property lists and the NSCoding protocol for serialisation. It is not designed for use with Core Data, although in principle the class could be extended to work with Core Data if needed by changing the BaseModel superclass to an NSManagedObject.

BaseModel is really designed as an alternative to Core Data for developers who prefer to have a little more control over the implementation of their data stack. BaseModel gives you precise control over the location and serialisation of your data files, whilst still proving enough automatic behaviour to save you from writing the same code over and over again.

BaseModel is designed to work with the following serialization libraries:

  • HRCoder (https://github.com/nicklockwood/HRCoder). HRCoder provides an alternative mechanism for loading and saving data in a human readable/editable format. HRCoder allows you to specify your data files in a standard format, and avoids the need for you to override the setWith... methods. Use of HRCoder is completely optional. For an example of how this works, check out the HRTodoList example.

  • CryptoCoding library (https://github.com/nicklockwood/CryptoCoding). When used in conjunction with CryptoCoding, BaseModel objects support automatic AES encryption of the entire object when saved or loaded to disk. Use of CryptoCoding is completely optional. For an example of how it works, check out the CryptoTodoList example.

  • FastCoding (https://github.com/nicklockwood/FastCoding). FastCoding provides an alternative mechanism for loading and saving data in a fast, compact binary format. FastCoding is a replacement for NSCoding that produces files tat at 50% of the size, and load in half the time as ordinary NScoded archives. Use of FastCoding is completely optional. For an example of how this works, check out the FCTodoList example.

Note: HRCoder and CryptoCoding both take advantage of BaseModel's NSCoding implementation and will call the setWithCoder: and encodeWithCoder: methods. FastCoding uses its own serialization implementation and does not use these methods.

Supported OS & SDK Versions

  • Supported build target - iOS 11.0 / Mac OS 10.12 (Xcode 9.0)
  • Earliest supported deployment target - iOS 9.0 / Mac OS 10.10
  • Earliest compatible deployment target - iOS 4.3 / Mac OS 10.6

NOTE: 'Supported' means that the library has been tested with this version. 'Compatible' means that the library should work on this iOS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly.

ARC Compatibility

As of version 2.4, BaseModel requires ARC. If you wish to use BaseModel in a non-ARC project, just add the -fobjc-arc compiler flag to the BaseModel.m class. To do this, go to the Build Phases tab in your target settings, open the Compile Sources group, double-click BaseModel.m in the list and type -fobjc-arc into the popover.

If you wish to convert your whole project to ARC, comment out the #error line in BaseModel.m, then run the Edit > Refactor > Convert to Objective-C ARC... tool in Xcode and make sure all files that you wish to use ARC for (including BaseModel.m) are checked.

Thread Safety

BaseModel instances can be safely created and accessed concurrently from multiple threads, however some BaseModel operations are synchronized on a per-class basis, so creating BaseModel instances or accessing the shared instance concurrently on multiple threads may lead to unexpected performance issues.

Installation

To use the BaseModel class in your project, just drag the BaseModel.h and .m files into your project. BaseModel has no required dependencies, however you may wish to also include the optional HRCoder (https://github.com/nicklockwood/HRCoder), CryptoCoding (https://github.com/nicklockwood/CryptoCoding) and/or FastCoding (https://github.com/nicklockwood/FastCoding) libraries to enable additional BaseModel functionality.

Classes

There is a single class, BaseModel which you should use as the base class for any model-type classes. BaseModel provides a core set of functions for dealing with model data, and through the BaseModel protocol, provides hooks to implement additional bespoke behaviours with minimal coding.

Methods

The BaseModel class has the following methods:

- (void)setUp;

BaseModel's initialisation routine is quite complex and follows a multi-step process. To simplify configuration, BaseModel provides a setUp method that is called before anything else so you can pre-configure your instance. This is called only after a successful [super init], so there is no need to verify that self is not nil or call [super setUp] (unless you are subclassing one of your own BaseModel subclasses). Like init, setUp is called only once at the start of the lifetime of an instance, so it is safe to set properties without releasing their existing values (relevant only if you are not using ARC). You should never call setUp yourself directly, except in the context of calling [super setUp] when subclassing your own BaseModel subclasses.

- (void)tearDown;

The tearDown method complements setUp. It is called whent he object is destroyed, but will only be called if the setUp method was called first. This is useful in situations where the class gets destroyed before it is initialised, which might for example happen if it was created by calling [[Model alloc] initWithObject:nil]. By putting your destructor logic in tearDown instead of dealloc, you can avoid unbalanced calls to removeObserver, etc. You should never call tearDown yourself directly, except in the context of calling [super tearDown] (it is called automatically by BaseModel's dealloc method). There is no need to call [super tearDown] unless you have subclassed one of your own BaseModel subclasses.

- (void)setWithDictionary:(NSDictionary *)dict;

If you are initializing your BaseModel instance using a dictionary (typically loaded from JSON or a Plist file) then this method will be called automatically. BaseModel provides a default implementation of setWithDictionary: that attempts to set the properties of your class automatically from the dictionary that is passed in, but you can override this if neccesary (e.g. if the property names or types don't match up exactly).

- (NSDictionary *)dictionaryRepresentation;

This method returns a dictionary containing all the (non-nil) properties of the model. This is a useful way to transform a model that was initialized from a Plist or JSON file back into a form that can be saved out as such a file. Note: There is no guarantee that the objects in this dictionary are Plist-safe, so if you intend to generate a Plist or JSON file, you may be better off using the HRCoding library, which can automatically convert child objects to Plist/JSON-safe form recursively.

- (void)setWithXXX:(XXX *)xxx;

BaseModel instances can be initialized with objects of any type, via the instanceWithObject:/initWithObject: method. To support a given object type, simply add a method setWith[ClassName]: where ClassName is the class of the object being set. For example to initialise your BaseModel using an NSArray, add a method setWithArray:orsetWithNSArray:` and it will be called automatically.

- (void)setWithCoder:(NSCoder *)aDecoder;

This method is called by initWithCoder: as part of the NSCoding implementation. BaseModel provides an automatic implementation of NSCoding by inspecting the properties of your class, so there is no need to implement this method yourself unless you need to customise the decoding behaviour. This method is called after the setUp method and potentially may be called after default values have been loaded using setWith[ClassName]:, so you should not assume that class properties and ivars do not already have values at the point when this method is called.

- (void)encodeWithCoder:(NSCoder *)aCoder;

The BaseModel class provides an automatic default implementation of this method by inspecting the properties of your class, so there is no need to implement this method yourself unless you need to customise the decoding behaviour.

+ (instancetype)instance;
- (instancetype)init;

Creates an autoreleased instance or initialises a retained instance of the class respectively. These methods will first call setUp, and will then attempt to initialise the class from resourceFile if that file exists.

+ (instancetype)instanceWithObject:(NSDictionary *)dict;
- (instancetype)initWithObject:(NSDictionary *)dict;

Creates an instance of the class and initialises it using the supplied object. This is useful when loading a model from an embedded property list file in the application bundle, or creating model objects from JSON data returned by a web service. This method requires that an appropriate setter method is defined on your class, where the setter name is of the form setWith[ClassName]:. For example, to initialise the model using an NSArray, your BaseModel subclass must have a method called setWithArray:. This method will attempt to initialise the class from resourceFile (if that file exists) prior to calling setWith[ClassName]:, so if your resourceFile contains a serialised object, this method will be called twice (with different input).

+ (NSArray *)instancesWithArray:(NSArray *)array;

This i

Related Skills

View on GitHub
GitHub Stars290
CategoryContent
Updated4mo ago
Forks46

Languages

Objective-C

Security Score

77/100

Audited on Nov 8, 2025

No findings