initWithPasteboardPropertyList from Objc to swift

I have the following code in a tutorial :


@implementation DesktopEntity
- (id)initWithFileURL:(NSURL *)fileURL {
    self = [super init];
    if (self) {
        _fileURL = fileURL;
    }
    return self;
}
+ (DesktopEntity *)entityForURL:(NSURL *)url {
    NSString *typeIdentifier;
    if ([url getResourceValue:&typeIdentifier forKey:NSURLTypeIdentifierKey error:NULL]) {
        NSArray *imgTypes = [NSImage imageTypes];
        if ([imgTypes containsObject:typeIdentifier]) {
            return [[DesktopImageEntity alloc] initWithFileURL:url];
        } else if ([typeIdentifier isEqualToString:(NSString *)kUTTypeFolder]) {
            return [[DesktopFolderEntity alloc] initWithFileURL:url];
        }
    }
    return nil;
}

- (id)initWithPasteboardPropertyList:(id)propertyList ofType:(NSString *)type {
    NSURL *url = [[NSURL alloc] initWithPasteboardPropertyList:propertyList ofType:type];
    self = [DesktopEntity entityForURL:url];
    return self;
}


, I am not sure how to convert to swift the initWithPasteboardPropertyList

If I call the class function DesktopEntity entityForURL:url, to which object should I assign its result ? Obviously I cannot write


self = DesktopEntity.entityForURL(url!)



here is what I wrote so far


class DesktopEntity: NSObject, NSPasteboardWriting, NSPasteboardReading {
  
    var fileUrl : NSURL
    private var _name : String /
    init(fileURL: NSURL) {
        self.fileUrl = fileURL
        _name = ""
        super.init()
    }
  
    class func entityForURL(url: NSURL) -> DesktopEntity? {
        var typeIdentifier: AnyObject?  /
        do {
            try url.getResourceValue(&typeIdentifier, forKey: NSURLTypeIdentifierKey) /
            let imgTypes = NSImage.imageTypes()
          
            let stringTypeIdentifier = typeIdentifier as! String
            if imgTypes.contains(stringTypeIdentifier) {
                return DesktopImageEntity(fileURL: url)
            } else if stringTypeIdentifier == kUTTypeFolder as String {
                return DesktopFolderEntity(fileURL: url)
            }
        } catch _ {}
      
    return nil /
    }
    var name : String? {
        get {
            var localName: AnyObject?
            do {
                try fileUrl.getResourceValue(&localName, forKey: NSURLLocalizedNameKey)
                    return localName as? String
                } catch _ {  }
            return _name /
        }
        set {
            _name = newValue!
        }
    }

    required init!(pasteboardPropertyList propertyList: AnyObject, ofType type: String) {       
        let url = NSURL(pasteboardPropertyList: propertyList, ofType: type)
                                           // How to implement : DesktopEntity.entityForURL(url!)
        self.fileUrl = url!
        _name = ""
        super.init()
    }

I will try this ; But what's surprising is that it seems easy to make it work in objc...

Keep in mind that the original code is doing something that's easy in Obj-C (returning a different object than original 'self' from an init method) but AFAIK is not allowed in Swift. That means there's no direct translation of the original code. You're going to have to alter the Obj-C slightly, first, and then make a simple translation, or implement a slightly different strategy in Swift. As you noted earlier, there's some juggling because there are exterior constraints like protocol conformance getting in the way.


Sometimes it's not worth trying to convert Obj-C directly. You may be better off just re-thinking the whole thing from scratch, in Swift terms.

I am finding out that Swift does not allow certain types of constructions. I have implemented in a different way and it finally works.


I'll post another thread to check if it is effectively impossible to get an instance with a subclass type.


Thanks for your help.

I did it that way and it works.

initWithPasteboardPropertyList from Objc to swift
 
 
Q