Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift UIImage extension

I am trying to make my code safer using Enums and a connivence initializer when dealing with UIImage and the Asset Catalog. My code is here below.

import UIKit

extension UIImage {
    enum AssetIdentifier: String {
        case Search = "Search"
        case Menu = "Menu"
    }

    convenience init(assetIdentifier: AssetIdentifier) {
        self.init(named: AssetIdentifier.RawValue)
    }
}

Currently I am getting this error.

'Cannot invoke 'UIImage.init' with an argument of type '(named: RawValue.Type)'
like image 533
Cody Weaver Avatar asked Sep 12 '15 22:09

Cody Weaver


2 Answers

There are 2 problems:

1. Failable init

In your convenience initializer you are calling a failable initializer. So how can you guarantee that an instance of UIImage is always created when you are relying on a failable initializer that, by definition, does not guarantee that? You can fix this by using the magic ! when you call the failable init.

2. Referencing the param you received

When you call self.init you are not passing the param received in your init. You are instead referencing the enum definition. To fix this replace this

self.init(named: AssetIdentifier.RawValue)

with this

self.init(named: assetIdentifier.rawValue)

Wrap up

This is the result

extension UIImage {
    enum AssetIdentifier: String {
        case Search = "Search"
        case Menu = "Menu"
    }
    convenience init(assetIdentifier: AssetIdentifier) {
        self.init(named: assetIdentifier.rawValue)!
    }
}

Testing

UIImage(assetIdentifier: .Search)
like image 53
Luca Angeletti Avatar answered Sep 21 '22 17:09

Luca Angeletti


You can use this code. I have tested it.

import UIKit
import Foundation

enum AssetIdentifier: String {
    case Search = "Search"
    case Menu = "Menu"
}
extension UIImage {
    convenience init?(assetIdentifier: AssetIdentifier) {
        self.init(named: assetIdentifier.rawValue)
    }
}


class ViewController: UIViewController {

    @IBOutlet var imageview: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        imageview.image = UIImage(assetIdentifier: AssetIdentifier.Menu)
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}
like image 36
Lokesh Dudhat Avatar answered Sep 19 '22 17:09

Lokesh Dudhat