How to enable custom view properties in Xcode ?

Sometimes we need to add custom visual properties to views for our applications, for example a border-width or a corner radius. Instead of blindly setting these values in the code, Xcode allows us to add custom properties to the views and to edit them like the original properties.

Basic view

Recently I had to customize cells from a collection view: add a colored border-width and a corner radius. First, drop a UICollectionViewController object to the storyboard. This is how it appears in Xcode originally, there are only basic properties (alpha, background color, tint color)

Original collection view
Original collection view

Custom view

In order to add editable custom visual properties to a view, make a subclass of this view’s class. In our example, we create the class CustomCellView subclassing UICollectionViewCell.

Fill the class with the following code:

The magic keyword is @IBInspectable. This keyword tells Xcode that this property is editable. The IDE will add a widget to the inspector pane based on the name and the type of the property. The didSet blocks will update the view according to the property. Here is an easy example because the layer object does natively support the properties borderWidth, borderColor and cornerRadius.

Then set the custom class name to the view in the storyboard

Custom cell view.
Custom cell view.

You can see that the pane is already updated with the User Defined Runtime Attributes widgets. There are legacies from the previous versions of Xcode: do not use them, jump to the next pane and use these other widgets. This pane is updated with our custom visual properties! Xcode parses the names to readable ones, and creates input based on the type of the property, this is great!

Updated collection view.
Updated collection view.

Updated view

Now you can edit the values of the custom properties and save the storyboard, at runtime the defined properties will be reflected to your view.

There is one last thing to do, you can edit the values but the view is not updated to the view in the storyboard: the view remains blank. To fix that, you must add a second magic keyword: @IBDesignable.

This keyword tells Xcode to update the view in the editor.

Final collection view.
Final collection view.

That’s it! Xcode allows us to easily add custom visual properties!

Here it is an easy example, but you can go further and add complex properties composed of multiple subviews.

CoreDataStack: easy use of CoreData framework with Swift

CoreData framework

The CoreData framework is the standard framework provided by Apple to manage persistent data within the applications. This framework is based on an object graph model.

The CoreData framework is a master piece of the iOS applications, it helps you build the model layer of your applications and handles for you a lot of work to persist the state of the model objects to disk.

To have more informations about the CoreData framework see Apple’s documentation.

Don’t repeat yourself

Developing iOS projects which use the CoreData framework often leads to writing the same code pattern:

To reduce the portion of code to produce I wrote a small framework which handles the initial CoreData stack (NSManagedObjectModel and NSPersistentStoreCoordinator objects) and the NSManagedObjectContext objects (to fetch and create NSManagedObject objects).

The CoreDataStack framework is available at Github: https://github.com/cygy/CoreDataStack. An example is present to show you how to use the framework.

Create the initial CoreData stack

The CoreDataStack class provides a useful init method to set up the initial CoreData stack: just provide an array of the names of the model files (the .momd files) and the name of the file to save the persistent data (the created file is into the “Application Support” directory of the application).

The init method has many optional parameters, see the code source to have more informations:

The NSManagedObjectContext objects

The CoreDataStack class handles two NSManagedObjectContext objects:

  • the first context is the writer, which exclusively writes into the persistent store coordinator, it is not bound to the main thread. Write to disk is an expensive operation, so it must not block the main thread.
  • the second is the default context. As it is bound to the main thread, you use it to fetch the objects from the NSFetchedResultsController.

These two NSManagedObjectContext objects are bound to the same NSPersistentStoreCoordinator object.

The batch NSManagedObjectContext objects are bound to a different NSPersistentStoreCoordinator object to avoid locking the first NSPersistentStoreCoordinator object.

CoreDataStack-Architecture

Fetch NSManagedObject objects

Use the default context from your CoreDataStack object with your NSFetchedResultsController objects:

Perform actions on NSManagedObject objects

To perform actions on NSManagedObject objects, the CoreDataStack class provides three useful methods:

  • The performBlockInContext method is used to perform a few actions like adding or deleting a very small amount of objects. As it uses a context bound to the default context, the changes are immediately passed to the default context when it saved, but the main thread is blocked.

  • The performBlockInContextForBackgroundTask method is used to perform a few actions too but here save the context does not block the main thread. The changes are not passed to the default context unless you call the saveBlock block with its parameter to true.

  • The performBlockInContextForBatchTask method is used to perform heavy actions like adding or deleting thousands objects. The method provides a saveBlock block which you can run into the first block to save the context. To see the changes in the default context, you have to refetch the requests.

As you can see, with these three methods, the first block provides a NSManagedObjectContext object to perform actions on NSManagedObject objects. This context is not bind to the main thread to preserve the user interface responsiveness. At the end of the first block, the context is automatically saved.

The second block (named mainThreadBlock) is optional and is executed in the main thread: you can perform here UI actions like reloading a UITableView or a NSFetchedResultsController object.

Handle yourself the contexts

If you want to handle yourself the NSManagedObjectContext object and save it, get a context object from one of the first methods below and save it with the third method:

Save the contexts

You can save the default and the writer contexts of the CoreDataStack object at every moment with the method:

To save a NSManagedObjectContext object generated by the CoreDataStack object call the method:

Get the framework

I hope this framework will help you to use the CoreData framework. It is available at Github: https://github.com/cygy/CoreDataStack. Read the example to know how to use the framework.