Handling class initialization failure in Swift extension

I’m rewriting an Objective C category below to Swift:

@implementation UIImage (Extra)

+ (UIImage *)validImageNamed:(NSString *)name
{
    UIImage *image = [self imageNamed:name];
    NSAssert(image, @"Unable to find image named '%@'", name);
    return image;
}

This asks to be implemented as an convenience init, but how can I check if designated initializer self.init(named:) succeeds?

  • Creating an extension to filter nils from an Array in Swift
  • Can I extend Tuples in Swift?
  • Add constraints to generic parameters in extension
  • Swift 'open' keyword & overridable method/properties in extension?
  • Pass in a type to a generic Swift extension, or ideally infer it
  • Swift is there a method that gives the index of a substring inside another string
  • extension UIImage {
        convenience init(validateAndLoad name: String!) {
            self.init(named: name)
    
            // need to assert here if self.init fails
        }
    

    When self.init(named:) call fails, extension’s init stops executing.

    I’ve tried creating an UIImage instance and assigning it to self, but this doesn’t compile.

    Of course, a helper method can be used like in ObjC version:

    extension UIImage {
    
        class func validImage(named name: String) -> UIImage {
            var image = UIImage(named: name)
            assert(image == nil, "Image doesn't exist")
            return image
        }
    

    But is there a way to implement this using an initializer?

    3 Solutions Collect From Internet About “Handling class initialization failure in Swift extension”

    You can now create failable initializers in extensions; however, the initializers can not be defined in a protocol.

    class Thing {
    
        var text:String?
    
    }
    
    extension Thing  {
    
        convenience init?(text:String) {
            self.init()
            if text == "" {
                return nil
            } else {
                self.text = text
            }
        }
    }
    
    
    let that = Thing(text: "Hello")
    println(that?.text) //prints Optional("Hello")
    
    let empty = Thing(text: "")
    println(empty) //prints nil
    

    Unlike Objective-C, Swift initializers don’t return self, so checking for initialization failures is not possible. An Apple engineer suggested using a factory method with an optional return type instead:

    class ImageFactory {
    
        class func validImage(named name: String) -> UIImage? 
        {
            var image = UIImage(named:name)
            assert(image != nil, "fail")
            return image;
        }
    }
    

    The Apple engineer indicated that they are working on building something into the language that will get around using factory class methods.

    i would write the method like below:

    extension UIImage {
    
    class func validImage(named name: String) -> UIImage? {
        var image = UIImage(named: name)
        return image
    }
    

    in swift you can use optionals. If here is no image with the given name the method will return nil.