Apple's Swift Logo
Recently on my journey learning Swift, Apple's new programming language, I decided to re-write my Objective-C View Stack utility using only Swift and it turns out you can't. Well you can't at the moment, it's worth bearing in mind that Swift is in Beta at the time of writing and could change at short notice.

Working around the problem is really easy though and it is this type of situation where Objective-C knowledge is going to remain important for developers focussed on Apple's iOS and OSX platforms.

The stumbling block in my particular utility arose because I store references to UIViewController sub classes and dynamically create instances of them which in Objective-C is easy enough.


@property (nonatomic, strong) Class viewControllerSubClass;

--

[[viewControllerSubClass alloc] init]
 

Naturally the first thing I tried was the Swift equivalent:


viewControllerSubClass()
 

However the compiler informs you that :


AnyObject is not constructible with ()
 

This is a bit confusing as in my application viewControllerSubClass is the type AnyClass. In Swift AnyClass is defined as :


typealias AnyClass = AnyObject.Type
 

AnyObject is defined as :


@class_protocol protocol AnyObject {
}
 

There doesn't seem to be a way of initialising AnyClass and I couldn't find out anymore about Type.

In fact treating my AnyClass as a Type doesn't make things an clearer :


var vc : viewControllerClassToShow = viewControllerClassToShow()
 


'viewControllerClassToShow' is not a type.
 

After some time thinking about this and deciding that creating a Factory for my UIViewController subclasses in Objective-C is very straight forward I adjusted my goal to be an almost pure Swift implementation of my View Stack.

I added the following files to my project.

UIViewControllerFactory.h


#import <UIKit/UIKit.h>

@interface UIViewControllerFactory : NSObject

    +(UIViewController *)viewControllerFromClass:( Class ) className;

    +(UIViewController *)viewControllerFromClass:(Class) className
                                                  withNibName:( NSString * )nibName
                                       andBundle:(NSBundle * )bundleName;

@end
 

UIViewControllerFactory.m


#import "UIViewControllerFactory.h"

@implementation UIViewControllerFactory

    +(UIViewController *)viewControllerFromClass:( Class )className{
       
        return [[className alloc] init];
       
    }

    +(UIViewController *)viewControllerFromClass:(Class) className
                                     withNibName:( NSString * )nibName
                                       andBundle:(NSBundle * )bundleName{
       
        return [[className alloc] initWithNibName:nibName bundle:bundleName];
       
    }

@end   
 

Really straight forward Objective-C which needs a bridging header added to XCode before it is accessible to Swift.

Once the bridge has been made using the Objective-C classes couldn't be simpler.


UIViewControllerFactory.viewControllerFromClass(viewControllerClassToShow)
 


UIViewControllerFactory.viewControllerFromClass(
                                       
                                        viewControllerClassToShow,
                                        withNibName: nibNameString,
                                        andBundle: nibBundleNSBundle
                                       
                                    )
 

As I mentioned before this may change in time as it is very early days for Swift but this sort of approach is very productive for this type of stumbling block as long as you know some Objective-C.