Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: return Array of type self

I would like to write a class function, which will return an array of the class type. As far as I understood, I can use Self for the objective-c instanceType. My goal is to create an extension for a NSManagedObject with a fetchObjects method. This method will than return an array of NSManagedObject subclasses. Here is a example of my pseudo code which does not compile:

extension NSManagedObject {

    class func fetchObjects(entity: String, context: NSManagedObjectContext, predicate: NSPredicate?, sortDescriptors: NSSortDescriptor[]?) -> Self[] {
        // can't define return type of an array with type Self
        // also var declaration does not work
        var objects : Self[]?

        return objects
    }
}

Any idea how i can define an array of type Self?

Thanks for any help!

like image 223
user966697 Avatar asked Jul 02 '14 17:07

user966697


People also ask

What is .first in Swift?

first(where:) Returns the first element of the sequence that satisfies the given predicate.

What is Swift Nsarray?

An object representing a static ordered collection, for use instead of an Array constant in cases that require reference semantics.

Which type are arrays in Swift?

Swift provides three primary collection types, known as arrays, sets, and dictionaries, for storing collections of values. Arrays are ordered collections of values. Sets are unordered collections of unique values.


1 Answers

This is the jist of what I use for a similar function, note that it's an extension on NSManagedObjectContext rather than NSManagedObject. Something similar could probably be done on NSManagedObject

protocol NamedManagedObject {

    class func entityName() -> String;

}

extension NSManagedObjectContext {

    func fetchObjects<T:NSManagedObject where T:NamedManagedObject>(entity:T.Type, predicate:NSPredicate? = nil, sortDescriptors:NSSortDescriptor[]? = nil) -> T[]? {
        let request = NSFetchRequest(entityName: entity.entityName())

        request.predicate = predicate
        request.sortDescriptors = sortDescriptors

        var error:NSError? = nil
        let results = self.executeFetchRequest(request, error: &error) as? T[]

        assert(error == nil)

        return results
    }

}

extension MyObjectClass : NamedManagedObject {
    class func entityName() -> String {
        return "MyObjectClass"
    }
}

Then using it is as simple as:

let objects = managedObjectContext.fetchObjects(MyObjectClass)

Note that you can also implement NamedManagedObject for all NSManagedObjects with:

extension NSManagedObject : NamedManagedObject {
    class func entityName() -> String {
        return NSStringFromClass(self)
    }
}

If you also insure that all your classes are explicitly given Objective-C friendly names:

@objc(MyManagedObject)
class MyManagedObject : NSManagedObject { ... }
like image 173
David Berry Avatar answered Oct 17 '22 03:10

David Berry